This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated. # Releases ## @chat-adapter/discord@4.29.0 ### Minor Changes -2ffed48: Adapter internals are now `protected` rather than `private`, so consumers can subclass an adapter to override or extend its behavior (e.g. handling additional Telegram update types by overriding `processUpdate`). ### Patch Changes -e60bc8c: chore: set supported Node versions in engines -b9b17cd: handle slash commands and button interactions in Discord gateway-only mode - Updated dependencies [ac8a207] - Updated dependencies [e60bc8c] - Updated dependencies [add2730] - Updated dependencies [b75eedb] - chat@4.29.0 - @chat-adapter/shared@4.29.0 ## @chat-adapter/gchat@4.29.0 ### Minor Changes -2ffed48: Adapter internals are now `protected` rather than `private`, so consumers can subclass an adapter to override or extend its behavior (e.g. handling additional Telegram update types by overriding `processUpdate`). ### Patch Changes -e60bc8c: chore: set supported Node versions in engines -06fb8e5: Align package shapes with the new `konsistent` conventions. All changes are backwards-compatible — previous type names are kept as deprecated aliases. - `@chat-adapter/gchat`, `@chat-adapter/slack`: moved `*AdapterConfig` (and related sub-types) into a `./types` module; the public re-exports from `index.ts` are unchanged. - `@chat-adapter/slack`: `createSlackAdapter` now accepts `SlackAdapterConfig` directly instead of `Partial<SlackAdapterConfig>`. Every field on the config was already optional, so no call sites need to change. - `@chat-adapter/messenger`: `MessengerAdapterConfig` fields are now optional (the factory still falls back to `FACEBOOK_*` env vars), and `logger` / `userName` live on `MessengerAdapterConfig` directly. The factory signature is now `createMessengerAdapter(config?: MessengerAdapterConfig)`. - `@chat-adapter/web`: renamed `WebAdapterOptions` to `WebAdapterConfig`; the old name is exported as a deprecated alias. - `@chat-adapter/whatsapp`: every field on `WhatsAppAdapterConfig` is optional (the factory still falls back to `WHATSAPP_*` env vars). `createWhatsAppAdapter` is now typed `(config?: WhatsAppAdapterConfig) => WhatsAppAdapter`. - `@chat-adapter/state-memory`: added an empty `MemoryStateAdapterOptions` type so the package matches every other state adapter; `createMemoryState` now accepts an optional argument of that type. - `@chat-adapter/state-ioredis`, `@chat-adapter/state-redis`, `@chat-adapter/state-pg`: the URL- and client-based option shapes were split into named interfaces (`*StateAdapterUrlOptions` / `*StateAdapterClientOptions`) and unified under `*StateAdapterOptions`. The factories now take the union type directly. Old names — `RedisStateClientOptions`, `CreateRedisStateOptions`, `PostgresStateClientOptions`, `CreatePostgresStateOptions`, `IoRedisStateClientOptions` — are kept as deprecated aliases. - Updated dependencies [ac8a207] - Updated dependencies [e60bc8c] - Updated dependencies [add2730] - Updated dependencies [b75eedb] - chat@4.29.0 - @chat-adapter/shared@4.29.0 ## @chat-adapter/github@4.29.0 ### Minor Changes -2f108bd: Rename the typed native client getter on the Slack, GitHub, and Linear adapters to match the underlying SDK class. - `bot.getAdapter("slack").client` is now `bot.getAdapter("slack").webClient` (returns `WebClient` from `@slack/web-api`). - `bot.getAdapter("github").client` is now `bot.getAdapter("github").octokit` (returns `Octokit`). - `bot.getAdapter("linear").client` is now `bot.getAdapter("linear").linearClient` (returns `LinearClient`). The previous `.client` getter is kept as a deprecated alias on all three adapters, so existing code continues to work without changes. -2ffed48: Adapter internals are now `protected` rather than `private`, so consumers can subclass an adapter to override or extend its behavior (e.g. handling additional Telegram update types by overriding `processUpdate`). ### Patch Changes -e60bc8c: chore: set supported Node versions in engines - Updated dependencies [ac8a207] - Updated dependencies [e60bc8c] - Updated dependencies [add2730] - Updated dependencies [b75eedb] - chat@4.29.0 - @chat-adapter/shared@4.29.0 ## @chat-adapter/linear@4.29.0 ### Minor Changes -2f108bd: Rename the typed native client getter on the Slack, GitHub, and Linear adapters to match the underlying SDK class. - `bot.getAdapter("slack").client` is now `bot.getAdapter("slack").webClient` (returns `WebClient` from `@slack/web-api`). - `bot.getAdapter("github").client` is now `bot.getAdapter("github").octokit` (returns `Octokit`). - `bot.getAdapter("linear").client` is now `bot.getAdapter("linear").linearClient` (returns `LinearClient`). The previous `.client` getter is kept as a deprecated alias on all three adapters, so existing code continues to work without changes. -2ffed48: Adapter internals are now `protected` rather than `private`, so consumers can subclass an adapter to override or extend its behavior (e.g. handling additional Telegram update types by overriding `processUpdate`). ### Patch Changes -e60bc8c: chore: set supported Node versions in engines - Updated dependencies [ac8a207] - Updated dependencies [e60bc8c] - Updated dependencies [add2730] - Updated dependencies [b75eedb] - chat@4.29.0 - @chat-adapter/shared@4.29.0 ## @chat-adapter/messenger@4.29.0 ### Minor Changes -2ffed48: Adapter internals are now `protected` rather than `private`, so consumers can subclass an adapter to override or extend its behavior (e.g. handling additional Telegram update types by overriding `processUpdate`). ### Patch Changes -e60bc8c: chore: set supported Node versions in engines -06fb8e5: Align package shapes with the new `konsistent` conventions. All changes are backwards-compatible — previous type names are kept as deprecated aliases. - `@chat-adapter/gchat`, `@chat-adapter/slack`: moved `*AdapterConfig` (and related sub-types) into a `./types` module; the public re-exports from `index.ts` are unchanged. - `@chat-adapter/slack`: `createSlackAdapter` now accepts `SlackAdapterConfig` directly instead of `Partial<SlackAdapterConfig>`. Every field on the config was already optional, so no call sites need to change. - `@chat-adapter/messenger`: `MessengerAdapterConfig` fields are now optional (the factory still falls back to `FACEBOOK_*` env vars), and `logger` / `userName` live on `MessengerAdapterConfig` directly. The factory signature is now `createMessengerAdapter(config?: MessengerAdapterConfig)`. - `@chat-adapter/web`: renamed `WebAdapterOptions` to `WebAdapterConfig`; the old name is exported as a deprecated alias. - `@chat-adapter/whatsapp`: every field on `WhatsAppAdapterConfig` is optional (the factory still falls back to `WHATSAPP_*` env vars). `createWhatsAppAdapter` is now typed `(config?: WhatsAppAdapterConfig) => WhatsAppAdapter`. - `@chat-adapter/state-memory`: added an empty `MemoryStateAdapterOptions` type so the package matches every other state adapter; `createMemoryState` now accepts an optional argument of that type. - `@chat-adapter/state-ioredis`, `@chat-adapter/state-redis`, `@chat-adapter/state-pg`: the URL- and client-based option shapes were split into named interfaces (`*StateAdapterUrlOptions` / `*StateAdapterClientOptions`) and unified under `*StateAdapterOptions`. The factories now take the union type directly. Old names — `RedisStateClientOptions`, `CreateRedisStateOptions`, `PostgresStateClientOptions`, `CreatePostgresStateOptions`, `IoRedisStateClientOptions` — are kept as deprecated aliases. - Updated dependencies [ac8a207] - Updated dependencies [e60bc8c] - Updated dependencies [add2730] - Updated dependencies [b75eedb] - chat@4.29.0 - @chat-adapter/shared@4.29.0 ## @chat-adapter/shared@4.29.0 ### Minor Changes -add2730: support typed Telegram attachment uploads ### Patch Changes -e60bc8c: chore: set supported Node versions in engines - Updated dependencies [ac8a207] - Updated dependencies [e60bc8c] - Updated dependencies [b75eedb] - chat@4.29.0 ## @chat-adapter/slack@4.29.0 ### Minor Changes -2f108bd: Rename the typed native client getter on the Slack, GitHub, and Linear adapters to match the underlying SDK class. - `bot.getAdapter("slack").client` is now `bot.getAdapter("slack").webClient` (returns `WebClient` from `@slack/web-api`). - `bot.getAdapter("github").client` is now `bot.getAdapter("github").octokit` (returns `Octokit`). - `bot.getAdapter("linear").client` is now `bot.getAdapter("linear").linearClient` (returns `LinearClient`). The previous `.client` getter is kept as a deprecated alias on all three adapters, so existing code continues to work without changes. -c46fdb6: Add support for external `installationProvider` and Enterprise Grid org-wide installs. - New optional `installationProvider` config: `{ getInstallation(installationId, isEnterpriseInstall) => Promise<SlackInstallation | null> }`. When set, the adapter resolves bot tokens for incoming events, slash commands, and interactive payloads through the provider instead of the internal `StateAdapter` — useful for hosted token-management systems (e.g. Vercel Connect). The provider is read-only; OAuth callback writes (`setInstallation`, `handleOAuthCallback`) and the `getInstallation`/`deleteInstallation` public methods continue to use internal state, so callers using a provider should manage their own writes. - Enterprise Grid org-wide installs (`is_enterprise_install: true`) are now keyed on `enterprise_id` instead of `team_id` across event_callback, slash command, and interactive payload paths. Multi-workspace deployments using the internal `StateAdapter` for org-wide installs must repopulate installations under the `enterprise_id` key — previously, org-wide events would fall through to a `team_id` lookup that did not match what the OAuth flow had stored. -fdebde7: feat(slack): expose direct `WebClient` access via `adapter.client` `bot.getAdapter("slack").client` now returns a typed `WebClient` from `@slack/web-api`, matching the existing pattern on the Linear and GitHub adapters. The returned client is bound to the bot token for the current request context (multi-workspace) or the configured default token (single-workspace). Use it for any Web API call not covered by the SDK's high-level methods, e.g. `adapter.client.pins.add(...)` or `adapter.client.usergroups.list(...)`. Resolution order: 1. The token from the current `requestContext` — set during webhook handling, or by `adapter.withBotToken(token, fn)`. 2. The default `botToken`, when configured as a static string or a synchronous resolver function. Throws `AuthenticationError` outside of any context in multi-workspace mode, or when `botToken` is configured as an async resolver function. For async tokens, await the token first and bind it explicitly with `adapter.withBotToken(token, () => adapter.client...)`. Also fixes `createSlackAdapter()` silently dropping the `apiUrl` config field. -2ffed48: Adapter internals are now `protected` rather than `private`, so consumers can subclass an adapter to override or extend its behavior (e.g. handling additional Telegram update types by overriding `processUpdate`). ### Patch Changes -e60bc8c: chore: set supported Node versions in engines -06fb8e5: Align package shapes with the new `konsistent` conventions. All changes are backwards-compatible — previous type names are kept as deprecated aliases. - `@chat-adapter/gchat`, `@chat-adapter/slack`: moved `*AdapterConfig` (and related sub-types) into a `./types` module; the public re-exports from `index.ts` are unchanged. - `@chat-adapter/slack`: `createSlackAdapter` now accepts `SlackAdapterConfig` directly instead of `Partial<SlackAdapterConfig>`. Every field on the config was already optional, so no call sites need to change. - `@chat-adapter/messenger`: `MessengerAdapterConfig` fields are now optional (the factory still falls back to `FACEBOOK_*` env vars), and `logger` / `userName` live on `MessengerAdapterConfig` directly. The factory signature is now `createMessengerAdapter(config?: MessengerAdapterConfig)`. - `@chat-adapter/web`: renamed `WebAdapterOptions` to `WebAdapterConfig`; the old name is exported as a deprecated alias. - `@chat-adapter/whatsapp`: every field on `WhatsAppAdapterConfig` is optional (the factory still falls back to `WHATSAPP_*` env vars). `createWhatsAppAdapter` is now typed `(config?: WhatsAppAdapterConfig) => WhatsAppAdapter`. - `@chat-adapter/state-memory`: added an empty `MemoryStateAdapterOptions` type so the package matches every other state adapter; `createMemoryState` now accepts an optional argument of that type. - `@chat-adapter/state-ioredis`, `@chat-adapter/state-redis`, `@chat-adapter/state-pg`: the URL- and client-based option shapes were split into named interfaces (`*StateAdapterUrlOptions` / `*StateAdapterClientOptions`) and unified under `*StateAdapterOptions`. The factories now take the union type directly. Old names — `RedisStateClientOptions`, `CreateRedisStateOptions`, `PostgresStateClientOptions`, `CreatePostgresStateOptions`, `IoRedisStateClientOptions` — are kept as deprecated aliases. -0f0c203: fix(slack): prefer `webhookVerifier` over `signingSecret` and `SLACK_SIGNING_SECRET` When a `webhookVerifier` is configured, it now takes precedence over both the `signingSecret` config field and the `SLACK_SIGNING_SECRET` env var. Previously, a configured `signingSecret` (or env var) would shadow the verifier. - Updated dependencies [ac8a207] - Updated dependencies [e60bc8c] - Updated dependencies [add2730] - Updated dependencies [b75eedb] - chat@4.29.0 - @chat-adapter/shared@4.29.0 ## @chat-adapter/teams@4.29.0 ### Minor Changes -2ffed48: Adapter internals are now `protected` rather than `private`, so consumers can subclass an adapter to override or extend its behavior (e.g. handling additional Telegram update types by overriding `processUpdate`). ### Patch Changes -e60bc8c: chore: set supported Node versions in engines - Updated dependencies [ac8a207] - Updated dependencies [e60bc8c] - Updated dependencies [add2730] - Updated dependencies [b75eedb] - chat@4.29.0 - @chat-adapter/shared@4.29.0 ## @chat-adapter/telegram@4.29.0 ### Minor Changes -add2730: support typed Telegram attachment uploads -2ffed48: Adapter internals are now `protected` rather than `private`, so consumers can subclass an adapter to override or extend its behavior (e.g. handling additional Telegram update types by overriding `processUpdate`). ### Patch Changes -e60bc8c: chore: set supported Node versions in engines -711babe: Handle `video_note` (round video messages) in `extractAttachments`. Previously these messages were silently dropped; now they are returned as `video` attachments with `width`/`height` set to the clip's `length`. - Updated dependencies [ac8a207] - Updated dependencies [e60bc8c] - Updated dependencies [add2730] - Updated dependencies [b75eedb] - chat@4.29.0 - @chat-adapter/shared@4.29.0 ## @chat-adapter/web@4.29.0 ### Minor Changes -2ffed48: Adapter internals are now `protected` rather than `private`, so consumers can subclass an adapter to override or extend its behavior (e.g. handling additional Telegram update types by overriding `processUpdate`). -716e934: Add first-class Vue and Svelte support via new subpath exports `@chat-adapter/web/vue` and `@chat-adapter/web/svelte`. Each exports a `useChat()` factory preconfigured with `DefaultChatTransport`, returning a framework-reactive `Chat` instance from `@ai-sdk/vue` / `@ai-sdk/svelte` respectively. Note: unlike the React subpath which wraps `@ai-sdk/react`'s `useChat` hook and returns destructurable helpers, the Vue and Svelte wrappers return a `Chat` class instance — access `chat.messages`, `chat.sendMessage()`, `chat.status`, and `chat.stop()` directly on the object. ### Patch Changes -e60bc8c: chore: set supported Node versions in engines -06fb8e5: Align package shapes with the new `konsistent` conventions. All changes are backwards-compatible — previous type names are kept as deprecated aliases. - `@chat-adapter/gchat`, `@chat-adapter/slack`: moved `*AdapterConfig` (and related sub-types) into a `./types` module; the public re-exports from `index.ts` are unchanged. - `@chat-adapter/slack`: `createSlackAdapter` now accepts `SlackAdapterConfig` directly instead of `Partial<SlackAdapterConfig>`. Every field on the config was already optional, so no call sites need to change. - `@chat-adapter/messenger`: `MessengerAdapterConfig` fields are now optional (the factory still falls back to `FACEBOOK_*` env vars), and `logger` / `userName` live on `MessengerAdapterConfig` directly. The factory signature is now `createMessengerAdapter(config?: MessengerAdapterConfig)`. - `@chat-adapter/web`: renamed `WebAdapterOptions` to `WebAdapterConfig`; the old name is exported as a deprecated alias. - `@chat-adapter/whatsapp`: every field on `WhatsAppAdapterConfig` is optional (the factory still falls back to `WHATSAPP_*` env vars). `createWhatsAppAdapter` is now typed `(config?: WhatsAppAdapterConfig) => WhatsAppAdapter`. - `@chat-adapter/state-memory`: added an empty `MemoryStateAdapterOptions` type so the package matches every other state adapter; `createMemoryState` now accepts an optional argument of that type. - `@chat-adapter/state-ioredis`, `@chat-adapter/state-redis`, `@chat-adapter/state-pg`: the URL- and client-based option shapes were split into named interfaces (`*StateAdapterUrlOptions` / `*StateAdapterClientOptions`) and unified under `*StateAdapterOptions`. The factories now take the union type directly. Old names — `RedisStateClientOptions`, `CreateRedisStateOptions`, `PostgresStateClientOptions`, `CreatePostgresStateOptions`, `IoRedisStateClientOptions` — are kept as deprecated aliases. - Updated dependencies [ac8a207] - Updated dependencies [e60bc8c] - Updated dependencies [add2730] - Updated dependencies [b75eedb] - chat@4.29.0 - @chat-adapter/shared@4.29.0 ## @chat-adapter/whatsapp@4.29.0 ### Minor Changes -2ffed48: Adapter internals are now `protected` rather than `private`, so consumers can subclass an adapter to override or extend its behavior (e.g. handling additional Telegram update types by overriding `processUpdate`). ### Patch Changes -e60bc8c: chore: set supported Node versions in engines -06fb8e5: Align package shapes with the new `konsistent` conventions. All changes are backwards-compatible — previous type names are kept as deprecated aliases. - `@chat-adapter/gchat`, `@chat-adapter/slack`: moved `*AdapterConfig` (and related sub-types) into a `./types` module; the public re-exports from `index.ts` are unchanged. - `@chat-adapter/slack`: `createSlackAdapter` now accepts `SlackAdapterConfig` directly instead of `Partial<SlackAdapterConfig>`. Every field on the config was already optional, so no call sites need to change. - `@chat-adapter/messenger`: `MessengerAdapterConfig` fields are now optional (the factory still falls back to `FACEBOOK_*` env vars), and `logger` / `userName` live on `MessengerAdapterConfig` directly. The factory signature is now `createMessengerAdapter(config?: MessengerAdapterConfig)`. - `@chat-adapter/web`: renamed `WebAdapterOptions` to `WebAdapterConfig`; the old name is exported as a deprecated alias. - `@chat-adapter/whatsapp`: every field on `WhatsAppAdapterConfig` is optional (the factory still falls back to `WHATSAPP_*` env vars). `createWhatsAppAdapter` is now typed `(config?: WhatsAppAdapterConfig) => WhatsAppAdapter`. - `@chat-adapter/state-memory`: added an empty `MemoryStateAdapterOptions` type so the package matches every other state adapter; `createMemoryState` now accepts an optional argument of that type. - `@chat-adapter/state-ioredis`, `@chat-adapter/state-redis`, `@chat-adapter/state-pg`: the URL- and client-based option shapes were split into named interfaces (`*StateAdapterUrlOptions` / `*StateAdapterClientOptions`) and unified under `*StateAdapterOptions`. The factories now take the union type directly. Old names — `RedisStateClientOptions`, `CreateRedisStateOptions`, `PostgresStateClientOptions`, `CreatePostgresStateOptions`, `IoRedisStateClientOptions` — are kept as deprecated aliases. - Updated dependencies [ac8a207] - Updated dependencies [e60bc8c] - Updated dependencies [add2730] - Updated dependencies [b75eedb] - chat@4.29.0 - @chat-adapter/shared@4.29.0 ## chat@4.29.0 ### Minor Changes -ac8a207: Add `chat/ai` subpath as the home for AI utilities, including `createChatTools` for the Vercel AI SDK and `toAiMessages` for converting chat history into AI SDK prompts. `createChatTools` exposes Chat SDK operations as ready-to-use AI SDK tools so an agent can read messages, post replies, send DMs, react, edit, delete, and manage thread subscriptions across every adapter the supplied `Chat` instance has registered. Write operations require user approval by default and can be toggled globally or per-tool via `requireApproval`. Three presets (`reader`, `messenger`, `moderator`) scope the toolset, and tools can also be cherry-picked from the same subpath. `toAiMessages` (and the `AiMessage` / `AiMessagePart` / `ToAiMessagesOptions` types) now ship from `chat/ai` alongside the tools — keeping the optional `ai` and `zod` peer dependencies out of bundles that don't use them. The previous `chat` re-exports continue to work, but are marked `@deprecated` so editors surface a hint pointing at `chat/ai`; existing code keeps compiling, and migrating is a single import-path change. -b75eedb: add burst concurrency strategy ### Patch Changes -e60bc8c: chore: set supported Node versions in engines ## @chat-adapter/state-ioredis@4.29.0 ### Patch Changes -e60bc8c: chore: set supported Node versions in engines -06fb8e5: Align package shapes with the new `konsistent` conventions. All changes are backwards-compatible — previous type names are kept as deprecated aliases. - `@chat-adapter/gchat`, `@chat-adapter/slack`: moved `*AdapterConfig` (and related sub-types) into a `./types` module; the public re-exports from `index.ts` are unchanged. - `@chat-adapter/slack`: `createSlackAdapter` now accepts `SlackAdapterConfig` directly instead of `Partial<SlackAdapterConfig>`. Every field on the config was already optional, so no call sites need to change. - `@chat-adapter/messenger`: `MessengerAdapterConfig` fields are now optional (the factory still falls back to `FACEBOOK_*` env vars), and `logger` / `userName` live on `MessengerAdapterConfig` directly. The factory signature is now `createMessengerAdapter(config?: MessengerAdapterConfig)`. - `@chat-adapter/web`: renamed `WebAdapterOptions` to `WebAdapterConfig`; the old name is exported as a deprecated alias. - `@chat-adapter/whatsapp`: every field on `WhatsAppAdapterConfig` is optional (the factory still falls back to `WHATSAPP_*` env vars). `createWhatsAppAdapter` is now typed `(config?: WhatsAppAdapterConfig) => WhatsAppAdapter`. - `@chat-adapter/state-memory`: added an empty `MemoryStateAdapterOptions` type so the package matches every other state adapter; `createMemoryState` now accepts an optional argument of that type. - `@chat-adapter/state-ioredis`, `@chat-adapter/state-redis`, `@chat-adapter/state-pg`: the URL- and client-based option shapes were split into named interfaces (`*StateAdapterUrlOptions` / `*StateAdapterClientOptions`) and unified under `*StateAdapterOptions`. The factories now take the union type directly. Old names — `RedisStateClientOptions`, `CreateRedisStateOptions`, `PostgresStateClientOptions`, `CreatePostgresStateOptions`, `IoRedisStateClientOptions` — are kept as deprecated aliases. - Updated dependencies [ac8a207] - Updated dependencies [e60bc8c] - Updated dependencies [b75eedb] - chat@4.29.0 ## @chat-adapter/state-memory@4.29.0 ### Patch Changes -e60bc8c: chore: set supported Node versions in engines -06fb8e5: Align package shapes with the new `konsistent` conventions. All changes are backwards-compatible — previous type names are kept as deprecated aliases. - `@chat-adapter/gchat`, `@chat-adapter/slack`: moved `*AdapterConfig` (and related sub-types) into a `./types` module; the public re-exports from `index.ts` are unchanged. - `@chat-adapter/slack`: `createSlackAdapter` now accepts `SlackAdapterConfig` directly instead of `Partial<SlackAdapterConfig>`. Every field on the config was already optional, so no call sites need to change. - `@chat-adapter/messenger`: `MessengerAdapterConfig` fields are now optional (the factory still falls back to `FACEBOOK_*` env vars), and `logger` / `userName` live on `MessengerAdapterConfig` directly. The factory signature is now `createMessengerAdapter(config?: MessengerAdapterConfig)`. - `@chat-adapter/web`: renamed `WebAdapterOptions` to `WebAdapterConfig`; the old name is exported as a deprecated alias. - `@chat-adapter/whatsapp`: every field on `WhatsAppAdapterConfig` is optional (the factory still falls back to `WHATSAPP_*` env vars). `createWhatsAppAdapter` is now typed `(config?: WhatsAppAdapterConfig) => WhatsAppAdapter`. - `@chat-adapter/state-memory`: added an empty `MemoryStateAdapterOptions` type so the package matches every other state adapter; `createMemoryState` now accepts an optional argument of that type. - `@chat-adapter/state-ioredis`, `@chat-adapter/state-redis`, `@chat-adapter/state-pg`: the URL- and client-based option shapes were split into named interfaces (`*StateAdapterUrlOptions` / `*StateAdapterClientOptions`) and unified under `*StateAdapterOptions`. The factories now take the union type directly. Old names — `RedisStateClientOptions`, `CreateRedisStateOptions`, `PostgresStateClientOptions`, `CreatePostgresStateOptions`, `IoRedisStateClientOptions` — are kept as deprecated aliases. - Updated dependencies [ac8a207] - Updated dependencies [e60bc8c] - Updated dependencies [b75eedb] - chat@4.29.0 ## @chat-adapter/state-pg@4.29.0 ### Patch Changes -e60bc8c: chore: set supported Node versions in engines -06fb8e5: Align package shapes with the new `konsistent` conventions. All changes are backwards-compatible — previous type names are kept as deprecated aliases. - `@chat-adapter/gchat`, `@chat-adapter/slack`: moved `*AdapterConfig` (and related sub-types) into a `./types` module; the public re-exports from `index.ts` are unchanged. - `@chat-adapter/slack`: `createSlackAdapter` now accepts `SlackAdapterConfig` directly instead of `Partial<SlackAdapterConfig>`. Every field on the config was already optional, so no call sites need to change. - `@chat-adapter/messenger`: `MessengerAdapterConfig` fields are now optional (the factory still falls back to `FACEBOOK_*` env vars), and `logger` / `userName` live on `MessengerAdapterConfig` directly. The factory signature is now `createMessengerAdapter(config?: MessengerAdapterConfig)`. - `@chat-adapter/web`: renamed `WebAdapterOptions` to `WebAdapterConfig`; the old name is exported as a deprecated alias. - `@chat-adapter/whatsapp`: every field on `WhatsAppAdapterConfig` is optional (the factory still falls back to `WHATSAPP_*` env vars). `createWhatsAppAdapter` is now typed `(config?: WhatsAppAdapterConfig) => WhatsAppAdapter`. - `@chat-adapter/state-memory`: added an empty `MemoryStateAdapterOptions` type so the package matches every other state adapter; `createMemoryState` now accepts an optional argument of that type. - `@chat-adapter/state-ioredis`, `@chat-adapter/state-redis`, `@chat-adapter/state-pg`: the URL- and client-based option shapes were split into named interfaces (`*StateAdapterUrlOptions` / `*StateAdapterClientOptions`) and unified under `*StateAdapterOptions`. The factories now take the union type directly. Old names — `RedisStateClientOptions`, `CreateRedisStateOptions`, `PostgresStateClientOptions`, `CreatePostgresStateOptions`, `IoRedisStateClientOptions` — are kept as deprecated aliases. - Updated dependencies [ac8a207] - Updated dependencies [e60bc8c] - Updated dependencies [b75eedb] - chat@4.29.0 ## @chat-adapter/state-redis@4.29.0 ### Patch Changes -e60bc8c: chore: set supported Node versions in engines -06fb8e5: Align package shapes with the new `konsistent` conventions. All changes are backwards-compatible — previous type names are kept as deprecated aliases. - `@chat-adapter/gchat`, `@chat-adapter/slack`: moved `*AdapterConfig` (and related sub-types) into a `./types` module; the public re-exports from `index.ts` are unchanged. - `@chat-adapter/slack`: `createSlackAdapter` now accepts `SlackAdapterConfig` directly instead of `Partial<SlackAdapterConfig>`. Every field on the config was already optional, so no call sites need to change. - `@chat-adapter/messenger`: `MessengerAdapterConfig` fields are now optional (the factory still falls back to `FACEBOOK_*` env vars), and `logger` / `userName` live on `MessengerAdapterConfig` directly. The factory signature is now `createMessengerAdapter(config?: MessengerAdapterConfig)`. - `@chat-adapter/web`: renamed `WebAdapterOptions` to `WebAdapterConfig`; the old name is exported as a deprecated alias. - `@chat-adapter/whatsapp`: every field on `WhatsAppAdapterConfig` is optional (the factory still falls back to `WHATSAPP_*` env vars). `createWhatsAppAdapter` is now typed `(config?: WhatsAppAdapterConfig) => WhatsAppAdapter`. - `@chat-adapter/state-memory`: added an empty `MemoryStateAdapterOptions` type so the package matches every other state adapter; `createMemoryState` now accepts an optional argument of that type. - `@chat-adapter/state-ioredis`, `@chat-adapter/state-redis`, `@chat-adapter/state-pg`: the URL- and client-based option shapes were split into named interfaces (`*StateAdapterUrlOptions` / `*StateAdapterClientOptions`) and unified under `*StateAdapterOptions`. The factories now take the union type directly. Old names — `RedisStateClientOptions`, `CreateRedisStateOptions`, `PostgresStateClientOptions`, `CreatePostgresStateOptions`, `IoRedisStateClientOptions` — are kept as deprecated aliases. - Updated dependencies [ac8a207] - Updated dependencies [e60bc8c] - Updated dependencies [b75eedb] - chat@4.29.0 ## @chat-adapter/tests@4.29.0 ### Patch Changes -0adf3ad: Add `@chat-adapter/tests` — Vitest factories, matchers, and setup utilities for Chat SDK adapter and bot authors. - **Factories**: `createMockAdapter`, `createMockChatInstance`, `createMockState` (with working in-memory subscriptions/locks/KV/queues), `createTestMessage`, `mockLogger`/`createMockLogger`. - **Matchers**: `toHavePosted(threadId, textPattern?)`, `toHaveDispatched(handler)`, `toBeSubscribedTo(threadId)`. - **Setup file**: `@chat-adapter/tests/setup` registers all matchers via `expect.extend` — drop into `vitest.config.ts` `setupFiles`. `chat` and `vitest` are peer dependencies. Adapter-specific helpers (e.g. signed Slack webhook builders) belong in each adapter's own `/testing` subpath, not in this kit. Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@chat-adapter/tests
Vitest factories, matchers, and setup utilities for testing Chat SDK adapters and bots.
Installation
pnpm add -D @chat-adapter/tests
This package has chat and vitest as peer dependencies — they should already be in your project.
Factories
import {
createMockAdapter,
createMockChatInstance,
createMockState,
createTestMessage,
mockLogger,
} from "@chat-adapter/tests";
createMockAdapter(name?, overrides?)
Returns an Adapter with every method as vi.fn() and sensible defaults. Pass overrides to swap individual methods:
const adapter = createMockAdapter("slack", {
postMessage: vi.fn().mockResolvedValue({ id: "msg-7", raw: {} }),
});
createMockState()
Returns a StateAdapter backed by in-memory Maps — subscriptions, locks, KV, lists, and queues all work end-to-end. Includes a cache: Map<string, unknown> for direct inspection.
createMockChatInstance(options?)
Returns a ChatInstance with every process* handler as vi.fn(). Useful for adapter authors verifying their adapter dispatches incoming events through the right hook.
const state = createMockState();
const chat = createMockChatInstance({ state });
await myAdapter.handleWebhook(req); // your adapter under test
expect(chat.processMessage).toHaveBeenCalledOnce();
createTestMessage(id, text, overrides?)
Builds a Message with parsed markdown AST already wired up.
mockLogger / createMockLogger()
mockLogger is a shared Logger for tests that don't care about isolation. createMockLogger() returns a fresh one per call.
Matchers
Vitest custom matchers covering the most common Chat SDK assertions.
Auto-register via setup file
// vitest.config.ts
import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
setupFiles: ["@chat-adapter/tests/setup"],
},
});
Manual registration
import { matchers } from "@chat-adapter/tests/matchers";
expect.extend(matchers);
Available matchers
| Matcher | Asserts |
|---|---|
expect(adapter).toHavePosted(threadId, textPattern?) |
adapter.postMessage was called for this thread (and message text matches textPattern if given) |
expect(adapter).toHaveEdited(threadId, messageId, textPattern?) |
adapter.editMessage was called for this message (and text matches textPattern if given) |
expect(adapter).toHaveDeleted(threadId, messageId) |
adapter.deleteMessage was called for this message |
expect(adapter).toHaveReactedWith(threadId, messageId, emoji) |
adapter.addReaction was called with the emoji (string or EmojiValue.name) |
expect(adapter).toHaveStartedTyping(threadId) |
adapter.startTyping was called for this thread |
expect(adapter).toHavePostedToChannel(channelId, textPattern?) |
adapter.postChannelMessage was called for this channel |
expect(chat).toHaveDispatched(handler) |
The named process* handler on the mock ChatInstance was called |
expect(state).toBeSubscribedTo(threadId) |
state.isSubscribed(threadId) resolves to true (async — needs await) |
expect(adapter).toHavePosted("slack:C1:t1", /hello/);
expect(adapter).toHaveEdited("slack:C1:t1", "msg-1", /updated/);
expect(adapter).toHaveDeleted("slack:C1:t1", "msg-1");
expect(adapter).toHaveReactedWith("slack:C1:t1", "msg-1", "thumbsup");
expect(adapter).toHaveStartedTyping("slack:C1:t1");
expect(adapter).toHavePostedToChannel("slack:C1");
expect(chat).toHaveDispatched("processMessage");
await expect(state).toBeSubscribedTo("slack:C1:t1");
Text-pattern matchers (toHavePosted, toHaveEdited, toHavePostedToChannel) extract a comparable string from AdapterPostableMessage — handling plain strings, PostableMarkdown.markdown, PostableRaw.raw, and PostableCard.fallbackText. AST-shaped messages (PostableAst) and cards without fallbackText aren't text-matchable; assert without textPattern and inspect mock.calls directly for deeper checks.
Audience
- Bot authors — drive simulated events through your handlers, assert on outbound calls.
- Adapter authors — verify your
Adapterimplementation routes webhooks through the rightChatInstance.process*hook with the right normalized payload.
Adapter-specific helpers (e.g. signed Slack webhook builders, Teams claim builders) live in each adapter's own /testing subpath, not in this kit.