eve 0.30.7 → 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.
- package/CHANGELOG.md +36 -0
- package/README.md +5 -6
- package/dist/src/acp/adapter.d.ts +10 -4
- package/dist/src/acp/adapter.js +1 -1
- package/dist/src/channel/adapter-context.d.ts +1 -1
- package/dist/src/channel/adapter.d.ts +2 -4
- package/dist/src/channel/adapter.js +1 -1
- package/dist/src/channel/channel-address.d.ts +58 -0
- package/dist/src/channel/channel-address.js +1 -0
- package/dist/src/channel/channel-operations.d.ts +72 -0
- package/dist/src/channel/channel-operations.js +1 -0
- package/dist/src/channel/compiled-channel.d.ts +10 -6
- package/dist/src/channel/cross-channel-receive.d.ts +13 -25
- package/dist/src/channel/cross-channel-receive.js +2 -2
- package/dist/src/channel/receive-target.d.ts +1 -2
- package/dist/src/channel/routes.d.ts +21 -149
- package/dist/src/channel/schedule.d.ts +1 -1
- package/dist/src/channel/schedule.js +1 -1
- package/dist/src/channel/send-input.d.ts +6 -0
- package/dist/src/channel/send-input.js +1 -0
- package/dist/src/channel/session.d.ts +44 -30
- package/dist/src/channel/session.js +1 -1
- package/dist/src/channel/types.d.ts +8 -35
- package/dist/src/chunks/{use-eve-agent-k-XHfrJT.js → use-eve-agent-CF5D6jSV.js} +361 -367
- package/dist/src/chunks/{use-eve-agent-BXMIf5fR.js → use-eve-agent-DbYZLG0h.js} +364 -368
- package/dist/src/cli/commands/agent-prompt/build-and-verify.md +1 -2
- package/dist/src/cli/commands/channel-add-conflicts.js +1 -1
- package/dist/src/cli/commands/info.d.ts +1 -1
- package/dist/src/cli/commands/info.js +1 -1
- package/dist/src/cli/commands/registry-metadata.d.ts +15 -0
- package/dist/src/cli/commands/registry-metadata.js +1 -0
- package/dist/src/cli/commands/registry-package.d.ts +46 -0
- package/dist/src/cli/commands/registry-package.js +1 -0
- package/dist/src/cli/commands/registry.d.ts +1 -1
- package/dist/src/cli/commands/registry.js +4 -4
- package/dist/src/cli/dev/tui/runner.d.ts +1 -1
- package/dist/src/cli/dev/tui/runner.js +1 -1
- package/dist/src/cli/dev/tui/subagent-pump.js +1 -1
- package/dist/src/cli/dev/tui/terminal-renderer.js +2 -2
- package/dist/src/cli/dev/tui/tui.js +1 -1
- package/dist/src/cli/invoke/invoke.d.ts +1 -1
- package/dist/src/cli/invoke/invoke.js +1 -1
- package/dist/src/cli/invoke/result.d.ts +0 -11
- package/dist/src/cli/invoke/result.js +1 -1
- package/dist/src/client/client-error.d.ts +2 -0
- package/dist/src/client/client-error.js +1 -1
- package/dist/src/client/client.d.ts +7 -14
- package/dist/src/client/client.js +1 -1
- package/dist/src/client/eve-agent-store.d.ts +4 -4
- package/dist/src/client/eve-agent-store.js +1 -1
- package/dist/src/client/index.d.ts +3 -2
- package/dist/src/client/index.js +1 -1
- package/dist/src/client/message-reducer-types.d.ts +3 -0
- package/dist/src/client/message-reducer.js +1 -1
- package/dist/src/client/message-response.d.ts +2 -7
- package/dist/src/client/message-response.js +1 -1
- package/dist/src/client/open-stream.js +1 -1
- package/dist/src/client/session-controls.d.ts +29 -0
- package/dist/src/client/session-controls.js +1 -0
- package/dist/src/client/session-utils.d.ts +0 -20
- package/dist/src/client/session-utils.js +1 -1
- package/dist/src/client/session.d.ts +26 -90
- package/dist/src/client/session.js +1 -1
- package/dist/src/client/sessions.d.ts +20 -0
- package/dist/src/client/sessions.js +1 -0
- package/dist/src/client/types.d.ts +26 -47
- package/dist/src/compiler/extension-compatibility.d.ts +10 -10
- package/dist/src/compiler/extension-compatibility.js +1 -1
- package/dist/src/compiler/normalize-subagent.js +1 -1
- package/dist/src/evals/cli/eval-client.js +1 -1
- package/dist/src/evals/context.js +1 -1
- package/dist/src/evals/session.d.ts +7 -6
- package/dist/src/evals/session.js +1 -1
- package/dist/src/evals/types.d.ts +9 -9
- package/dist/src/execution/agent-handle-dispatch.js +1 -1
- package/dist/src/execution/cancel-descendant-turns-step.js +1 -1
- package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
- package/dist/src/execution/remote-agent-dispatch.d.ts +1 -3
- package/dist/src/execution/remote-agent-dispatch.js +1 -1
- package/dist/src/execution/runtime-context.js +1 -1
- package/dist/src/execution/runtime-errors.d.ts +1 -1
- package/dist/src/execution/session-command-token.d.ts +2 -0
- package/dist/src/execution/session-command-token.js +1 -1
- package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
- package/dist/src/execution/subagent-hitl-proxy.js +1 -1
- package/dist/src/execution/tool-auth.d.ts +1 -1
- package/dist/src/execution/tool-auth.js +1 -1
- package/dist/src/execution/turn-control-receiver.d.ts +2 -2
- package/dist/src/execution/turn-workflow.js +1 -1
- package/dist/src/execution/workflow-entry.js +1 -1
- package/dist/src/execution/workflow-runtime.js +1 -1
- package/dist/src/harness/cancelled-turn-emission.d.ts +1 -1
- package/dist/src/harness/cancelled-turn-emission.js +1 -1
- package/dist/src/harness/emission-state.d.ts +25 -0
- package/dist/src/harness/emission-state.js +1 -0
- package/dist/src/harness/emission.d.ts +5 -37
- package/dist/src/harness/emission.js +1 -1
- package/dist/src/harness/handles/prompt.d.ts +22 -3
- package/dist/src/harness/handles/prompt.js +1 -1
- package/dist/src/harness/handles/store.d.ts +0 -5
- package/dist/src/harness/handles/store.js +1 -1
- package/dist/src/harness/ordered-stream-emitter.d.ts +3 -2
- package/dist/src/harness/ordered-stream-emitter.js +1 -1
- package/dist/src/harness/runtime-actions.js +1 -1
- package/dist/src/harness/session-limit-enforcement.js +1 -1
- package/dist/src/harness/tool-loop.js +1 -1
- package/dist/src/harness/tools.d.ts +1 -1
- package/dist/src/harness/tools.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/nitro/dev-runtime-artifacts.js +1 -1
- package/dist/src/internal/nitro/dev-runtime-source-snapshot-copy.js +1 -1
- package/dist/src/internal/nitro/dev-runtime-source-snapshot-local-roots.d.ts +15 -0
- package/dist/src/internal/nitro/dev-runtime-source-snapshot-local-roots.js +1 -0
- package/dist/src/internal/nitro/dev-runtime-source-snapshot.d.ts +14 -2
- package/dist/src/internal/nitro/dev-runtime-source-snapshot.js +1 -1
- package/dist/src/internal/nitro/host/dev-server-http.js +1 -1
- package/dist/src/internal/nitro/routes/channel-dispatch.d.ts +2 -5
- package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
- package/dist/src/internal/nitro/routes/channel-route-context.d.ts +4 -3
- package/dist/src/internal/nitro/routes/channel-route-context.js +1 -1
- package/dist/src/packages/eve-catalog/src/index.js +1 -1
- package/dist/src/protocol/cancel-turn.d.ts +9 -4
- package/dist/src/protocol/cancel-turn.js +1 -1
- package/dist/src/protocol/message.d.ts +27 -17
- package/dist/src/protocol/message.js +2 -2
- package/dist/src/protocol/reset-session.d.ts +1 -1
- package/dist/src/protocol/routes.d.ts +27 -47
- package/dist/src/protocol/routes.js +1 -1
- package/dist/src/public/channels/chat-sdk/chatSdkChannel.d.ts +19 -21
- package/dist/src/public/channels/chat-sdk/chatSdkChannel.js +2 -2
- package/dist/src/public/channels/discord/discordChannel.d.ts +5 -4
- package/dist/src/public/channels/discord/discordChannel.js +1 -1
- package/dist/src/public/channels/eve.d.ts +11 -10
- package/dist/src/public/channels/eve.js +1 -1
- package/dist/src/public/channels/github/dispatch.d.ts +8 -8
- package/dist/src/public/channels/github/dispatch.js +1 -1
- package/dist/src/public/channels/github/githubChannel.d.ts +4 -3
- package/dist/src/public/channels/github/githubChannel.js +1 -1
- package/dist/src/public/channels/github/pr-context.d.ts +1 -1
- package/dist/src/public/channels/index.d.ts +1 -1
- package/dist/src/public/channels/linear/linearChannel.d.ts +4 -3
- package/dist/src/public/channels/linear/linearChannel.js +1 -1
- package/dist/src/public/channels/slack/index.d.ts +1 -1
- package/dist/src/public/channels/slack/interactions.d.ts +3 -4
- package/dist/src/public/channels/slack/interactions.js +1 -1
- package/dist/src/public/channels/slack/session-operations.d.ts +37 -0
- package/dist/src/public/channels/slack/session-operations.js +1 -0
- package/dist/src/public/channels/slack/slackChannel.d.ts +56 -74
- package/dist/src/public/channels/slack/slackChannel.js +1 -1
- package/dist/src/public/channels/teams/teamsChannel.d.ts +4 -3
- package/dist/src/public/channels/teams/teamsChannel.js +1 -1
- package/dist/src/public/channels/telegram/telegramChannel.d.ts +5 -4
- package/dist/src/public/channels/telegram/telegramChannel.js +1 -1
- package/dist/src/public/channels/twilio/twilioChannel.d.ts +4 -3
- package/dist/src/public/channels/twilio/twilioChannel.js +1 -1
- package/dist/src/public/definitions/callback-context.d.ts +1 -2
- package/dist/src/public/definitions/channel.d.ts +22 -86
- package/dist/src/public/definitions/channel.js +1 -1
- package/dist/src/public/definitions/hook.d.ts +1 -0
- package/dist/src/public/definitions/remote-agent.js +1 -1
- package/dist/src/public/definitions/schedule.d.ts +16 -16
- package/dist/src/public/definitions/tool.d.ts +5 -5
- package/dist/src/public/schedules/index.d.ts +1 -1
- package/dist/src/react/use-eve-agent.d.ts +7 -4
- package/dist/src/react/use-eve-agent.js +1 -1
- package/dist/src/runtime/agent/bootstrap-model-utils.d.ts +11 -0
- package/dist/src/runtime/agent/bootstrap-model-utils.js +1 -1
- package/dist/src/runtime/agent/mock-model-adapter.js +1 -1
- package/dist/src/runtime/agent/mock-model-fixtures.js +2 -2
- package/dist/src/runtime/prompt/compose.js +1 -1
- package/dist/src/runtime/subagents/dynamic-remote-agent-config.js +1 -1
- package/dist/src/runtime/types.d.ts +2 -2
- package/dist/src/services/inspect-application.d.ts +1 -1
- package/dist/src/services/inspect-application.js +1 -1
- package/dist/src/setup/channel-add-conflicts.js +1 -1
- package/dist/src/setup/integrations/linear/setup.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/setup/scaffold/create/web-template.d.ts +1 -1
- package/dist/src/setup/scaffold/create/web-template.js +29 -17
- package/dist/src/shared/async-iterable.d.ts +2 -0
- package/dist/src/shared/async-iterable.js +1 -0
- package/dist/src/shared/channel-definition.d.ts +7 -7
- package/dist/src/shared/schedule-definition.d.ts +2 -2
- package/dist/src/shared/tool-definition.d.ts +1 -1
- package/dist/src/svelte/index.js +1 -1
- package/dist/src/svelte/use-eve-agent.d.ts +8 -5
- package/dist/src/svelte/use-eve-agent.js +1 -1
- package/dist/src/vue/index.js +1 -1
- package/dist/src/vue/use-eve-agent.d.ts +8 -5
- package/dist/src/vue/use-eve-agent.js +1 -1
- package/docs/README.md +6 -6
- package/docs/channels/chat-sdk.mdx +5 -6
- package/docs/channels/custom.mdx +116 -144
- package/docs/channels/discord.mdx +1 -1
- package/docs/channels/eve.mdx +76 -30
- package/docs/channels/github.mdx +1 -1
- package/docs/channels/linear.mdx +10 -10
- package/docs/channels/overview.mdx +2 -2
- package/docs/channels/slack.mdx +46 -15
- package/docs/channels/telegram.mdx +1 -1
- package/docs/channels/twilio.mdx +1 -1
- package/docs/concepts/default-harness.md +11 -3
- package/docs/concepts/execution-model-and-durability.mdx +17 -5
- package/docs/concepts/sessions-runs-and-streaming.md +45 -16
- package/docs/evals/cases.mdx +3 -3
- package/docs/evals/targets.mdx +1 -1
- package/docs/guides/auth-and-route-protection.md +2 -1
- package/docs/guides/client/continuations.mdx +50 -77
- package/docs/guides/client/messages.mdx +29 -33
- package/docs/guides/client/output-schema.mdx +7 -14
- package/docs/guides/client/overview.mdx +40 -11
- package/docs/guides/client/streaming.mdx +18 -23
- package/docs/guides/frontend/nuxt.mdx +1 -1
- package/docs/guides/frontend/overview.mdx +40 -36
- package/docs/guides/frontend/sveltekit.mdx +1 -1
- package/docs/guides/frontend/use-eve-agent-svelte.mdx +19 -23
- package/docs/guides/frontend/use-eve-agent-vue.mdx +21 -25
- package/docs/guides/hooks.md +1 -1
- package/docs/guides/instrumentation.md +1 -1
- package/docs/install-integrations.mdx +4 -2
- package/docs/patterns/dynamic-scheduling.md +16 -15
- package/docs/reference/cli.md +4 -1
- package/docs/schedules.mdx +10 -11
- package/docs/subagents.mdx +1 -1
- package/docs/tools/human-in-the-loop.md +1 -1
- package/docs/tools/overview.mdx +26 -2
- package/docs/tutorial/ship-it.mdx +1 -1
- package/package.json +1 -1
- package/dist/src/channel/cancel.d.ts +0 -6
- package/dist/src/channel/cancel.js +0 -1
- package/dist/src/channel/clear-session.d.ts +0 -4
- package/dist/src/channel/clear-session.js +0 -1
- package/dist/src/channel/compact-session.d.ts +0 -4
- package/dist/src/channel/compact-session.js +0 -1
- package/dist/src/channel/reset-session.d.ts +0 -6
- package/dist/src/channel/reset-session.js +0 -1
- package/dist/src/channel/resolve-active-session.d.ts +0 -4
- package/dist/src/channel/resolve-active-session.js +0 -1
- package/dist/src/channel/send.d.ts +0 -6
- package/dist/src/channel/send.js +0 -1
package/docs/channels/linear.mdx
CHANGED
|
@@ -11,10 +11,12 @@ 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
|
|
14
|
+
eve add linear
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
|
|
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.
|
|
18
|
+
|
|
19
|
+
The flow checks that the Vercel CLI is authenticated, creates or links a Vercel project when needed, reuses a compatible existing connector when available or provisions an app-scoped Linear Connect client, and replaces its default trigger with `/eve/v1/linear`. It then installs `@vercel/connect` and writes `agent/channels/linear.ts` with the connector UID.
|
|
18
20
|
|
|
19
21
|
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.
|
|
20
22
|
|
|
@@ -158,7 +160,7 @@ await channel.linear.updateSession({
|
|
|
158
160
|
|
|
159
161
|
## Proactive sessions
|
|
160
162
|
|
|
161
|
-
Use the channel's
|
|
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(...)`.
|
|
162
164
|
|
|
163
165
|
```ts
|
|
164
166
|
import { defineSchedule } from "eve/schedules";
|
|
@@ -167,15 +169,13 @@ import linear from "../channels/linear";
|
|
|
167
169
|
|
|
168
170
|
export default defineSchedule({
|
|
169
171
|
cron: "0 14 * * 1",
|
|
170
|
-
async run({
|
|
172
|
+
async run({ to, waitUntil, appAuth }) {
|
|
171
173
|
waitUntil(
|
|
172
|
-
|
|
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.", {
|
|
173
178
|
auth: appAuth,
|
|
174
|
-
message: "Post a concise status update with blockers and next actions.",
|
|
175
|
-
target: {
|
|
176
|
-
issueId: "EVE-123",
|
|
177
|
-
initialActivity: "Preparing the status update.",
|
|
178
|
-
},
|
|
179
179
|
}),
|
|
180
180
|
);
|
|
181
181
|
},
|
|
@@ -6,7 +6,7 @@ description: "How users reach your agent: the channel contract, the base eve HTT
|
|
|
6
6
|
A channel is the edge adapter between a platform and your agent. It does three things:
|
|
7
7
|
|
|
8
8
|
- Normalizes platform input into a user message.
|
|
9
|
-
- Owns the
|
|
9
|
+
- Owns the channel-local address that maps a platform conversation to its current durable session.
|
|
10
10
|
- Decides delivery, meaning how, where, and whether a response goes back.
|
|
11
11
|
|
|
12
12
|
eve ships a base HTTP channel plus first-class platform channels, and you can author your own. Browse the full set in the [Integrations](/integrations) gallery and choose the Channels filter.
|
|
@@ -36,7 +36,7 @@ The eve channel is the framework's default HTTP session API, the routes the term
|
|
|
36
36
|
|
|
37
37
|
## Custom channels
|
|
38
38
|
|
|
39
|
-
When eve doesn't ship a channel for your surface, build one with `defineChannel` from `eve/channels`. A custom channel declares route handlers (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`, `WS`), an `events` map, and
|
|
39
|
+
When eve doesn't ship a channel for your surface, build one with `defineChannel` from `eve/channels`. A custom channel declares route handlers (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`, `WS`), an `events` map, and uses `send(address, input)` to start or resume a session. See [Custom channels](./custom) for the full walkthrough, including WebSocket routes, cross-channel hand-off, channel metadata, address tokens, and file uploads.
|
|
40
40
|
|
|
41
41
|
## Relationship to the Chat SDK
|
|
42
42
|
|
package/docs/channels/slack.mdx
CHANGED
|
@@ -108,7 +108,7 @@ Like `threadContext`, this helper calls `conversations.replies` and requires the
|
|
|
108
108
|
|
|
109
109
|
#### Cancel an active turn
|
|
110
110
|
|
|
111
|
-
Message hooks (`onMessage`, `onAppMention`, and `onDirectMessage`) receive
|
|
111
|
+
Message hooks (`onMessage`, `onAppMention`, and `onDirectMessage`) receive thread-bound session operations directly on `ctx`. Call `ctx.cancel({ turnId? })` before returning `{ auth }` to stop the current turn and queue the new Slack message as replacement input, producing a debounce-like experience:
|
|
112
112
|
|
|
113
113
|
```ts title="agent/channels/slack.ts"
|
|
114
114
|
export default slackChannel({
|
|
@@ -123,11 +123,28 @@ export default slackChannel({
|
|
|
123
123
|
});
|
|
124
124
|
```
|
|
125
125
|
|
|
126
|
-
`"accepted"` means the cancellation request
|
|
126
|
+
`"accepted"` means the live thread session durably queued the cancellation request. A parked session consumes it as a no-op; `"no_active_turn"` means the thread has no active session owner. Both are successful outcomes, so the hook can still return `{ auth }` to deliver the replacement message. Cancellation never sends input itself. A custom `onInteraction` handler receives the same flat operations, which is useful for a Stop button that should cancel without replacement input.
|
|
127
|
+
|
|
128
|
+
Message and interaction hooks expose every current-owner operation directly on `ctx`:
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
async onAppMention(ctx) {
|
|
132
|
+
await ctx.send("Run a separate turn.");
|
|
133
|
+
await ctx.respond(inputResponses);
|
|
134
|
+
await ctx.cancel();
|
|
135
|
+
await ctx.compact();
|
|
136
|
+
await ctx.clear();
|
|
137
|
+
await ctx.reset({ reason: "Start over" });
|
|
138
|
+
const session = await ctx.resolveSession();
|
|
139
|
+
return { auth: null };
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
These calls are independent examples; a handler normally chooses one. `ctx.send()` is the only method that can create a session when the thread is unowned. It derives Slack auth from the inbound user unless `auth` is supplied explicitly. Use `await ctx.resolveSession()` only when later work must stay pinned to the currently owning durable session ID.
|
|
127
144
|
|
|
128
145
|
#### Reset a conversation
|
|
129
146
|
|
|
130
|
-
Use the thread-bound `ctx.reset({ reason? })`
|
|
147
|
+
Use the thread-bound `ctx.reset({ reason? })` method when the conversation should start over instead. Reset terminally retires the session that currently owns the thread, including any in-flight turn. The next delivered message starts a new session with fresh history, state, and a new session-scoped sandbox:
|
|
131
148
|
|
|
132
149
|
```ts title="agent/channels/slack.ts"
|
|
133
150
|
export default slackChannel({
|
|
@@ -142,11 +159,11 @@ export default slackChannel({
|
|
|
142
159
|
});
|
|
143
160
|
```
|
|
144
161
|
|
|
145
|
-
Reset returns `{ status: "reset", previousSessionId }` when the thread had a session, or `{ status: "no_active_session" }` when it was already free. Both outcomes are successful. Returning `null` after reset consumes the triggering message as a command; return `{ auth }` instead to deliver that message as the first turn of the fresh session. Custom `onInteraction` handlers receive the same
|
|
162
|
+
Reset returns `{ status: "reset", previousSessionId }` when the thread had a session, or `{ status: "no_active_session" }` when it was already free. Both outcomes are successful. Returning `null` after reset consumes the triggering message as a command; return `{ auth }` instead to deliver that message as the first turn of the fresh session. Custom `onInteraction` handlers receive the same flat operations, which is useful for a New conversation button.
|
|
146
163
|
|
|
147
164
|
### Other Events API callbacks
|
|
148
165
|
|
|
149
|
-
Use `onEvent` for subscribed events such as `reaction_added`, `team_join`, or `channel_created`. It receives the raw, open-ended Slack event and owns control flow. `ctx.
|
|
166
|
+
Use `onEvent` for subscribed events such as `reaction_added`, `team_join`, or `channel_created`. It receives the raw, open-ended Slack event and owns control flow. Call `ctx.send(message, { target, auth })` zero, one, or many times to start turns. Each call returns the resulting session.
|
|
150
167
|
|
|
151
168
|
```ts title="agent/channels/slack.ts"
|
|
152
169
|
import { connectSlackCredentials } from "@vercel/connect/eve";
|
|
@@ -156,25 +173,39 @@ const onboardingChannels = ["C0123ABC", "C0456DEF"];
|
|
|
156
173
|
|
|
157
174
|
export default slackChannel({
|
|
158
175
|
credentials: connectSlackCredentials("slack/my-agent"),
|
|
159
|
-
async onEvent(
|
|
176
|
+
async onEvent(ctx, event) {
|
|
160
177
|
if (event.type !== "team_join") return;
|
|
161
178
|
|
|
162
179
|
await Promise.all(
|
|
163
180
|
onboardingChannels.map((channelId) =>
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
181
|
+
ctx.send(
|
|
182
|
+
`A user joined the Slack workspace. Onboard them from this event:\n${JSON.stringify(event)}`,
|
|
183
|
+
{
|
|
184
|
+
target: { channelId },
|
|
185
|
+
auth: null,
|
|
186
|
+
},
|
|
187
|
+
),
|
|
169
188
|
),
|
|
170
189
|
);
|
|
171
190
|
},
|
|
172
191
|
});
|
|
173
192
|
```
|
|
174
193
|
|
|
175
|
-
The webhook invocation already keeps an awaited `onEvent` handler alive. Use `ctx.waitUntil(promise)` for deliberately detached work, matching a handler-form schedule. `ctx.slack.request(operation, body)` provides workspace-scoped Slack Web API access, while `ctx.envelope` carries delivery metadata such as `team_id`, `event_id`, and `event_time`. Calls to `ctx.
|
|
194
|
+
The webhook invocation already keeps an awaited `onEvent` handler alive. Use `ctx.waitUntil(promise)` for deliberately detached work, matching a handler-form schedule. `ctx.slack.request(operation, body)` provides workspace-scoped Slack Web API access, while `ctx.envelope` carries delivery metadata such as `team_id`, `event_id`, and `event_time`. Calls to `ctx.send` automatically seed the callback's team id into Slack session state.
|
|
195
|
+
|
|
196
|
+
Because a generic event is not necessarily tied to one thread, put the target in each operation's input:
|
|
176
197
|
|
|
177
|
-
|
|
198
|
+
```ts
|
|
199
|
+
const target = { channelId, threadTs };
|
|
200
|
+
|
|
201
|
+
await ctx.send("Follow up", { auth: null, target });
|
|
202
|
+
await ctx.respond(inputResponses, { auth: null, target });
|
|
203
|
+
await ctx.cancel({ target, turnId });
|
|
204
|
+
await ctx.compact({ target });
|
|
205
|
+
await ctx.clear({ target });
|
|
206
|
+
await ctx.reset({ reason: "Start over", target });
|
|
207
|
+
const session = await ctx.resolveSession({ target });
|
|
208
|
+
```
|
|
178
209
|
|
|
179
210
|
`onEvent` is the raw fallback after the message hooks. If an event is not claimed by `onAppMention`, `onDirectMessage`, or `onMessage`, an authored `onEvent` receives it; otherwise eve applies the built-in mention/DM default or ignores it.
|
|
180
211
|
|
|
@@ -233,7 +264,7 @@ The default handlers reply in-thread and show progress. Typing indicators post a
|
|
|
233
264
|
|
|
234
265
|
Outbound text preserves bare `@` tokens as literal text. To mention a user, embed Slack's `<@USER_ID>` syntax directly or use `channel.thread.mentionUser(userId)`.
|
|
235
266
|
|
|
236
|
-
When a session starts without a `threadTs` (say, from a schedule
|
|
267
|
+
When a session starts without a `threadTs` (say, from a schedule's `to(slack, target).send(...)`), eve gives it a unique temporary continuation token. The first agent post anchors the session to the Slack message timestamp, and later posts and mentions resume that same session. Pass `initialMessage` with a `Card` to land a structured anchor first instead. `threadTs` and `initialMessage` are mutually exclusive.
|
|
237
268
|
|
|
238
269
|
The example below overrides `onAppMention` to gate on an authored message and posts the completed reply to the thread. Event handlers receive `(eventData, channel, ctx)`, with Slack platform handles on `channel.thread` and `channel.slack`:
|
|
239
270
|
|
|
@@ -272,7 +303,7 @@ events: {
|
|
|
272
303
|
|
|
273
304
|
### Proactive sessions
|
|
274
305
|
|
|
275
|
-
Start a session without an inbound message through `
|
|
306
|
+
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, threadTs?, initialMessage? }`.
|
|
276
307
|
|
|
277
308
|
### Attachments
|
|
278
309
|
|
|
@@ -51,7 +51,7 @@ Human-in-the-loop (HITL) turns option requests into inline-keyboard buttons and
|
|
|
51
51
|
|
|
52
52
|
### Proactive sessions
|
|
53
53
|
|
|
54
|
-
Start a session without an inbound message through `
|
|
54
|
+
Start a session without an inbound message through `to(telegram, target).send(message, { auth })` from a schedule `run` handler, or `ctx.to(telegram, target).send(message, { auth })` from another channel. `target.chatId` is required. Add `messageThreadId` to land in a specific forum topic.
|
|
55
55
|
|
|
56
56
|
Private proactive chats stay keyed to the chat, or to the chat plus `messageThreadId` when you target a topic. Group and supergroup proactive sends anchor to the bot message id returned by Telegram, so replies to different bot messages can resume different sessions in the same chat. If Telegram does not return a recognized chat type for an outbound send, eve keeps the session unanchored instead of guessing.
|
|
57
57
|
|
package/docs/channels/twilio.mdx
CHANGED
|
@@ -66,7 +66,7 @@ SMS and voice have no native button or card affordance, so HITL prompts do not r
|
|
|
66
66
|
|
|
67
67
|
### Proactive sessions
|
|
68
68
|
|
|
69
|
-
Start a session without an inbound message through `
|
|
69
|
+
Start a session without an inbound message through `to(twilio, target).send(message, { auth })` from a schedule `run` handler, or `ctx.to(twilio, target).send(message, { auth })` from another channel. `target.phoneNumber` is required, and the channel needs `messaging.from` or `messaging.messagingServiceSid` for the outbound sender.
|
|
70
70
|
|
|
71
71
|
### Attachments
|
|
72
72
|
|
|
@@ -20,9 +20,17 @@ export default defineAgent({
|
|
|
20
20
|
|
|
21
21
|
Compaction also preserves the framework's own tool state automatically. It resets read-before-write tracking (so a write afterward re-reads the file whose read evidence was summarized away) and re-injects the active todo list, so the model keeps its task list across the summary. There is no per-tool hook to configure.
|
|
22
22
|
|
|
23
|
-
Clients and channels can also request compaction between turns. Call
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
Clients and channels can also request compaction between turns. Call
|
|
24
|
+
`ClientSession.compact()`, a channel route's `compact(address)`, or
|
|
25
|
+
`attachSession(sessionId).compact()`. The request does not append a user message;
|
|
26
|
+
if a turn is running, eve queues it until that turn settles. A successful manual
|
|
27
|
+
compaction emits the same `compaction.requested` and `compaction.completed`
|
|
28
|
+
events as automatic compaction, followed by `session.waiting`.
|
|
29
|
+
|
|
30
|
+
To discard model-message history instead of summarizing it, call the corresponding
|
|
31
|
+
`clear()` method on any of those handles. Clearing preserves the session identity,
|
|
32
|
+
system prompt, configured tools and skills, durable state, limits, and sandbox.
|
|
33
|
+
Its stream boundary is `context.cleared` followed by `session.waiting`.
|
|
26
34
|
|
|
27
35
|
## Built-in tools
|
|
28
36
|
|
|
@@ -68,11 +68,23 @@ Some work has to wait, including a human approving a [tool](../tools), an intera
|
|
|
68
68
|
|
|
69
69
|
## Message delivery and queueing
|
|
70
70
|
|
|
71
|
-
eve does not maintain a durable FIFO queue of user messages for a session.
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
71
|
+
eve does not maintain a durable FIFO queue of user messages for a session. An
|
|
72
|
+
ID-addressed HTTP delivery and a channel-address delivery both target the
|
|
73
|
+
session's current command inbox; neither is a general message queue.
|
|
74
|
+
|
|
75
|
+
Only one active session can own a channel continuation token. A channel-created
|
|
76
|
+
session commits both its stable session-ID alias and its channel alias before
|
|
77
|
+
processing the first turn, and fails creation if another run already owns the
|
|
78
|
+
channel alias. Rekeying replaces only that channel alias. An HTTP-created
|
|
79
|
+
session has the stable ID alias and no channel continuation token. Competing
|
|
80
|
+
channel input is not forwarded to the owner.
|
|
81
|
+
|
|
82
|
+
When a session is waiting, a delivery through its ID or current channel address
|
|
83
|
+
wakes the session and starts the next turn. When a turn is already active, the
|
|
84
|
+
inbox may accept additional deliveries, but the runtime only drains them at
|
|
85
|
+
specific workflow boundaries. If more than one delivery is ready when the driver
|
|
86
|
+
checks, eve may fold them into the next turn; that drain is best-effort and
|
|
87
|
+
depends on workflow and transport timing.
|
|
76
88
|
|
|
77
89
|
So don't rely on concurrent sends to the same session behaving like a typical ordered chat queue. For deterministic behavior, send one user turn at a time and wait for `session.waiting` before sending the next message to the same session. If your channel can receive bursts while the agent is working, keep your own per-session queue in the channel or app layer, then deliver the next message after the session parks again. Separate sessions still run independently.
|
|
78
90
|
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "Sessions, Runs & Streaming"
|
|
3
|
-
description: "The session
|
|
3
|
+
description: "The ID-addressed session contract: messages, controls, the NDJSON event stream, and reconnecting."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
Every eve app speaks the same stable HTTP API to a [durable session](./execution-model-and-durability). This page is the contract you hold: the handles you get back, the events you stream, and how to reconnect.
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## Identity by surface
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
The HTTP API and TypeScript client use one durable `sessionId` for messages,
|
|
11
|
+
controls, and streams. Every operation targets that exact session; none follows
|
|
12
|
+
or creates a replacement implicitly.
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
Authored channels also have channel-local continuation tokens. A token addresses
|
|
15
|
+
whichever session currently owns a platform conversation, such as a Slack thread.
|
|
16
|
+
That identity stays behind the channel boundary and is never accepted or returned
|
|
17
|
+
by the eve HTTP session API. See [Custom channels](../channels/custom#address-and-session-handles).
|
|
16
18
|
|
|
17
19
|
Sessions last 30 days by default; configure `limits.sessionTimeoutMs` in
|
|
18
20
|
`agent.ts`, or set it to `false` to disable the deadline. At expiration, eve
|
|
@@ -30,7 +32,8 @@ curl -X POST http://127.0.0.1:2000/eve/v1/session \
|
|
|
30
32
|
-d '{"message":"Summarize the latest forecast."}'
|
|
31
33
|
```
|
|
32
34
|
|
|
33
|
-
eve responds right away
|
|
35
|
+
eve responds right away with the durable `sessionId` in the JSON body and
|
|
36
|
+
`x-eve-session-id` header.
|
|
34
37
|
|
|
35
38
|
## Stream a session
|
|
36
39
|
|
|
@@ -47,6 +50,7 @@ The stream is newline-delimited JSON (NDJSON), one event per line:
|
|
|
47
50
|
| `message.received` | An inbound user message was accepted; carries flattened text plus structured text/file parts. |
|
|
48
51
|
| `step.started` | A model step began. |
|
|
49
52
|
| `actions.requested` | The model requested one or more actions, including tool calls; calls stream before execution. |
|
|
53
|
+
| `action.partial` | A locally executed tool generator yielded a preliminary output snapshot. |
|
|
50
54
|
| `action.result` | A tool call returned. |
|
|
51
55
|
| `input.requested` | The run paused for human input ([HITL](/docs/human-in-the-loop) approval or `ask_question`); carries `requests`. |
|
|
52
56
|
| `subagent.called` | A subagent was delegated; carries `childSessionId` to attach to. |
|
|
@@ -65,12 +69,14 @@ The stream is newline-delimited JSON (NDJSON), one event per line:
|
|
|
65
69
|
| `turn.completed` | The turn finished. |
|
|
66
70
|
| `turn.failed` | The turn failed; carries `{ code, message, details? }`. |
|
|
67
71
|
| `turn.cancelled` | The turn was cancelled before finishing; always followed by `session.waiting`. |
|
|
68
|
-
| `session.waiting` | The session parked
|
|
72
|
+
| `session.waiting` | The session parked and is ready for the next message. |
|
|
69
73
|
| `session.failed` | The session failed. |
|
|
70
74
|
| `session.completed` | The session reached a terminal end. |
|
|
71
75
|
|
|
72
76
|
`reasoning.appended` and `message.appended` stream incremental output as it arrives. When the durable stream writer is busy, eve may coalesce adjacent deltas of the same type; the text remains in source order, and any other event forms an ordering barrier. Each append carries both the new delta and the cumulative text for the current block. The finalized block shows up on `message.completed` and `reasoning.completed`, which is the compatibility path for clients that don't render incremental streaming.
|
|
73
77
|
|
|
78
|
+
`action.partial` carries one complete preliminary output snapshot from an authored async-generator tool. A later partial for the same `callId` replaces it, and `action.result` is the final snapshot. When the durable writer is busy, eve may keep only the newest adjacent partial for a call. Treat partials as last-write-wins: a durable step can retry and replay overlapping event runs. Provider-executed tool progress and MCP progress notifications are not projected as `action.partial` events.
|
|
79
|
+
|
|
74
80
|
Note: consider the privacy, confidentiality, and user-experience implications for displaying, storing, or transmitting reasoning events in your application.
|
|
75
81
|
|
|
76
82
|
`message.completed` can fire more than once in a turn: the agent often emits interim assistant text before a tool call. To tell tool-call narration from a terminal reply, check `message.completed.data.finishReason`. `step.completed.data.finishReason` mirrors the step outcome, and usage lives on `step.completed`.
|
|
@@ -134,12 +140,12 @@ Authored [hooks](../guides/hooks) receive the same envelope, but observe each ev
|
|
|
134
140
|
|
|
135
141
|
## Send a follow-up message
|
|
136
142
|
|
|
137
|
-
Once the session is waiting (you'll see `session.waiting`), POST your follow-up to
|
|
143
|
+
Once the session is waiting (you'll see `session.waiting`), POST your follow-up to its ID-addressed messages endpoint:
|
|
138
144
|
|
|
139
145
|
```bash
|
|
140
146
|
curl -X POST http://127.0.0.1:2000/eve/v1/session/<sessionId> \
|
|
141
147
|
-H 'content-type: application/json' \
|
|
142
|
-
-d '{"
|
|
148
|
+
-d '{"message":"Now send the short version."}'
|
|
143
149
|
```
|
|
144
150
|
|
|
145
151
|
The follow-up reuses the same durable session: same history, same state.
|
|
@@ -163,9 +169,30 @@ curl -X POST http://127.0.0.1:2000/eve/v1/session/<sessionId>/cancel
|
|
|
163
169
|
# {"ok":true,"sessionId":"<sessionId>","status":"accepted"}
|
|
164
170
|
```
|
|
165
171
|
|
|
166
|
-
`"accepted"` means
|
|
172
|
+
`"accepted"` means the live session durably queued the request. Confirm an actual cancellation on the stream as `turn.cancelled` followed by `session.waiting`; the session then accepts the next message normally. If the turn is waiting on active local or remote subagents, eve also requests cancellation of every adopted child, recursively, before settling the parent. Each child reports its own cancellation boundary on its child-session stream; the parent does not emit `subagent.completed` for cancelled work. A live but already-parked session also returns `"accepted"` and consumes the command as a no-op. `"no_active_turn"` means the session or channel address is unknown or terminal. Both statuses are success, so clients can fire and forget. See the [eve channel](../channels/eve) for the full route contract.
|
|
173
|
+
|
|
174
|
+
The HTTP route returns `202` for `"accepted"` and `200` for
|
|
175
|
+
`"no_active_turn"`. Only the accepted result includes `sessionId`.
|
|
176
|
+
|
|
177
|
+
Custom channel routes request the same cancellation through
|
|
178
|
+
`from(address).cancel()` or `attachSession(sessionId).cancel()`. See
|
|
179
|
+
[custom channels](../channels/custom#channel-operations-and-session-handles).
|
|
180
|
+
|
|
181
|
+
## Compact, clear, and reset
|
|
182
|
+
|
|
183
|
+
All session controls are ID-addressed and accept no continuation token:
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
curl -X POST http://127.0.0.1:2000/eve/v1/session/<sessionId>/compact
|
|
187
|
+
curl -X POST http://127.0.0.1:2000/eve/v1/session/<sessionId>/clear
|
|
188
|
+
curl -X POST http://127.0.0.1:2000/eve/v1/session/<sessionId>/reset \
|
|
189
|
+
-H 'content-type: application/json' \
|
|
190
|
+
-d '{"reason":"Start over"}'
|
|
191
|
+
```
|
|
167
192
|
|
|
168
|
-
|
|
193
|
+
Compaction summarizes context, clear removes model-message history in place,
|
|
194
|
+
and reset terminally retires the session. A reset ID never becomes a new session;
|
|
195
|
+
create another session explicitly for a fresh conversation.
|
|
169
196
|
|
|
170
197
|
## Reconnect and rewind
|
|
171
198
|
|
|
@@ -183,7 +210,9 @@ A negative `startIndex` reads relative to the stream's current tail. For example
|
|
|
183
210
|
curl "http://127.0.0.1:2000/eve/v1/session/<sessionId>/stream?startIndex=-1"
|
|
184
211
|
```
|
|
185
212
|
|
|
186
|
-
|
|
213
|
+
Because a tail-relative position does not resolve to an absolute consumed-event
|
|
214
|
+
count, client tail reads do not automatically reconnect or advance the stored
|
|
215
|
+
cursor.
|
|
187
216
|
|
|
188
217
|
For a catch-up read that stops instead of following the live stream, pass `includeTailIndex=1`. The response then carries the `x-eve-stream-tail-index` header: the zero-based index of the last durably recorded event, or `-1` before the first. Read from your cursor until it passes that tail, then disconnect — reconnecting from the updated cursor if the connection drops first:
|
|
189
218
|
|
|
@@ -198,7 +227,7 @@ The lookup is opt-in; requests without the parameter get no header. The TypeScri
|
|
|
198
227
|
|
|
199
228
|
For scripts, server-to-server calls, tests, evals, and custom UIs, `eve/client` wraps these routes in a typed client so you don't hand-roll the POST and NDJSON stream loop.
|
|
200
229
|
|
|
201
|
-
Start with the [TypeScript SDK](../guides/client/overview) guide. It covers basic usage, sending messages,
|
|
230
|
+
Start with the [TypeScript SDK](../guides/client/overview) guide. It covers basic usage, sending messages, session state, streaming, and per-turn `outputSchema` results.
|
|
202
231
|
|
|
203
232
|
## Inspect the agent over HTTP
|
|
204
233
|
|
|
@@ -224,6 +253,6 @@ The order is structural, not incidental. By the time a resolver or hook reads ch
|
|
|
224
253
|
## What to read next
|
|
225
254
|
|
|
226
255
|
- [Execution model & durability](./execution-model-and-durability): what makes a session durable and how parked work resumes.
|
|
227
|
-
- [Channels](../channels/overview):
|
|
256
|
+
- [Channels](../channels/overview): how platform addresses map to durable sessions.
|
|
228
257
|
- [TypeScript SDK](../guides/client/overview): call these routes from scripts and server-side code.
|
|
229
258
|
- [Frontend](../guides/frontend/overview): `useEveAgent` instead of raw routes.
|
package/docs/evals/cases.mdx
CHANGED
|
@@ -101,12 +101,12 @@ export default defineEval({
|
|
|
101
101
|
|
|
102
102
|
`t` drives the primary session; `t.newSession()` returns an independent `EveEvalSession` against the same target, whose events feed the same run-level assertions.
|
|
103
103
|
|
|
104
|
-
- `t.send(
|
|
105
|
-
- `t.start(
|
|
104
|
+
- `t.send(message, options?)` sends a turn and waits for it to settle. It matches `ClientSession.send()` and resolves to a turn carrying `.message` and `.expectOk()`.
|
|
105
|
+
- `t.start(message)` starts a text turn but returns as soon as the server accepts it. The returned live turn exposes `.sessionId`, `.waitForEvent(...)`, `.cancel()`, and `.result()` for coordinating with work that is still running.
|
|
106
106
|
- `t.cancel()` requests cooperative cancellation of the primary session's active turn. Both `accepted` and `no_active_turn` are successful outcomes.
|
|
107
107
|
- `t.sendFile(text, path, mediaType?)` attaches a local file as a data URL.
|
|
108
108
|
- `t.requireInputRequest(filter?)` records a gate, requires exactly one pending request, and returns it. Filters match tool name, action input, prompt, display, and option ids.
|
|
109
|
-
- `t.respond(
|
|
109
|
+
- `t.respond(responses, options?)` answers specific pending input requests and sends them as the next turn.
|
|
110
110
|
- `t.respondAll(optionId)` answers every pending input request with the same option and sends the responses as the next turn.
|
|
111
111
|
- `t.reply` is the last assistant message (or `null`); `t.sessionId` is the current session id; `t.events` is the full typed event stream captured so far.
|
|
112
112
|
|
package/docs/evals/targets.mdx
CHANGED
|
@@ -24,7 +24,7 @@ export default defineEval({
|
|
|
24
24
|
|
|
25
25
|
- `t.target.fetch(path, init)` performs an authenticated fetch against the target, useful for channel and webhook ingress. See [Authentication](#authentication) for how the runner authenticates.
|
|
26
26
|
- `t.target.dispatchSchedule(id)` triggers a [schedule](../schedules) through the dev-only schedule route and returns the session ids it created. It works only against a target with dev routes enabled (the local `eve eval` dev server, or a deployment running in development mode), and throws otherwise.
|
|
27
|
-
- `t.target.attachSession(sessionId, { startIndex? })` consumes one turn from a session created outside the eval, by a channel or a schedule, so its events feed the run-level assertions. `startIndex` skips events before that position, so a session already partway through its stream resumes from where you left off rather than replaying from the start.
|
|
27
|
+
- `t.target.attachSession(sessionId, { startIndex? })` consumes one turn from a session created outside the eval, by a channel or a schedule, so its events feed the run-level assertions. `startIndex` skips events before that position, so a session already partway through its stream resumes from where you left off rather than replaying from the start. The attached session stays bound to that exact ID, so `session.send(...)` and `session.respond(...)` continue it after the turn parks (`session.waiting`).
|
|
28
28
|
- `t.target.watchTurn(sessionId, { startIndex? })` starts consuming an externally-created turn immediately and returns a live-turn handle. Use `waitForEvent(...)` to coordinate with mid-turn work, `cancel()` to request cancellation, and `result()` to consume through the boundary. The live turn's `.session` is the attached `EveEvalSession` for follow-up sends after settlement.
|
|
29
29
|
|
|
30
30
|
Sessions attached this way are full `EveEvalSession`s: you can keep driving them and assert directly on that session (`session.succeeded()`, `session.calledTool(...)`). Aggregate assertions on `t` continue to read the whole run, including every attached session.
|
|
@@ -16,6 +16,7 @@ The route-auth policy lives on the HTTP channel factory (`agent/channels/eve.ts`
|
|
|
16
16
|
|
|
17
17
|
- `POST /eve/v1/session`
|
|
18
18
|
- `POST /eve/v1/session/:sessionId`
|
|
19
|
+
- `POST /eve/v1/session/:sessionId/{cancel,compact,clear,reset}`
|
|
19
20
|
- `GET /eve/v1/session/:sessionId/stream`
|
|
20
21
|
|
|
21
22
|
These routes are protected by the channel's auth policy. eve fails closed by default: production traffic is rejected unless you configure an authenticator that accepts it, and anonymous access requires an explicit `none()`.
|
|
@@ -181,7 +182,7 @@ import { createUnauthorizedResponse } from "eve/channels/auth";
|
|
|
181
182
|
|
|
182
183
|
export default defineChannel({
|
|
183
184
|
routes: [
|
|
184
|
-
POST("/message", async (req
|
|
185
|
+
POST("/message", async (req) => {
|
|
185
186
|
if (!isAllowed(req)) {
|
|
186
187
|
return createUnauthorizedResponse({
|
|
187
188
|
status: 403, // defaults to 401; code defaults to "forbidden" / "unauthorized"
|