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/telegram
Telegram adapter for Chat SDK. Configure for bot webhooks and messaging.
Installation
pnpm add @chat-adapter/telegram
Usage
The adapter auto-detects TELEGRAM_BOT_TOKEN, TELEGRAM_WEBHOOK_SECRET_TOKEN, TELEGRAM_BOT_USERNAME, and TELEGRAM_API_BASE_URL from environment variables:
import { Chat } from "chat";
import { createTelegramAdapter } from "@chat-adapter/telegram";
const bot = new Chat({
userName: "mybot",
adapters: {
telegram: createTelegramAdapter(),
},
});
bot.onNewMention(async (thread, message) => {
await thread.post(`You said: ${message.text}`);
});
Webhook route
import { bot } from "@/lib/bot";
export async function POST(request: Request): Promise<Response> {
return bot.webhooks.telegram(request);
}
Configure this URL as your bot webhook in BotFather / Telegram API:
curl -X POST "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/setWebhook" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-domain.com/api/webhooks/telegram",
"secret_token": "your-secret-token"
}'
Polling (local development)
When developing locally you typically can't expose a public URL for Telegram to deliver webhooks to. Polling mode uses getUpdates to fetch messages directly from Telegram instead — no public endpoint needed.
The longPolling option is entirely optional. Sensible defaults are applied when omitted.
import { Chat } from "chat";
import { createTelegramAdapter } from "@chat-adapter/telegram";
import { createMemoryState } from "@chat-adapter/state-memory";
const telegram = createTelegramAdapter({
mode: "polling",
// Optional — fine-tune polling behavior:
// longPolling: { timeout: 30, dropPendingUpdates: false },
});
const bot = new Chat({
userName: "mybot",
adapters: { telegram },
state: createMemoryState(),
});
// Optional manual lifecycle control:
// await telegram.resetWebhook();
// await telegram.startPolling();
// await telegram.stopPolling();
Auto mode
With mode: "auto" (the default), the adapter picks the right strategy for you. When deployed to a serverless environment like Vercel it uses webhooks; everywhere else (e.g. local dev) it falls back to polling automatically.
import { Chat } from "chat";
import { createTelegramAdapter } from "@chat-adapter/telegram";
import { createMemoryState } from "@chat-adapter/state-memory";
const telegram = createTelegramAdapter({
mode: "auto", // default
});
export const bot = new Chat({
userName: "mybot",
adapters: { telegram },
state: createMemoryState(),
});
// Call initialize() so polling can start in long-running local processes:
void bot.initialize();
console.log(telegram.runtimeMode); // "webhook" | "polling"
Configuration
All options are auto-detected from environment variables when not provided.
| Option | Required | Description |
|---|---|---|
botToken |
No* | Telegram bot token. Auto-detected from TELEGRAM_BOT_TOKEN |
secretToken |
No | Optional webhook secret token. Auto-detected from TELEGRAM_WEBHOOK_SECRET_TOKEN |
mode |
No | Adapter mode: auto (default), webhook, or polling |
longPolling |
No | Optional long polling config for getUpdates (timeout, limit, allowedUpdates, deleteWebhook, dropPendingUpdates, retryDelayMs) |
userName |
No | Bot username used for mention detection. Auto-detected from TELEGRAM_BOT_USERNAME or getMe |
apiUrl |
No | Telegram API base URL. Auto-detected from TELEGRAM_API_BASE_URL. Use apiUrl for cross-adapter consistency; the legacy apiBaseUrl alias is still accepted |
logger |
No | Logger instance (defaults to ConsoleLogger("info")) |
*botToken is required — either via config or env vars.
Environment variables
TELEGRAM_BOT_TOKEN=123456:ABCDEF...
TELEGRAM_WEBHOOK_SECRET_TOKEN=your-webhook-secret
TELEGRAM_BOT_USERNAME=mybot
# Optional (self-hosted API gateway)
TELEGRAM_API_BASE_URL=https://api.telegram.org
Features
Messaging
| Feature | Supported |
|---|---|
| Post message | Yes |
| Edit message | Yes |
| Delete message | Yes |
| File uploads | Single file (sendDocument) |
| Attachment uploads | Single image/audio/video/file (sendPhoto, sendAudio, sendVideo, sendDocument) |
| Streaming | Post+Edit fallback |
Rich content
| Feature | Supported |
|---|---|
| Card format | MarkdownV2 + inline keyboard buttons |
| Buttons | Inline keyboard callbacks |
| Link buttons | Inline keyboard URLs |
| Select menus | No |
| Tables | ASCII |
| Fields | Yes |
| Images in cards | No |
| Modals | No |
Conversations
| Feature | Supported |
|---|---|
| Slash commands | No |
| Mentions | Yes |
| Add reactions | Yes |
| Remove reactions | Yes |
| Typing indicator | Yes |
| DMs | Yes |
| Ephemeral messages | No |
Message history
| Feature | Supported |
|---|---|
| Fetch messages | Cached |
| Fetch single message | Cached |
| Fetch thread info | Yes |
| Fetch channel messages | Cached |
| List threads | No |
| Fetch channel info | Yes |
| Post channel message | Yes |
Markdown formatting
Outbound messages are sent with Telegram's MarkdownV2 parse mode. The adapter walks the markdown AST and emits MarkdownV2 with context-aware escaping (normal text vs. code blocks vs. link URLs), so you author standard markdown (**bold**, *italic*, `code`, [label](url)) and the adapter handles every reserved character.
Behavior change in 4.27.0: previous versions used Telegram's legacy Markdown parse mode, which used different syntax (*bold* instead of **bold**) and silently rejected any text containing unescaped ., !, (, ), -, _. If you were emitting raw legacy-Markdown strings or hand-escaping characters yourself, drop the manual escaping — the renderer does it for you. Pass { raw: "..." } only if you need to ship a fully pre-escaped MarkdownV2 string.
Notes
- Telegram does not expose full historical message APIs to bots.
fetchMessages/fetchChannelMessagesreturn adapter-cached messages from the current process. listThreadsis not available for Telegram chats.- Polling and webhooks are mutually exclusive in Telegram.
mode: "polling"deletes webhook by default before callinggetUpdates.mode: "auto"checksgetWebhookInfo: if a webhook URL exists it uses webhook mode; if it is empty it falls back to polling on non-serverless runtimes without deleting webhook.- If
getWebhookInfofails inmode: "auto", the adapter stays in webhook mode (safe fallback). ButtonandLinkButtonin cardActionsrender as inline keyboard buttons.- Telegram callback data is limited to 64 bytes. Keep button
id/valuepayloads short. filesupload as Telegram documents.attachmentspreserve the normalized media type for single image, audio, video, or file uploads. UsedataorfetchDatafor private/authenticated files; URL-only attachments must be public URLs Telegram can fetch directly.- Other rich card elements (images/select menus/radios) render as fallback text only.
License
MIT