Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .changeset/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"$schema": "https://unpkg.com/@changesets/config@3.1.4/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false,
"fixed": [],
"fixed": [["eve", "@vercel/eve-photon", "@vercel/eve-slack"]],
"linked": [],
"access": "public",
"baseBranch": "main",
Expand Down
7 changes: 7 additions & 0 deletions .changeset/integration-packages.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"eve": patch
"@vercel/eve-photon": patch
"@vercel/eve-slack": patch
---

Move the first-class Photon and Slack channels into independently installable packages released in lockstep with eve.
2 changes: 1 addition & 1 deletion apps/docs/app/[lang]/(home)/components/file-tree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ export default defineSandbox({
NavIcon: IconMessage,
description: "Add channel files to use the same agent in Slack, Discord, Teams, or the web.",
code: `import { slackChannel } from
"eve/channels/slack";
"@vercel/eve-slack";

export default slackChannel({
botName: "my-agent",
Expand Down
4 changes: 2 additions & 2 deletions apps/docs/lib/integrations/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ npm install eve@latest @vercel/connect

\`\`\`ts
// agent/channels/slack.ts
import { slackChannel } from "eve/channels/slack";
import { slackChannel } from "@vercel/eve-slack";
import { connectSlackCredentials } from "@vercel/connect/eve";

export default slackChannel({
Expand Down Expand Up @@ -856,7 +856,7 @@ eve add channel/photon

\`\`\`ts
import { connectPhotonCredentials } from "@vercel/connect/eve";
import { photonChannel } from "eve/channels/photon";
import { photonChannel } from "@vercel/eve-photon";

export default photonChannel({
credentials: connectPhotonCredentials(process.env.PHOTON_CONNECTOR_ID!),
Expand Down
6 changes: 3 additions & 3 deletions apps/docs/lib/templates/sources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default eveChannel({
"agent/channels/slack.ts",
"typescript",
`import { connectSlackCredentials } from "@vercel/connect/eve";
import { slackChannel } from "eve/channels/slack";
import { slackChannel } from "@vercel/eve-slack";

// SLACK_CONNECTOR is the UID returned by \`vercel connect create slack\`.
// For local setup, create a connector with:
Expand Down Expand Up @@ -173,7 +173,7 @@ export default defineAgent({
"agent/channels/slack.ts",
"typescript",
`import { connectSlackCredentials } from '@vercel/connect/eve';
import { slackChannel } from 'eve/channels/slack';
import { slackChannel } from '@vercel/eve-slack';
import { designAgentConfig } from '../../generated/config.js';

const setupIncompleteMessage =
Expand Down Expand Up @@ -405,7 +405,7 @@ export default defineAgent({
"agent/channels/slack.ts",
"typescript",
`import { connectSlackCredentials } from "@vercel/connect/eve";
import { slackChannel } from "eve/channels/slack";
import { slackChannel } from "@vercel/eve-slack";

// SLACK_CONNECTOR is provisioned by the "Deploy with Vercel" button. To set it
// up yourself, create a connector with \`vercel connect create slack --triggers\`
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/public/r/channel/photon.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"type": "registry:item",
"title": "Photon",
"description": "Connect an eve agent to iMessage through Photon with guided project and phone setup.",
"dependencies": ["@vercel/connect@0.4.3"],
"dependencies": ["@vercel/connect@0.4.3", "@vercel/eve-photon@__EVE_VERSION__"],
"meta": {
"eve": {
"setup": {
Expand Down
10 changes: 8 additions & 2 deletions apps/docs/registry.json
Original file line number Diff line number Diff line change
Expand Up @@ -666,7 +666,10 @@
"requires": ">=0.27.8"
}
},
"dependencies": ["@vercel/connect@0.4.2"]
"dependencies": [
"@vercel/connect@0.4.3",
"@vercel/eve-slack@__EVE_VERSION__"

@vercel vercel Bot Jul 28, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registry dependencies pin @vercel/eve-slack/@vercel/eve-photon to an unresolved __EVE_VERSION__ placeholder, causing channel installs to fail with an invalid version spec.

Fix on Vercel

]
},
{
"name": "channel/discord",
Expand Down Expand Up @@ -1209,7 +1212,10 @@
"type": "registry:item",
"title": "Photon",
"description": "Connect an eve agent to iMessage through Photon with guided project and phone setup.",
"dependencies": ["@vercel/connect@0.4.3"],
"dependencies": [
"@vercel/connect@0.4.3",
"@vercel/eve-photon@__EVE_VERSION__"
],
"meta": {
"eve": {
"setup": {
Expand Down
2 changes: 1 addition & 1 deletion docs/channels/custom.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ When a parent agent dispatches a subagent, the framework forwards the parent's c
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.

```ts
import { slackContinuationToken } from "eve/channels/slack";
import { slackContinuationToken } from "@vercel/eve-slack";
import { twilioContinuationToken } from "eve/channels/twilio";

slackContinuationToken("C0123ABC", "1800000000.001234"); // "C0123ABC:1800000000.001234"
Expand Down
2 changes: 1 addition & 1 deletion docs/channels/photon.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ first initializes:

```ts title="agent/channels/photon.ts"
import { connectPhotonCredentials } from "@vercel/connect/eve";
import { photonChannel } from "eve/channels/photon";
import { photonChannel } from "@vercel/eve-photon";

export default photonChannel({
credentials: connectPhotonCredentials(process.env.PHOTON_CONNECTOR_ID!),
Expand Down
10 changes: 5 additions & 5 deletions docs/channels/slack.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ npm install @vercel/connect

```ts title="agent/channels/slack.ts"
import { connectSlackCredentials } from "@vercel/connect/eve";
import { slackChannel } from "eve/channels/slack";
import { slackChannel } from "@vercel/eve-slack";

export default slackChannel({
credentials: connectSlackCredentials("slack/my-agent"),
Expand Down Expand Up @@ -150,7 +150,7 @@ Use `onEvent` for subscribed events such as `reaction_added`, `team_join`, or `c

```ts title="agent/channels/slack.ts"
import { connectSlackCredentials } from "@vercel/connect/eve";
import { slackChannel } from "eve/channels/slack";
import { slackChannel } from "@vercel/eve-slack";

const onboardingChannels = ["C0123ABC", "C0456DEF"];

Expand Down Expand Up @@ -183,7 +183,7 @@ Because a generic event is not necessarily tied to one thread, its session helpe
You get the triggering mention by default, but not the earlier replies in the thread. Enable `threadContext` to fetch and inject them with every message attributed by stable Slack user id. Use `since: "last-agent-reply"` so repeated mentions inject only what is new:

```ts
import { slackChannel } from "eve/channels/slack";
import { slackChannel } from "@vercel/eve-slack";
import { connectSlackCredentials } from "@vercel/connect/eve";

export default slackChannel({
Expand All @@ -209,7 +209,7 @@ messages, for example, has no inbound Slack request. For that, call the
same primitive the handle uses directly:

```ts
import { callSlackApi, resolveSlackBotToken } from "eve/channels/slack";
import { callSlackApi, resolveSlackBotToken } from "@vercel/eve-slack";
import { connectSlackCredentials } from "@vercel/connect/eve";

const { botToken } = connectSlackCredentials("slack/my-agent");
Expand Down Expand Up @@ -238,7 +238,7 @@ When a session starts without a `threadTs` (say, from a schedule or `receive(sla
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`:

```ts
import { defaultSlackAuth, slackChannel } from "eve/channels/slack";
import { defaultSlackAuth, slackChannel } from "@vercel/eve-slack";
import { connectSlackCredentials } from "@vercel/connect/eve";

export default slackChannel({
Expand Down
2 changes: 1 addition & 1 deletion docs/patterns/dynamic-scheduling.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ Configure Slack normally:

```ts title="agent/channels/slack.ts"
import { connectSlackCredentials } from "@vercel/connect/eve";
import { slackChannel } from "eve/channels/slack";
import { slackChannel } from "@vercel/eve-slack";

export default slackChannel({
credentials: connectSlackCredentials("slack/my-agent"),
Expand Down
12 changes: 12 additions & 0 deletions packages/eve-photon/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# @vercel/eve-photon

First-class Photon iMessage channel for [eve](https://eve.dev).

```ts
import { connectPhotonCredentials } from "@vercel/connect/eve";
import { photonChannel } from "@vercel/eve-photon";

export default photonChannel({
credentials: connectPhotonCredentials(process.env.PHOTON_CONNECTOR_ID!),
});
```
46 changes: 46 additions & 0 deletions packages/eve-photon/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"name": "@vercel/eve-photon",
"version": "0.27.10",
"description": "First-class Photon iMessage channel for eve",
"license": "Apache-2.0",
"files": [
"dist",
"README.md",
"NOTICE"
],
"type": "module",
"sideEffects": false,
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"default": "./dist/index.js"
},
"./package.json": "./package.json"
},
"publishConfig": {
"access": "public"
},
"scripts": {
"clean": "rm -rf dist",
"build": "pnpm run clean && tsc -p tsconfig.build.json",
"prepack": "pnpm run build && node ../../scripts/copy-package-license.mjs .",
"test": "pnpm run test:unit",
"test:unit": "vitest run --config vitest.config.ts",
"typecheck": "tsc -p tsconfig.json --noEmit"
},
"dependencies": {
"@chat-adapter/state-memory": "4.34.0",
"@photon-ai/chat-adapter-imessage": "3.2.0",
"chat": "4.34.0",
"eve": "workspace:*"
},
"devDependencies": {
"vitest": "catalog:"
},
"engines": {
"node": ">=24"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ export {
type PhotonInboundMessageContext,
type PhotonInboundResult,
type PhotonInboundResultOrPromise,
} from "#public/channels/photon/photonChannel.js";
} from "./photonChannel.js";
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { describe, expect, it, vi } from "vitest";

import { isCompiledChannel } from "#channel/compiled-channel.js";
import { photonChannel } from "#public/channels/photon/photonChannel.js";
import { isCompiledChannel } from "eve/internal/channel/compiled-channel";
import { photonChannel } from "./photonChannel.js";

function routes(channel: unknown): Array<{ method: string; path: string }> {
if (!isCompiledChannel(channel)) throw new Error("Expected compiled channel.");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import type { SessionAuthContext } from "#channel/types.js";
import { vercelOidc } from "#public/channels/auth.js";
import type { SessionAuthContext } from "eve/internal/channel/types";
import { vercelOidc } from "eve/channels/auth";
import {
chatSdkChannel,
messageToUserContent,
type ChatSdkChannel,
type ChatSdkChannelBridge,
type ChatSdkChannelEvents,
} from "#public/channels/chat-sdk/index.js";
import type { Message, Thread } from "#compiled/chat/index.js";
import { createMemoryState } from "#compiled/@chat-adapter/state-memory/index.js";
} from "eve/channels/chat-sdk";
import type { Message, Thread } from "chat";
import { createMemoryState } from "@chat-adapter/state-memory";
import {
createiMessageAdapter,
type iMessageAdapter,
type iMessageCredentialProvider,
type iMessageWebhookVerifier,
} from "#compiled/@photon-ai/chat-adapter-imessage/index.js";
} from "@photon-ai/chat-adapter-imessage";

/** Photon project credentials used by {@link photonChannel}. */
export type PhotonChannelCredentials = iMessageCredentialProvider;
Expand Down Expand Up @@ -64,7 +64,7 @@ export interface PhotonChannel extends ChatSdkChannel {}
* @example
* ```ts
* import { connectPhotonCredentials } from "@vercel/connect/eve";
* import { photonChannel } from "eve/channels/photon";
* import { photonChannel } from "@vercel/eve-photon";
*
* export default photonChannel({
* credentials: connectPhotonCredentials(process.env.PHOTON_CONNECTOR_ID!),
Expand Down
11 changes: 11 additions & 0 deletions packages/eve-photon/tsconfig.build.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "./tsconfig.json",
"compilerOptions": {
"declaration": true,
"declarationMap": true,
"noEmit": false,
"outDir": "dist",
"sourceMap": true
}
}
10 changes: 10 additions & 0 deletions packages/eve-photon/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "../../tsconfig.json",
"compilerOptions": {
"noEmit": true,
"rootDir": "src"
},
"include": ["src/**/*.ts"],
"exclude": ["src/**/*.test.ts"]
}
3 changes: 3 additions & 0 deletions packages/eve-photon/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { defineConfig } from "vitest/config";

export default defineConfig({ test: { include: ["src/**/*.test.ts"] } });
12 changes: 12 additions & 0 deletions packages/eve-slack/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# @vercel/eve-slack

First-class Slack channel for [eve](https://eve.dev).

```ts
import { connectSlackCredentials } from "@vercel/connect/eve";
import { slackChannel } from "@vercel/eve-slack";

export default slackChannel({
credentials: connectSlackCredentials(process.env.SLACK_CONNECTOR_ID!),
});
```
46 changes: 46 additions & 0 deletions packages/eve-slack/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"name": "@vercel/eve-slack",
"version": "0.27.10",
"description": "First-class Slack channel for eve",
"license": "Apache-2.0",
"files": [
"dist",
"README.md",
"NOTICE"
],
"type": "module",
"sideEffects": false,
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"default": "./dist/index.js"
},
"./package.json": "./package.json"
},
"publishConfig": {
"access": "public"
},
"scripts": {
"clean": "rm -rf dist",
"build": "pnpm run clean && tsc -p tsconfig.build.json",
"prepack": "pnpm run build && node ../../scripts/copy-package-license.mjs .",
"test": "pnpm run test:unit",
"test:unit": "vitest run --config vitest.config.ts",
"typecheck": "tsc -p tsconfig.json --noEmit"
},
"dependencies": {
"@chat-adapter/slack": "4.34.0",
"chat": "4.34.0",
"eve": "workspace:*"
},
"devDependencies": {
"ai": "catalog:",
"vitest": "catalog:"
},
"engines": {
"node": ">=24"
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import { describe, expect, it } from "vitest";

import {
describeActionRequest,
describeActionRequests,
} from "#public/channels/slack/action-status.js";
import type { RuntimeActionRequest } from "#runtime/actions/types.js";
import type { JsonObject } from "#shared/json.js";
import { describeActionRequest, describeActionRequests } from "./action-status.js";
import type { RuntimeActionRequest } from "eve/internal/runtime/actions/types";
import type { JsonObject } from "eve/internal/shared/json";

function toolCall(toolName: string, input: JsonObject = {}): RuntimeActionRequest {
return { callId: "c1", input, kind: "tool-call", toolName };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* label is the action's name plus its most telling argument — `grep useEve`
* or `read_file agent/agent.ts` instead of `Running grep...`.
*/
import type { RuntimeActionRequest } from "#runtime/actions/types.js";
import type { RuntimeActionRequest } from "eve/internal/runtime/actions/types";

/** Argument keys worth surfacing, most telling first, per tool. */
const SALIENT_KEYS: Readonly<Record<string, readonly string[]>> = {
Expand Down
Loading
Loading