slack-agent

Use when building Slack agents/bots with eve (Vercel's filesystem-first agent framework), @vercel/connect, or eve/channels/slack. Covers defineAgent/defineTool patterns, Vercel Connect credential brokering, Slack channel setup, testing requirements, and quality standards.

By vercel-labs · 776 installs

npx skills add vercel-labs/slack-agent-skill --skill slack-agent

Source repository · Upstream listing

Slack Agent Development Skill This skill builds Slack agents with eve — Vercel's filesystem first framework for durable backend agents — using Vercel Connect for Slack credentials: eve ( eve package) — agent runtime, tools, channels, durability @vercel/connect — brokered short lived Slack tokens; no bot tokens or signing secrets to manage Skill Invocation Handling When this skill is invoked via /slack agent , check for arguments and route accordingly: Command Arguments Argument Action new Run the setup wizard from Phase 1. Read ./wizard/1 project setup.md and guide the user through creating a new Slack agent. configure Start wizard at Phase 2 or 3 for existing projects deploy Start wizard at Phase 5 for production deployment test Start wizard at Phase 6 to set up testing (no argument) Auto detect based on project state (see below) Auto Detection (No Argument) If invoked without arguments, detect the project state and route appropriately: 1. No package.json with eve and no agent/ directory → Treat as new , start Phase 1 2. Has eve project but no agent/channels/slack.ts → Start Phase 2 (Slack connector + channel) 3. Has Slack channel but no SLACK CONNECTOR configured → Start Phase 3 4. Configured but not deployed → Start Phase 5 (the Slack surface only works on a deployment) 5. Deployed but no tests → Start Phase 6 6. Otherwise → Provide general assistance using this skill's patterns Project Detection Detect an eve project by either signal: package.json contains "eve" as a dependency An agent/ directory with instructions.md and/or agent.ts exists If neither is present, this is a new project: scaffold with npx eve@latest init (Node 24+ required). Wizard Phases The wizard is located in ./wizard/ with these phases: 1 project setup.md Understand purpose, generate custom implementation plan, scaffold with npx eve@latest init 1b approve plan.md Present plan for user approval before scaffolding 2 create slack app.md Create the Slack connector with Vercel Connect and add the Slack channel 3 configure environment.md Set up env vars ( SLACK CONNECTOR , model credentials) 4 test locally.md Test agent logic locally with the eve dev TUI (Slack surface tests happen after deploy) 5 deploy production.md Deploy with eve deploy , verify the Slack surface 6 setup testing.md Vitest configuration IMPORTANT: For new projects, you MUST: 1. Read ./wizard/1 project setup.md first 2. Ask the user what kind of agent they want to build 3. Generate a custom implementation plan using ./reference/agent archetypes.md 4. Present the plan for approval (Phase 1b) BEFORE scaffolding the project 5. Only proceed to scaffold after the plan is approved General Development Guidance You are working on a Slack agent project built with eve. Follow these mandatory practices for all code changes. Project Stack Framework : eve (filesystem first agent framework; Node 24+) Slack channel : eve/channels/slack + @vercel/connect for credentials AI : model routed through Vercel AI Gateway by default ( anthropic/claude sonnet 5 ); tool schemas with zod Durability : Workflow SDK under the hood (Vercel Workflows when deployed on Vercel) Linting : Biome Package Manager : pnpm (or npm — npx eve@latest init installs with npm) Filesystem First Layout In eve, a file's location says what it does, and its path usually gives it its name. The whole agent lives under agent/ : Even a two file agent ( instructions.md + agent.ts ) gets file, shell, web, and delegation tools out of the box from the default harness. Full docs are bundled at node modules/eve/docs/ once eve is installed — read them when a detail isn't covered here. Quality Standards (MANDATORY) These quality requirements MUST be followed for every code change. There are no exceptions. After EVERY File Modification 1. Run linting immediately: If errors exist, run pnpm lint write for auto fixes Manually fix remaining issues Re run pnpm lint to verify 2. Check for corresponding test file: If you modified foo.ts , check if foo.test.ts exists If no test file exists and the file exports functions, create one Before Completing ANY Task You MUST run all quality checks and fix any issues before marking a task complete: Do NOT complete a task if any of these fail. Fix the issues first. Unit Tests Required For ANY code change, you MUST write or update unit tests. Location : Co located .test.ts files (e.g. agent/tools/get weather.test.ts ) Framework : Vitest Coverage : All exported functions and every tool's execute() (including error paths) must have tests Example test structure: E2E Tests for User Facing Changes If you modify: Dispatch hooks ( onAppMention , onDirectMessage , onInteraction ) Custom channel event handlers Tools the agent calls in response to Slack messages Delivery behavior (what gets posted to Slack) You MUST add or update tests that verify the full flow. Remember: the Slack surface itself cannot be exercised locally (see Gotchas), so E2E coverage means unit/integration tests around your handlers plus a post deploy smoke test. Bot Setup Patterns (CRITICAL) Slack Channel ( agent/channels/slack.ts ) The Slack channel is a single file. Its filename registers the slack channel, served at /eve/v1/slack — this is the canonical trigger path everywhere in this skill. connectSlackCredentials(connectorUid) returns { botToken, webhookVerifier } : botToken — resolved at runtime via Vercel Connect as a short lived, app scoped token; Connect handles rotation and multi workspace tenancy webhookVerifier — confirms each forwarded event genuinely came from Connect (replaces Slack's native signature check) There is no SLACK BOT TOKEN and no SLACK SIGNING SECRET in this stack. The only Slack env var is SLACK CONNECTOR (the connector UID, e.g. slack/my agent ). Vercel Connect Setup Create a Slack connector and point its trigger at eve's Slack route: triggers is required. Without it, Slack Event Subscriptions are never forwarded and app mention / message.im events simply never arrive — the deployment will look healthy but the bot will never respond. You can also add the channel with eve channels add slack , which scaffolds agent/channels/slack.ts for you. Deploy Then invite the bot to a channel and @mention it. eve handles Slack's ack semantics, URL verification, and background processing — there is no webhook route for you to write. Event Handling Patterns Dispatch Hooks (Inbound) The Slack channel decides which inbound events start or continue a session via dispatch hooks. Each hook returns { auth } to dispatch, null to drop the event, or { auth, context } to inject background context into the session: The triggering Slack user's id is attached to the model message automatically, preserving speaker attribution in multi user threads. Custom Event Handlers (Outbound Delivery) Override delivery per stream event with the events map. Handlers receive (eventData, channel, ctx) with channel.thread and channel.slack handles: Key stream events: session.started , actions.requested , action.result , message.completed , session.completed ; incremental reasoning.appended / message.appended are optional. Thread Context Give the agent prior thread messages when it's triggered mid thread: since options: "thread root" — all prior messages (default when thread context is enabled) "last agent reply" — incremental, only messages since the agent last spoke A predicate (message: SlackThreadMessage) = boolean as a custom cutoff — includes messages after the last match ( loadThreadContextMessages exists for arbitrary filtering) Cost: one conversations.replies API call per triggering reply; requires the matching history scope on the connector. Human in the Loop (HITL) Approval gated tool calls and sign in challenges render natively in Slack: Approval prompts appear as buttons/selects ; the user's response resumes the durably parked session Sign in challenges (OAuth URLs, device codes) go ephemerally to the triggering user; a public status message posts in thread and updates on authorization.completed The HITL handler context deliberately offers only postEphemeral , postDirectMessage (needs im:write ), and state — no public post , no raw API access Proactive Sessions (Schedules) Start a session that posts into Slack without an inbound trigger — e.g. from a schedule: Sessions without a threadTs get a temporary continuation token; the first post anchors the thread initialMessage (optionally a Card ) and threadTs are mutually exclusive Use eve schedules (see https://eve.dev/docs/schedules) to trigger proactive sessions on a cadence Raw Slack API Access Inside handlers : ctx.slack.request(operation, body) Outside handlers (schedules, tools): callSlackApi({ botToken, operation, body }) and resolveSlackBotToken from eve/channels/slack These form encode request bodies for you — Slack's JSON support is only partial, so prefer these helpers over hand rolled fetch calls. Implementation Gotchas 1. The Slack Surface Cannot Be Tested Locally Vercel Connect forwards Slack events to deployments only, never to localhost . There is no ngrok/Socket Mode escape hatch in this stack. Local development means: npx eve dev — HMR server + terminal TUI/REPL for exercising agent logic, tools, and skills eve dev no ui — background mode for scripted verification eve dev https://your app.vercel.app — drive a deployed app interactively To test @mentions and DMs, deploy (preview or production) and test in Slack itself. 2. Connect Forwarding Has No Delivery De duplication Connect may deliver the same forwarded event more than once. Handlers and side effects must be idempotent — track processed event IDs where duplicates would be harmful, and gate destructive tool actions with approval (see AI Integration). 3. triggers Is Required or Events Never Arrive A Slack connector created without triggers (or attached without a trigger path) will authenticate fine but forward nothing. If the bot never responds to @mentions: 1. Verify the connector was created/attached with triggers 2. Verify the trigger path is /eve/v1/slack 3. Verify the bot was invited to the channel and the deployment finished 4. placeholderAuth() Fails Closed in Production Scaffolded projects ship with placeholderAuth() for the HTTP API, which rejects everything in production . Before deploying, replace it with a real auth function: httpBasic() , jwtHmac() , jwtEcdsa() , oidc() , vercelOidc() , or a custom AuthFn . (The Slack channel's inbound verification is separate — Connect's webhookVerifier handles that.) 5. Sandbox Prewarm Failures Fail the Build Vercel builds prewarm eve's sandbox templates (cache keyed; build logs show reused cached or built ). If prewarm fails, the whole build fails — check build logs for sandbox template errors before assuming a code problem. 6. Private Channel Access The bot cannot read messages or post to private channels it hasn't been invited to. When creating features that will later post to a channel (e.g. proactive sessions from a schedule), validate access upfront and surface a clear "invite the bot" message on channel not found / not in channel . 7. Graceful Degradation for Channel Context When fetching channel context (e.g. via ctx.slack.request("conversations.history", ...) ) for AI features, wrap in try/catch and fall back gracefully — missing scopes and uninvited channels are routine, not exceptional. 8. Vercel Cron Endpo