Two fixes from the pre-merge adversarial CR of this PR (both pre-existing,
flagged as in-subject):
- ChannelManager.status() reported overall "online" for a manager stopped
BEFORE activate() (e.g. SIGTERM during startup): `entries` is empty, so the
empty-set fold returned "online" — a torn-down manager reading healthy. Now
short-circuits to "stopped" when `this.stopped`, matching the documented
status() contract. New red-green test covers the stop()-before-activate() case.
- examples/slack/.env.example: COPILOTKIT_INTELLIGENCE_WS_URL example was
ws://localhost:4401, but derivation is a scheme-only swap of the :4201 API URL
(→ ws://localhost:4201) and 4401 is used nowhere — a user uncommenting it hit a
dead port. Corrected to :4201 and clarified the derivation note.
Pre-existing .env.example issues noted in the OSS-473 CR:
- AGENT_MODEL example was `anthropic/claude-sonnet-4.5`, but runtime.ts is
OpenAI-only (web search is an OpenAI hosted tool; it strips a leading
`openai/` and passes the rest to `openaiText`). Use an OpenAI example and say
so.
- Removed ANTHROPIC_API_KEY / GOOGLE_API_KEY — never read by this runtime.
- LINEAR_API_KEY, NOTION_TOKEN and NOTION_MCP_AUTH_TOKEN were non-blank
placeholders, but runtime.ts turns the Linear/Notion MCPs ON purely on the
presence of LINEAR_API_KEY / NOTION_MCP_AUTH_TOKEN — a placeholder wires a
broken MCP. Blanked them (they're optional integrations, like the commented
Discord/Telegram/WhatsApp creds).
- Documented NOTION_MCP_PORT (the `pnpm notion-mcp` sidecar port, default 3001;
must match NOTION_MCP_URL).
- Added WhatsApp to the header list of supported adapters.
The StateStore interface and the in-memory MemoryStore default remain;
durable backends can be reintroduced as a follow-up. Both adapter packages
were merged in #5613 but never published to npm, so removal is a clean
delete with no consumer impact.
- Delete packages/bot-store-redis and packages/bot-store-postgres.
- Revert the bot release scope and drift guard to bot + bot-ui.
- Strip the Redis dep, demo:restart script, restart demo, docker-compose,
and REDIS_URL env from examples/slack.
- Rewrite the bot persistence/transcripts docs around "MemoryStore default
+ implement the StateStore interface yourself for durability".
Adds a durable persistence layer for @copilotkit/bot, replacing the
in-memory-only ActionStore with a pluggable StateStore.
- StateStore interface (kv/list/lock/dedup/queue) with a shared
conformance suite; MemoryStore default plus @copilotkit/bot-store-redis
and @copilotkit/bot-store-postgres backends.
- createBot({ store }): typed per-thread state via Standard Schema,
action snapshots persisted through the store, per-conversation turn
lock (onLockConflict drop|force), and inbound-event dedup keyed on a
stable eventId. ActionStore is kept as a deprecated alias.
- Cross-platform transcripts (bot.transcripts + identity resolver) with
age-bounded retention (prune on append + filter on read), and
runAgent({ transcript: true }) to auto-inject history and capture the
reply.
- createBot({ components }) re-registers components so durable actions
re-fire after a restart; restart-durability demo in examples/slack.
- Dedup is marked seen only after the turn lock is acquired, so a turn
dropped on lock-conflict does not burn its eventId (no lost retries).
- Release lockstep: bot-store-redis/postgres version with bot + bot-ui.
Unify WhatsApp with main's Slack+Discord multi-adapter demo: WhatsApp becomes a
third env-gated platform block in examples/slack/app/index.ts (listening on
Railway $PORT, with a malformed-PORT guard). Keep the platform-aware
senderContext (also fixes the Discord 'Slack user' label); drop the superseded
buildAdapters helper for main's inline per-platform pattern. package.json takes
main's ~0.0.2 bumps + bot-discord and adds bot-whatsapp (workspace:~); README
intro + deploy section cover all three surfaces.
examples/slack now starts a Slack bot and/or a Telegram bot from one platform-neutral app layer, env-conditional on which credentials are set. Neutralized Slack-specific rendering so the shared components work on both platforms: unicode glyphs instead of mrkdwn shortcodes, no Block Kit raw fallbacks, neutral context/tool wording. Migrated the Telegram e2e smoke harness and BotFather setup docs; removed the separate examples/telegram app.
100% JSX bot at feature parity with the PoC example: issue/page cards,
tables, Chart.js charts, Mermaid diagrams, incident/status/links cards,
a confirm_write HITL gate, and /agent + /triage slash commands.
Registers examples/slack in the pnpm workspace.