mirror of
https://github.com/vercel/chat.git
synced 2026-09-14 18:32:29 +08:00
create-chat-sdk@0.2.0
133 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
ef2542c5fd |
feat(x): add X (Twitter) adapter (#682)
## summary
new `@chat-adapter/x` adapter for X (Twitter), built on the X API v2 and
the X Activity API. write bot logic once and reply to mentions, hold DM
conversations, post from the account, and like posts, like the other
Chat SDK adapters
what it supports:
- reply to public mentions (`post.mention.create`) and top-level posts
via `channel.post`
- send and receive direct messages (`dm.received` / `dm.sent`)
- edit and delete owned posts, delete own DM events
- likes as the only reaction (`emoji.heart` or `"like"`)
- buffered streaming: accumulates an LLM stream and posts once instead
of post+edit churn on a public timeline
- OAuth 2.0 user context with managed token refresh (rotating refresh
token persisted in the state adapter, optional AES-256-GCM encryption)
- webhook CRC and `x-twitter-webhooks-signature` verification
key design decisions:
- DMs are threaded by the other participant's user id (`x:dm:{userId}`)
because X DM webhooks carry no conversation id, only participants
- OAuth 2.0 only at runtime: DM send and read are verified to work on
OAuth 2.0 user tokens, so no OAuth 1.0a in the adapter (subscription and
webhook setup is one-time and handled in the X developer console)
- parsers were written against real captured payloads: mentions use the
v2 shape (author hydrated in `includes.users`), DMs use the legacy
Account Activity shape (`direct_message_events`,
`message_create.message_data`, a `users` map, and no conversation id)
also includes the `chat/adapters` catalog entry, docs page, CLI scaffold
spec, and `sample-messages.md` with real captured payloads
<details><summary>usage</summary>
```typescript
import { Chat } from "chat";
import { createXAdapter } from "@chat-adapter/x";
const bot = new Chat({
userName: "mybot",
adapters: { x: createXAdapter() },
});
bot.onNewMention(async (thread, message) => {
await thread.post(`hi @${message.author.userName}!`);
});
bot.onDirectMessage(async (thread) => {
await thread.post("hello from X");
});
```
</details>
## test plan
- adapter unit tests pass against the real captured payload shapes, with
regression tests for author-from-`includes` (mentions) and the legacy
`direct_message_events` shape (DMs)
- real captured `post.mention.create` and `dm.received` payloads
verified end-to-end through `handleWebhook`: signature verification,
routing, author resolution, and participant threading, plus
bad-signature rejection returns 401
- every write and read path fired live against the X API through the
adapter: top-level post, reply to a mention, like and unlike, edit,
delete, DM send, DM read, DM delete
- OAuth 2.0 managed token refresh exercised live (access and refresh
token rotation)
---------
Signed-off-by: dancer <josh@afterima.ge>
|
||
|
|
eb466e526f |
docs: add chat-adapter-zaileys community adapter (#677)
## Summary Adds **chat-adapter-zaileys** to the community adapters catalog — a WhatsApp adapter powered by [Zaileys](https://github.com/zeative/zaileys), a batteries-included TypeScript wrapper around the unofficial WhatsApp Web API. - npm: https://www.npmjs.com/package/chat-adapter-zaileys - Repo: https://github.com/zeative/chat-adapter-zaileys - Docs: https://zeative.github.io/chat-adapter-zaileys/ ## What it adds vs the existing Baileys community adapter - Real `thread.fetchMessages` history backed by a pluggable message store (memory/SQLite/Postgres/Redis/Convex), with cursor pagination and `rehydrateAttachment` for queue/debounce strategies - Cards render as **native WhatsApp buttons** with `chat.onAction` round-trips - Poll votes decrypted natively — no `messageSecret` bookkeeping, works across restarts - `scheduleMessage` support (persisted scheduler) - Opt-in slash-command routing to `chat.onSlashCommand` - QR/pairing auth, reconnection, and session persistence handled by the underlying client ## Files changed (per `.agents/skills/add-adapter`) - `apps/docs/content/adapters/community/zaileys.mdx` — docs page with feature matrix - `apps/docs/content/adapters/community/meta.json` — slug added to Platforms - `apps/docs/adapters.json` — registry entry - `packages/integration-tests/src/documentation-test-utils.ts` — `chat-adapter-zaileys` + `zaileys` in `VALID_DOC_PACKAGES` ## Validation - `pnpm --filter chat build` ✓ - `pnpm --filter @chat-adapter/integration-tests test` → 914/914 ✓ - `pnpm --filter chat typecheck` ✓ - `pnpm check` + `pnpm konsistent` ✓ Signed-off-by: zeative <zaadevofc@gmail.com> |
||
|
|
0c761f1bdd |
docs(adapters): add Dial as vendor-official adapter (#676)
Adds Dial as a vendor-official adapter — SMS, MMS, iMessage, and inbound voice-call transcripts for Chat SDK. - `vendor-official/dial.mdx` adapter page (following the Photon / Linq / Sendblue format) - catalog entry in `packages/chat/src/adapters/index.ts` with `DIAL_API_KEY` / `DIAL_FROM_NUMBER_ID` / `DIAL_WEBHOOK_SECRET` - `create-chat-sdk` scaffold spec entry - registry entry in `adapters.json` + `dial` added to vendor-official `meta.json` - integration-test doc lists + changeset Repo: https://github.com/GetDial-AI/chat-sdk-adapter · npm: `@getdial/chat-sdk-adapter` · Dial docs: https://docs.getdial.ai/integrations/agent-clients/vercel-chat-sdk The adapter maps a phone conversation to a Chat SDK thread (identified by the pair of phone numbers — Dial-owned and peer), an SMS/MMS/iMessage to a message with optional media attachments, and a completed voice call's transcript to a message on the caller's thread. Outbound sends and transcript fetches go through the official `@getdial/sdk`; inbound webhooks are HMAC-SHA256 verified against a per-subscription signing secret with constant-time compare. ### Validation - `pnpm --filter chat build` — clean - `pnpm --filter chat typecheck` — clean - `pnpm --filter create-chat-sdk typecheck` — clean - `pnpm --filter @chat-adapter/integration-tests exec vitest run src/docs-adapters.test.ts` — 361/361 passed - `pnpm check` (ultracite) — clean - `pnpm konsistent` — 34 files, no violations |
||
|
|
3abdc69103 |
docs(adapters): add Cloudflare Agents as vendor-official state adapter (#669)
Adds Cloudflare Agents as a vendor-official **state** adapter — `agents/chat-sdk`'s `createChatSdkState()`, a Chat SDK `StateAdapter` that stores subscriptions, locks, queues, dedupe keys, thread/channel state, transcripts, and history in Durable Object SQLite via `ChatSdkStateAgent` sub-agents. - `vendor-official/cloudflare-agents.mdx` state-adapter page (Agent setup, wrangler DO migration, sharding, config, storage/cleanup) - catalog entry in `packages/chat/src/adapters/index.ts` (`group: vendor-official`, `type: state`) - registry entry in `adapters.json` + `cloudflare-agents` in vendor-official `meta.json` - integration-test doc lists + changeset Repo: https://github.com/cloudflare/agents · package `agents` (`agents/chat-sdk`) · [docs](https://developers.cloudflare.com/agents/runtime/communication/chat-sdk/) ### Not wired into the create-chat-sdk CLI This adapter runs inside a Cloudflare Worker with Durable Objects, not the generated Next.js runtime, so it is intentionally kept out of the scaffold: - added to `CLI_INCOMPATIBLE_ADAPTERS` (rejected via `--adapter`, hidden from the platform picker and e2e run, like `lark`/`matrix`) - new `listCliStateAdapters()` filters the interactive **state** picker and the `--help` adapter list (the state picker previously used raw `listStateAdapters()` and would have offered it, then thrown on selection) ### Tests - `catalog/display.test.ts` — `listCliStateAdapters`: returns only state adapters, includes `memory`/`redis`, and excludes `cloudflare-agents` while asserting it *is* in the raw catalog - `catalog/selection.test.ts` — `resolveAdapterValue("cloudflare-agents")` throws "not supported" - `cli/program.test.ts` — `buildAdapterList()` help text omits `cloudflare-agents` - existing `CLI_SCAFFOLD_SPEC covers every catalog adapter` + docs-adapters/docs-content suites cover the catalog entry, registry parity, and MDX imports ### Validation - create-chat-sdk: **178 passed**, typecheck clean - integration docs suites pass; Biome + knip clean --------- Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> |
||
|
|
24a04d5653 |
docs(adapters): add Photon as vendor-official adapter (#668)
Adds Photon as a vendor-official adapter — iMessage for Chat SDK. - `vendor-official/photon.mdx` adapter page (following the Linq / Sendblue / Kapso format) - catalog entry in `packages/chat/src/adapters/index.ts` with cloud/self-host credential modes - `create-chat-sdk` scaffold spec entry - registry entry in `adapters.json` + `photon` added to vendor-official `meta.json` - integration-test doc lists + changeset Repo: https://github.com/photon-hq/vercel-chat-adapter-imessage · npm: `@photon-ai/chat-adapter-imessage` · built on [spectrum-ts](https://github.com/photon-hq/spectrum-ts) The adapter runs in three modes — **Cloud** ([Spectrum Cloud](https://app.photon.codes)), **self-hosted** (gRPC), and **local** (on-device, macOS) — auto-detected from environment variables. Cloud mode delivers inbound messages via HMAC-signed webhooks; DMs can be replied to cold from a webhook delivery. ### Notes - Catalog slug is `photon`; docs code examples use `imessage` as the adapter key to match the upstream README. - Feature flags encode the README's remote-only caveats (reactions / editing / typing / modals as `partial`, mentions as DMs-only; no history, thread info, or reaction removal). ### Validation - `docs-adapters` integration tests — 1237 passed (catalog↔registry parity, peerDeps↔PackageInstall alignment) - `create-chat-sdk` e2e scaffold — 175 passed (scaffolds every catalog adapter, incl. photon) - `chat` + `create-chat-sdk` typecheck, Biome check, and konsistent — clean Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> |
||
|
|
4115c9431e |
feat(linear): add Vercel Connect support (#649)
Adds Vercel Connect support to the Linear adapter: - `accessToken` now accepts a `() => string | Promise<string>` resolver in addition to a string, so tokens can be sourced from Vercel Connect at runtime. - A new optional `webhookVerifier` verifies inbound webhooks (Connect trigger-forwarded requests via a Vercel OIDC token) in place of the Linear webhook secret. - Connect-mode outbound calls outside webhook handling are supported via `withInstallation(organizationId, fn)`. Pair with `connectLinearAdapter()` from `@vercel/connect/chat`. Includes a changeset (`@chat-adapter/linear` minor). Stacked on #647 (base `vercel-connect/base`). ## Companion `@vercel/connect/chat` subpath: vercel/vercel#16826. <img width="929" height="664" alt="CleanShot 2026-06-30 at 12 35 30" src="https://github.com/user-attachments/assets/c5861cb9-d66b-42c6-b838-5b4983f48646" /> --------- Signed-off-by: Ben Sabic <bensabic@users.noreply.github.com> Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> |
||
|
|
ab0e1806c8 |
feat(chat): Vercel Connect (#647)
Adds a Vercel Connect guide to the docs under **Usage** (`chat-sdk.dev/docs/vercel-connect`), covering connector setup, trigger forwarding, the per-platform `connect*Adapter` helpers from `@vercel/connect/chat`, custom OIDC webhook verification and its trust boundary, and limitations. Also adds a "Vercel Connect Guide" card to the docs homepage. This is the base of a stack; the adapter, tests, and CLI PRs below build on it. Docs-only, so no changeset. ## Stack - #647 — feat(chat): Vercel Connect (this PR, base → `main`) - #648 — docs(slack): document Vercel Connect support - #649 — feat(linear): add Vercel Connect support - #650 — feat(github): add Vercel Connect support - #654 — feat(tests): add Vercel Connect webhook contract helper - #655 — feat(create-chat-sdk): add Vercel Connect mode All of the above are stacked on this branch (`vercel-connect/base`). ## Companion The helpers this documents ship in the `@vercel/connect/chat` subpath: vercel/vercel#16826. --------- Signed-off-by: Ben Sabic <bensabic@users.noreply.github.com> Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> |
||
|
|
99c598505f |
docs: refresh agent docs, README badges, and Chat SDK skill (#646)
- Replace npm version/download badges with Agent Stack and MIT badges on the root README and all published package READMEs - Streamline root `AGENTS.md`: fix title, add an accurate monorepo map, trim duplicated CONTRIBUTING/Ultracite/env-var content, and link to package-level `AGENTS.md` files - Slim the Chat SDK agent skill (`skills/chat/SKILL.md` and published copies) to defer to bundled docs, chat-sdk.dev, Vercel KB, and `llms.txt` instead of inlining CLI flags, quick-start code, and API tables - Polish root README copy (install examples, adapter/build links, Vercel Plugin URL, Vercel KB link, “Made by Vercel” badge) - Minor `CONTRIBUTING.md` fixes: simplify DCO wording, correct preview-branch proxy file references (`proxy.ts` vs middleware) --------- Signed-off-by: Ben Sabic <bensabic@users.noreply.github.com> Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> |
||
|
|
ef3f0f63bd |
docs: add Weixin community adapter (#638)
Adds the [`chat-adapter-weixin`](https://github.com/wong2/weixin-chat-adapter) community adapter (Weixin / WeChat iLink bot) to the docs. ### What's included - `apps/docs/content/adapters/community/weixin.mdx` — hand-authored adapter page following the existing community-adapter structure (install, quick start, long-polling note, QR login, env vars, config `TypeTable`, thread-ID format, capabilities/limitations, and `<FeatureSupport />`). - `apps/docs/adapters.json` — registry entry (`community: true`, author, pinned README commit). - `apps/docs/content/adapters/community/meta.json` — sidebar link under **Platforms**. ### Notes The adapter talks to Weixin's iLink bot HTTP JSON APIs directly. It uses long polling for inbound messages (no webhook) and requires a Chat SDK `StateAdapter` for cursor / context-token / dedupe / history. It's 1:1 only, so messages route through `onDirectMessage`. ### Verification `docs-adapters` (322) and `docs-llms` (129) integration tests pass. --------- Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> |
||
|
|
64b66864b1 |
chore(changesets): ignore all example-* packages and enforce the convention (#626)
Replace the explicit per-example entries in the changesets `ignore` list with an `example-*` name glob (matched by micromatch). All example apps are private and never published, so listing them individually only adds version and changelog churn to release PRs, and each new example required editing this CODEOWNERS-gated file. Add an integration test that resolves the changesets config against the workspace and asserts every examples/* package is in the resolved ignore list and follows the `example-*` naming convention, so an off-convention example app fails CI instead of silently leaking into releases. --------- Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> |
||
|
|
efa96108bd |
docs: sync KB resources and harden sync-resources script (#635)
Syncs the bundled Chat SDK KB resources from Edge Config and hardens the `sync-resources` script that generates them. - **New guides** (4): Vercel Connect, the Slack Vercel Connect bot, AI Gateway + AI SDK, and the daily digest bot. Existing guide bodies refreshed and `templates.json` regenerated. - **Script hardening** (`scripts/sync-resources.ts`): - Fetch + validate all guides into memory **before** wiping the resources dir — a failed fetch now leaves the working tree untouched. - Validate the `resources-edge-config.json` shape with a clear error instead of a blind cast. - Reject duplicate guide slug collisions. - Retry transient fetches (5xx / network) with exponential backoff; fail fast on 4xx, bad content-type, and oversized bodies. - Mirror `skills/chat/SKILL.md` to **all four** committed copies (docs site `.well-known` + `AGENTS.md`, and the two `create-chat-sdk` scaffold templates). - TSDoc on every function. - **Tests**: new offline consistency test in `packages/integration-tests` — every guide has a non-empty file with no orphans, `templates.json` mirrors the config, no duplicate slugs, and all four `SKILL.md` copies are byte-identical to the source. --------- Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> |
||
|
|
d034b8b575 |
docs(adapters): add Linq as vendor-official adapter (#625)
Adds Linq as a vendor-official adapter — iMessage and SMS for Chat SDK. - `vendor-official/linq.mdx` adapter page (following the Velt / AgentPhone format) - catalog entry in `adapters.json` - `linq` added to the vendor-official `meta.json` Repo: https://github.com/linq-team/linq-chat-sdk · npm: `@linqapp/chat-sdk-adapter` (Apache-2.0) The adapter is built and tested end-to-end against the live Linq API and the Chat SDK runtime (real iMessage round-trip, webhooks, reactions, media). Confirmed with Benji that a repo link works and Apache-2.0 is fine. Happy to adjust the page to match any conventions I missed. --------- Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> |
||
|
|
06af3e12fd |
docs(adapters): add Novu as vendor-official adapter (#622)
## Summary Adds Novu as a vendor official adapter to Chat SDK allowing multi-channel notification delivery and quick channel setup for multi-tenant apps. Official change log entry: https://novu.co/changelog/novu-chat-sdk-adapter/ Official social post: https://x.com/novuhq/status/2067870170320679158 ## Test plan Manually tested with our team to ensure compatability with the create chat sdk and template apps, also created an example repo: https://github.com/novuhq/novu-chat-sdk-example ## Checklist - [x] All commits are signed and verified - [x] `pnpm validate` passes - [x] Changeset added (or N/A — see [CONTRIBUTING.md](./CONTRIBUTING.md)) - [x] Documentation updated (or N/A) --------- Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> |
||
|
|
8c7141174a |
feat(teams): add low-level primitives (#593)
Add Teams subpath exports for custom runtimes, including Bot Connector API helpers, Graph reads, parse-only webhooks, format helpers, Adaptive Cards, and Task Module primitives. --------- Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> |
||
|
|
8f3af76565 |
feat: add create-chat-sdk CLI (#603)
Adds `create-chat-sdk`, a CLI that scaffolds a Next.js Chat SDK bot project: ```bash npm create chat-sdk@latest my-bot # non-interactive npm create chat-sdk@latest -- my-bot --adapter slack redis -y ``` The user picks platform and state adapters interactively or via `--adapter`, and the CLI generates a webhook-only project with `src/lib/bot.ts`, `.env.example`, `next.config.ts`, `package.json`, and a README, then optionally runs `git init` and installs dependencies. There are no pages or client UI in the template. Adapter choices come straight from the `chat/adapters` catalog, so the CLI has no adapter registry of its own. When a coding agent such as Cursor or Claude Code runs the CLI, it uses non-interactive defaults and requires an explicit platform adapter. `--interactive` forces prompts. ## also in this pr - `google-chat` is renamed to `gchat` everywhere, including docs pages, the OG image, and adapter catalog. Old URLs redirect permanently, including language-prefixed and `/og` paths - a new docs page is available at `chat-sdk.dev/docs/create-chat-sdk`, and the CLI is promoted on the homepage, package READMEs, and agent skill - `create-chat-sdk` releases independently with a minor changeset for its initial `0.1.0` release --------- Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> Co-authored-by: dancer <josh@afterima.ge> |
||
|
|
b14114a714 |
test(slack): expand emulator coverage for emulate.dev 0.6.0 APIs (#591)
Upgrade @emulators/* to 0.6.0 and add integration tests for DMs, reactions, fetch history, modals, scheduled messages, file uploads, member joins, and bookmarks against the in-process Slack emulator. --------- Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> |
||
|
|
778ae69abc |
add zero-dependency chat/adapters for adapters catalog (#599)
Adapter Catalog: - Adds a zero-dependency `chat/adapters` subpath for official and vendor-official adapter metadata. - Includes typed catalog entries, env specs, peer dependency metadata, and helper APIs for setup and onboarding flows. - Wires the subpath into the `chat` package export map and build config. Code Coverage: - Adds unit coverage for catalog integrity, registry sync, helper behavior, official env declarations, and peer dependency derivation. - Extends docs integration coverage for `chat/adapters` imports and vendor-official package install metadata. Documentation: - Documents the new catalog on the adapter overview page. - Splits platform-specific adapter guidance into a new `/docs/platform-adapters` page. - Renames `/docs/state` to `/docs/state-adapters` and adds a redirect for the old slug. Agent Guidance: - Updates repo-local and public agent guidance so agents know when and how to use `chat/adapters`. - Adds focused `AGENTS.md` guidance inside `packages/chat/src/adapters` for future catalog maintenance. --------- Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> |
||
|
|
7ecb9730e3 |
chore(docs): add missing Twilio logo and add official platform adapter OG images (#589)
Adds official platform adapter branding across the docs site, npm
READMEs, and social previews.
- **Homepage**: add Twilio to the supported-platforms logo grid
- **OG images**: add custom artwork for all 11 official platform
adapters under content/adapters/official/og/; serve static-first from
the existing /adapters/official/{slug}/og route with dynamic fallback
for state adapters
- **READMEs**: add linked hero banners to every official platform
adapter package README, using the live OG URL as the single image source
- **Tests**: integration-test guardrails for OG image coverage, README
banner discoverability, and knip-clean helpers
- **Changeset**: empty changeset for CI
<img width="2400" height="1256" alt="Chat SDK - Slack"
src="https://github.com/user-attachments/assets/4d186a1c-5651-44b8-8698-091ee23b44da"
/>
Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com>
|
||
|
|
9921dcd1c4 |
docs(seo): improve npm metadata, README discoverability, and structured data (#587)
Improves Chat SDK discoverability across npm, READMEs, and the docs site for search engines and AI coding agents. - **npm metadata**: point every published package `homepage` at chat-sdk.dev deep links; expand `chat` keywords/description; fix `repository.directory` (`packages/chat-sdk` → `packages/chat`); align state adapter keywords - **READMEs**: add npm callouts, Documentation/Guides links, and AI Coding Agents sections (skill install, optional Vercel Plugin, `llms.txt` / `llms-full.txt`) across all published packages and the repo root - **docs JSON-LD**: `HowTo` / `TechArticle` on getting-started, streaming, and cards; `CollectionPage` + official-only `ItemList` on `/adapters` (with split human vs JSON-LD descriptions) - **UTMs**: add `chat-sdk_site` / `chat-sdk_repo` tracking params to Resources links in selected MDX pages and adapter READMEs (discord, github, slack, liveblocks, getting-started, ai index) - **contract tests**: integration-tests guardrails for npm metadata and README discoverability so future package additions don't drift --------- Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> |
||
|
|
c290464634 |
docs(adapters): promote Sendblue to vendor-official adapter (#584)
Moves the Sendblue adapter from community to vendor-official in the docs site now that Sendblue maintains `chat-adapter-sendblue`. - package: `chat-adapter-sendblue` - repo: https://github.com/sendblue-api/chat-adapter-sendblue - docs: https://docs.sendblue.com/guides/chat-sdk-adapter/ Updates the adapter registry and hand-authored detail page (iMessage, SMS, RCS, `sb-signing-secret` webhook verification, official Sendblue guide links). Reorders vendor-official adapters so Liveblocks, Resend, Sendblue, and Zernio appear first. Adds a permanent redirect from `/adapters/community/sendblue`. Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> |
||
|
|
2fb8ad29cf |
docs(adapters): add Kapso WhatsApp adapter (#577)
## Summary Adds [Kapso WhatsApp](https://docs.kapso.ai/) as a vendor-official adapter in `adapters.json`. Kapso is a WhatsApp adapter for Chat SDK that receives signed Kapso webhooks, replies through Chat SDK threads, and supports WhatsApp-native messaging features: - **Text messages** — send and receive WhatsApp messages via Kapso - **Buttons/cards** — Chat SDK card buttons render as WhatsApp reply buttons - **Media** — send and receive images, video, audio, documents, and stickers - **Reactions** — add/remove reactions and handle inbound reaction events - **History** — fetch Kapso-backed message, contact, and conversation metadata - **Webhook verification** — validates Kapso `X-Webhook-Signature` deliveries | Feature | Support | | --- | --- | | Send/receive text | Yes | | Reply buttons | Yes, up to 3 | | CTA URL buttons | Yes | | Media attachments | Yes | | Reactions | Yes | | Message history | Yes | - **Docs**: [docs.kapso.ai](https://docs.kapso.ai/) - **npm**: [`@kapso/chat-adapter`](https://www.npmjs.com/package/@kapso/chat-adapter) - **GitHub**: [`gokapso/chat-sdk-adapter`](https://github.com/gokapso/chat-sdk-adapter) - **Blog**: https://kapso.ai/blog/chat-sdk-adapter |
||
|
|
9b99ee2d2d |
fix(docs): allow Velt adapter examples (#575)
## summary fixes the release-blocking docs validation failures from the Velt vendor-official adapter page this updates the docs integration-test allowlists so `velt` is an expected vendor-official adapter slug and `@veltdev/chat-sdk-adapter` is accepted in docs code examples no changeset needed because this only updates test expectations for existing docs content |
||
|
|
5a72259fbc |
feat(docs): improve LLM/search discoverability of docs (#566)
SEO/AEO improvements for the docs site: - Append `| Chat SDK` to every page's `<title>` and `og:title` (home stays `Chat SDK`). - Expose a plain-markdown version of every docs and adapter page via an `sr-only` AI/LLM hint link and a `text/markdown` alternate; adapter pages get a new `/adapters/<group>/<slug>.md` endpoint. - Turn `llms.txt` into a sitemap-style index linking to each page's markdown, and move the full-text concatenation to `llms-full.txt`. A `<link rel="llms-txt">` is added to every page. --------- Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> |
||
|
|
293356525d |
feat: docs: add Lark / Feishu adapter (#517)
## Summary Adds [`@larksuite/vercel-chat-adapter`](https://www.npmjs.com/package/@larksuite/vercel-chat-adapter), the Lark / Feishu adapter for Chat SDK, as a **vendor-official community adapter**. - **Package**: `@larksuite/vercel-chat-adapter` — published on npm under the official `larksuite` scope - **Built on**: [`@larksuiteoapi/node-sdk`](https://www.npmjs.com/package/@larksuiteoapi/node-sdk)'s `LarkChannel`, the official Lark Node SDK - **Docs source**: external README referenced by `adapters.json` lives in [`larksuite/node-sdk`](https://github.com/larksuite/node-sdk/tree/cbc4adf13cbcb93b389db01faf428e3b3cef053c/docs/vercel-chat-adapter) (the official Lark vendor-owned GitHub org, pinned at commit `cbc4adf1`); the in-tree MDX in this PR is the rendered detail page (`mdxBody: true`) - **Capabilities**: native cardkit typewriter streaming, interactive cards, reactions, edit / delete, message history (via SDK `normalize()`), DM detection, mention handling, and scan-to-create app onboarding through `registerLarkApp` ## Changes | File | Change | |---|---| | `apps/docs/adapters.json` | Add Lark / Feishu entry (`community: true`, `vendorOfficial: true`) | | `apps/docs/content/adapters/vendor-official/lark.mdx` | New hand-authored MDX detail page (frontmatter with full features matrix, install / quick start / configuration / transport / streaming / ID encoding / history / safety / limitations / FeatureSupport) | | `apps/docs/content/adapters/vendor-official/meta.json` | Append `"lark"` to the sidebar `pages` array | | `packages/integration-tests/src/docs-adapters.test.ts` | Append `"lark"` to the hardcoded vendor-official slug list asserted by `Vendor-Official adapter MDX › contains exactly the expected adapters` | No icon registered in `adapters.json` / `iconMap` / `adapterLogos` — matches the existing pattern for vendor-official adapters (Beeper, Resend, Liveblocks, Zernio, Photon). ## Vendor Official tier Per `docs/contributing/building.mdx` (Qualifications for vendor official tier): - ✅ **Commitment for continued maintenance** — owned by the Lark / Feishu team - ✅ **GitHub hosting in official vendor-owned org** — adapter README lives in [`larksuite/node-sdk`](https://github.com/larksuite/node-sdk), the official Lark org - ✅ **Documentation in primary vendor docs** — will be cross-linked from the official Lark Open Platform developer documentation - ✅ **Announcement** — will be announced through Lark developer changelog / channels ## A note on source visibility The adapter source is not currently open-sourced due to internal release-process requirements. What is public: - The npm package itself (consumable by any user) - The README, hosted in `larksuite/node-sdk` (official Lark org) - The underlying [`@larksuiteoapi/node-sdk`](https://github.com/larksuite/node-sdk) on which it is built — this *is* fully open-source ## Test plan - [x] `pnpm --filter docs build` — docs app builds cleanly; `/en/adapters/vendor-official/lark` and `/en/adapters/vendor-official/lark/og` routes are generated - [x] `pnpm typecheck` — passes (33 tasks) - [x] `pnpm check` (Ultracite / Biome) — 438 files, no fixes - [x] `pnpm --filter @chat-adapter/integration-tests test docs-adapters` — 232 tests pass (frontmatter, vendor-official roster, adapters.json ↔ MDX sync) - [x] Manual: `/adapters` lists the Lark / Feishu card in the **Vendor Official** section; `/adapters/vendor-official/lark` renders the MDX detail page with the FeatureSupport matrix |
||
|
|
bd38498b60 |
docs(adapters): add AgentPhone as vendor-official adapter (#562)
## Summary Adds [AgentPhone](https://agentphone.to) as a vendor-official adapter in `adapters.json`. AgentPhone is the first Chat SDK adapter with unified support for **SMS, MMS, iMessage, and voice calls** in a single package: - **SMS/MMS** — send and receive via `agent.message` webhooks - **iMessage** — full support including tapback reactions (love, like, laugh, etc.) and expressive send styles - **Voice** — inbound/outbound call transcripts and summaries via `agent.call_ended` webhooks - **HMAC-SHA256** webhook verification with replay protection | | SMS | MMS | iMessage | Voice | |---|---|---|---|---| | Send messages | ✓ | ✓ | ✓ | — | | Receive messages | ✓ | ✓ | ✓ | — | | Media attachments | — | ✓ | ✓ | — | | Reactions | — | — | ✓ | — | | Call transcripts | — | — | — | ✓ | - **npm**: [`@agentphone/chat-sdk-adapter`](https://www.npmjs.com/package/@agentphone/chat-sdk-adapter) - **GitHub**: [`AgentPhone-AI/chat-sdk-adapter`](https://github.com/AgentPhone-AI/chat-sdk-adapter) - **Docs**: [docs.agentphone.ai](https://docs.agentphone.ai) |
||
|
|
25ebc3b925 |
feat(twilio): add sms, mms, and voice helpers (#558)
## summary adds a first-class Twilio adapter for SMS and MMS bots, plus low-level voice helpers for custom Twilio voice routes this includes webhook parsing and signature verification, outbound Messages API helpers, phone-number and Messaging Service sending, inbound MMS attachments with authenticated `fetchData`, plain text card fallback rendering, markdown conversion, and runtime-light `api`, `webhook`, `voice`, and `format` subpaths the adapter intentionally avoids the `twilio` npm runtime dependency so apps can use the low-level helpers without pulling in the full SDK |
||
|
|
0488a6613c |
docs(slack): document low-level api subpaths (#557)
## summary documents the low-level Slack subpaths for custom runtimes that own routing, state, sessions, or workflow execution covers `@chat-adapter/slack/webhook`, `@chat-adapter/slack/format`, `@chat-adapter/slack/api`, and `@chat-adapter/slack/blocks`, including when to use them instead of the full `createSlackAdapter` runtime also links the new guide from the Slack adapter page |
||
|
|
ac8a20779c |
feat(chat): add chat/ai subpath for AI SDK utilities (#492)
## Summary
Introduces a dedicated `chat/ai` subpath as the home for every Vercel AI
SDK helper that ships with Chat SDK. Importing from this subpath keeps
the optional `ai` and `zod` peer dependencies out of bundles that don't
use them.
### What's new
- **`createChatTools`** — exposes Chat SDK operations as ready-to-use AI
SDK tools so an agent can read, post, react, edit, delete, and manage
thread subscriptions across every adapter the supplied `Chat` instance
has registered.
- Write operations require user approval by default (`requireApproval:
true`); toggle globally or per-tool.
- Three presets — `reader`, `messenger`, `moderator` — scope the
toolset.
- Individual tools can also be cherry-picked (`import { postMessage,
addReaction } from "chat/ai"`).
- **`toAiMessages`** (and the `Ai*` / `ToAiMessagesOptions` types) now
live alongside the tools at `chat/ai`. The previous `chat` re-exports
continue to work, but are flagged `@deprecated` with an editor hint
pointing to the new home — migration is a one-line import change.
- **Docs** — new `/docs/ai` section between Usage and Adapters in the
sidebar:
- `/docs/ai` — Overview
- `/docs/ai/ai-sdk-tools` — `createChatTools` guide
- `/docs/ai/to-ai-messages` — `toAiMessages` reference
- `/docs/ai/types` — Reference for every type exported from `chat/ai`
- **Example app** — `examples/nextjs-chat` now demos the new surface via
a "Run Agent Demo" button on the welcome card and a free-form `/agent
<prompt>` slash command (streaming, with a placeholder so users get
immediate feedback in channel contexts where Slack's typing-status API
is a no-op).
### Future plans
`createChatTools` currently exposes the cross-adapter Chat SDK surface
only. A natural follow-up is to also support **platform-specific tools**
— e.g. expose Slack-only `pin`/`unpin`, Discord-only thread archiving,
GitHub-only issue commenting, etc., so users can further extend what
their agent can do without dropping back to raw adapter calls. The shape
would likely be additional opt-in factories under `chat/ai` (or
per-adapter subpaths like `@chat-adapter/slack/ai`) that return tools
layered on top of the platform-specific adapter clients, while keeping
the cross-platform `createChatTools` API as the lowest common
denominator.
### Coverage
- `createChatTools` orchestrator: 100% statements / 94.7% branches.
- Every tool factory's `execute()` is exercised end-to-end (29 tests in
`index.test.ts`).
- `toAiMessages` keeps its existing 35-test suite covering role mapping,
attachment handling, links, transforms, and unsupported-attachment
fallbacks.
- Tools folder overall: 99.0% statements / 86.1% branches / 97.4%
functions / 98.9% lines.
---------
Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com>
Co-authored-by: dancer <josh@afterima.ge>
|
||
|
|
cd7b6af1c8 |
test(integration-tests): add Emulate.dev-backed tests for the GitHub adapter (#479)
## Summary Add an Emulate.dev-backed integration-test suite for the GitHub adapter, mirroring the structure of the Slack work in #477. Tests drive the adapter against an in-process [`@emulators/github`](https://emulate.dev/docs/github) server and assert on its stateful store (comments, reviews) rather than `mock.calls`, catching wire-format and contract issues that pure Octokit mocks miss. - New private devDeps in `packages/integration-tests`: `@emulators/github`, `@emulators/core`, `@hono/node-server`, plus a workspace dep on `@chat-adapter/github`. (`@emulators/core` and `@hono/node-server` are also declared by #477; this PR is independent of merge order.) - New harness `packages/integration-tests/src/github-emulator-utils.ts` boots the emulator on an ephemeral `127.0.0.1` port, seeds a deterministic user / repo / issue / PR / starter review comment, and exposes a near-passthrough HTTP forwarder. **No re-signing needed** here. `@emulators/core`'s `WebhookDispatcher` already signs deliveries with `X-Hub-Signature-256: sha256=<hex>` exactly as the GitHub adapter expects. The harness also adds a small URL rewriter for Octokit's `pulls.createReplyForReviewComment` shortcut endpoint, translating it into the canonical review-comment POST that the emulator implements. - Four new test files (12 tests), wired to the adapter via its existing `apiUrl` + `webhookSecret` config **zero source changes** to `packages/adapter-github`: - `emulator-github-auth.test.ts` (2) `GET /user` populates `botUserId` during `initialize()`. - `emulator-github-comments.test.ts` (4) `thread.post` / `edit` / `delete` on issue and PR-conversation threads. - `emulator-github-reviews.test.ts` (3) review-comment replies routed through `pulls.createReplyForReviewComment` with the right \`in_reply_to_id\`, plus edit / delete. - `emulator-github-events.test.ts` (3) full inbound `issue_comment` / `pull_request_review_comment` round-trip, including bot self-message filtering. ```mermaid flowchart LR subgraph Test["Vitest test process"] SDK[GitHubAdapter + Chat] Forwarder["HTTP forwarder<br/>passthrough"] Emu["@emulators/github<br/>(in-process Hono)"] end SDK -->|"issues.createComment / pulls.* / GET /user<br/>(apiUrl override)"| Emu Emu -->|"X-Hub-Signature-256 + x-github-event"| Forwarder Forwarder -->|"chat.webhooks.github(request)"| SDK ``` ### Out of scope (deliberate) - **Reactions** `@emulators/github` does not implement the `/reactions` endpoints used by the adapter. Reaction logic is still covered by the existing mock-based tests in `packages/adapter-github/src/index.test.ts`. - **GitHub App auth** (JWT \u2192 installation token via `POST /app/installations/:id/access_tokens`) the adapter and emulator both support it, but PAT-mode was the agreed scope here. - **Multi-tenant install flows** via `installation` webhook events. - Branches/refs, releases, search, actions, checks not used by the adapter. ## Test plan - [x] `pnpm --filter @chat-adapter/integration-tests test` 407 tests pass across 34 files (including the 12 new emulator-github tests, ~480 ms total). - [x] `pnpm check` and `pnpm knip` clean. - [x] CI safety verified: ephemeral ports (`port: 0`), loopback-only binds (`127.0.0.1`), deterministic teardown via `httpServer.close()`, no env vars, no external network egress. ## Checklist - [x] All commits are signed and verified - [x] \`pnpm validate\` passes - [x] Changeset added (or N/A see [CONTRIBUTING.md](./CONTRIBUTING.md)) N/A: \`@chat-adapter/integration-tests\` is \`private: true\` and the change is test-only. - [x] Documentation updated (or N/A) \`packages/integration-tests/README.md\` describes the new emulator-github test category. --------- Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> |
||
|
|
79227ae991 |
docs: refresh adapter pages with hand-authored MDX (#474)
## Summary
Refreshes the adapter docs end-to-end so every adapter — official,
vendor-official, and community — now ships hand-authored MDX, lives
under a clean URL structure, and renders on a polished
sidebar/right-rail layout dedicated to `/adapters` (the shared `/docs`
chrome is untouched).
```mermaid
flowchart LR
subgraph Before
direction TB
OB[official] --> CB[community<br/>incl. 5 vendor pages]
end
subgraph After
direction TB
OA[official] --> VA[vendor-official<br/>5 pages] --> CA[community]
end
Before -.-> After
```
### Content & routing
- **New `/adapters/vendor-official/<slug>` route** for vendor-maintained
adapters (Beeper Matrix, Photon iMessage, Liveblocks, Resend, Zernio).
Sidebar gets a third labelled group ("Vendor-Official Adapters") between
Official and Community, with a top divider matching the existing
Community treatment.
- **All 13 vendor-official + community adapters migrated** from runtime
README fetching to hand-authored MDX with rich `features:` matrices and
full body content (install, quick start, configuration, auth,
gateway/streaming, troubleshooting). README fetch stays as a fallback
for any future community adapter that hasn't been migrated yet, gated by
a new `mdxBody: true` frontmatter flag.
- **Messenger filter pages removed** (`/adapters/for/<messenger>` + the
"Browse by messenger" chip row on `/adapters`). Existing URLs
308-redirect to `/adapters`.
- **Permanent redirects** from
`/adapters/community/{matrix,imessage,resend,zernio,liveblocks}` to
their new `/adapters/vendor-official/...` paths.
- **Fixed** `/docs/adapters` and `/docs/state` so the bare pages are
accessible again — the previous catch-all redirect (`:slug*`) was
swallowing them. Switched to `:slug+` so subpath URLs still 308 while
the bare pages render.
### Visual polish
- **Adapter-only sidebar variant** (`AdaptersDocsLayout` +
`AdaptersSidebar`) with uppercase eyebrow separators, tighter rows, and
a thin themed scrollbar utility class. The shared `/docs` sidebar is
untouched.
- **Restyled `AdapterHero`**: drops the badges row + packageName, sits
the title inline with the logo, larger 17 px tagline, horizontal divider
beneath the block.
- **Restyled `PackageInstall`** as a tabbed dark single-line snippet
with a `$` prompt prefix and a copy button — replaces the previous
multi-line `CodeBlock` layout.
- **New "Deploy your chat app on Vercel" upsell card** (`<Upsell />`)
replaces the old `EditSource / ScrollTop / Feedback / CopyPage` footer
cluster on every adapter detail page.
- **Listing & messenger pages**: align the H1 to a tighter `text-4xl
sm:text-[44px]`, and the section headers to `text-base font-medium
tracking-tight` with a one-line muted lede.
### Tooling & tests
- Added `mdxBody: true` opt-in to the adapter frontmatter schema
(`source.config.ts`), and updated both detail-page handlers
(`community/[slug]` and the new `vendor-official/[slug]`) to render the
MDX body when present, falling back to README fetch otherwise.
- Refactored both detail-page handlers to flatten the body-render
branches into a `renderBody()` helper, removing the nested ternaries
that were tripping `lint/style/noNestedTernary`.
- New test file
[`packages/integration-tests/src/docs-adapters.test.ts`](https://github.com/vercel/chat/blob/docs/refresh-adapters/packages/integration-tests/src/docs-adapters.test.ts)
— **220 new assertions** covering:
- Adapter MDX frontmatter completeness, slug ↔ filename consistency, and
`type ∈ {platform, state}`.
- Vendor-official invariants: exactly the expected slugs,
`vendorOfficial: true`, `community: true`, `author`, `mdxBody: true`,
`<FeatureSupport />` rendered.
- Community invariants: `community: true` (never vendor-official),
`mdxBody: true`, `<FeatureSupport />`.
- Official invariants: never flagged, `packageName` always under
`@chat-adapter/*`.
- `adapters.json` ↔ MDX sync on `packageName` / `type` / `community` /
`vendorOfficial`.
- Extended `VALID_DOC_PACKAGES` so `docs-content.test.ts` accepts the
new vendor-official + community packages, plus `@chat-adapter/web`,
`@chat-adapter/web/react`, and `@chat-adapter/messenger`.
### Per-package AGENTS.md
- Added `AGENTS.md` to every official adapter and state adapter (14
packages), each tailored to that adapter's surface — overview, directory
layout, build/test commands, public exports, thread ID format, webhook
flow, authentication, format conversion, cards/streaming, platform
quirks, testing approach, coding conventions, and release rules.
- Added a one-line `CLAUDE.md` (`@AGENTS.md`) beside each so Claude Code
picks up the same instructions through its built-in resolver — same
convention as the root.
### Web adapter copy
- Cleaned up the Web adapter tagline (removed inline backticks) and
dropped the now-redundant "v1 scope" section from the body.
---------
Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com>
|
||
|
|
fdebde7988 |
Reapply "feat(slack): expose direct WebClient access via adapter.client" (#472) (#476)
This reverts commit
|
||
|
|
14b1434998 |
test(integration-tests): add Emulate.dev-backed tests for the Slack adapter (#477)
* chore(integration-tests): add Emulate.dev Slack emulator devDeps
Add @emulators/slack, @emulators/core, and @hono/node-server as
devDependencies of the private integration-tests package. These power
the upcoming in-process Slack emulator harness used to drive the Slack
adapter against a stateful, Slack-shaped HTTP server instead of mocks.
* test(integration-tests): add Slack emulator test harness
Introduce slack-emulator-utils.ts, a test-only helper that boots the
@emulators/slack Hono app on an ephemeral 127.0.0.1 port via
@hono/node-server and pre-seeds a deterministic team / channel / bot /
human user / OAuth app. The Slack adapter is wired to it via its
existing apiUrl config; no source changes required.
Also exposes startSlackWebhookForwarder, a tiny in-process Node http
forwarder that re-signs the emulator's outbound event_callback
deliveries with x-slack-signature / x-slack-request-timestamp before
handing them to chat.webhooks.slack(...). The emulator's core
WebhookDispatcher only emits GitHub-style X-Hub-Signature-256 headers,
so this bridge is what makes inbound flows exercise the SDK's real
HMAC verification path.
The handle returns direct access to the emulator's Store and
WebhookDispatcher so tests can assert on persisted state instead of
mock call records.
* test(integration-tests): cover Slack auth, postMessage, and reactions via emulator
Add three test files that drive the SlackAdapter's outbound WebClient
calls through the in-process emulator and assert on its stateful store
rather than on mock call records:
- emulator-slack-auth.test.ts (3 tests): auth.test populates botUserId
during initialize(); explicit botUserId is respected; multi-workspace
mode skips the call entirely.
- emulator-slack-post-message.test.ts (5 tests): plain text and threaded
thread.post round-trip into the messages collection and are visible
via conversations.replies; editMessage updates via chat.update;
deleteMessage removes via chat.delete; markdown posts succeed.
- emulator-slack-reactions.test.ts (3 tests): addReaction /
removeReaction round-trip via reactions.add / reactions.remove and
show up via reactions.get; multi-user reactions accumulate correctly.
These exercise the full HTTP path against a Slack-shaped server,
catching wire-format and contract issues that pure mocks miss.
* test(integration-tests): cover Slack inbound events and OAuth v2 install via emulator
Add two test files that drive end-to-end flows previously only
verifiable against real Slack:
- emulator-slack-events.test.ts (4 tests): a human posts to the
emulator, which dispatches an event_callback to the local forwarder,
which signs the body and hands it to chat.webhooks.slack(...). The
SDK's onNewMention and onNewMessage handlers run with a live Thread
and the bot's reply lands back in the emulator. Bot self-messages
are correctly filtered. This is the only Slack adapter test in the
repo that covers the full inbound-then-outbound round-trip without
hand-crafted webhook payloads.
- emulator-slack-oauth.test.ts (4 tests): handleOAuthCallback
exchanges a real authorization code via oauth.v2.access against the
emulator's authorize/callback flow; the resulting installation is
persisted in the state adapter; invalid codes and mismatched
client_secrets are rejected; the freshly issued bot token works for
subsequent chat.postMessage calls via withBotToken.
* docs(integration-tests): document emulator-* test category
Add an "Emulator tests" entry to the package README so newcomers can
distinguish the new emulator-backed suite from the existing unit and
replay tests, and find the harness in slack-emulator-utils.ts.
* fix(integration-tests): keep full token scopes after emulator.reset()
`applyTokenSeed` (used during `reset()`) was granting only
["chat:write", "channels:read"] to seeded tokens, while the initial
`createCoreServer({ tokens })` call granted the full bot/human scope
sets. After the first `reset()` the bot token silently lost
`channels:history`, `users:read`, `reactions:read`, and
`reactions:write`, which would surface as flaky behaviour for any test
that relied on those scopes after a reset.
Unify both call sites on a single `buildTokenSeedEntries` helper so
fresh-boot and post-reset state always grant the same scopes. Add a
regression test in emulator-slack-auth.test.ts that triggers a manual
`emulator.reset()` and re-asserts that the bot token still resolves
via auth.test.
* refactor(integration-tests): reorganize Slack emulator tests under emulator/slack/
Address review feedback (visyat) by moving the flat
`emulator-slack-*.test.ts` files into a per-adapter directory:
packages/integration-tests/src/emulator/slack/
utils.ts
auth.test.ts
events.test.ts
oauth.test.ts
post-message.test.ts
reactions.test.ts
This scales cleanly as more adapter emulator suites land (e.g.
`emulator/github/`), instead of cluttering the top-level src tree with
adapter-prefixed file names.
Also hoist the duplicated `silentLogger` definition from each test
file into the shared `utils.ts`, removing five identical copies.
No behavior changes. All 20 emulator tests still pass.
* test(integration-tests): cover Slack multi-workspace token resolution via emulator
Add `emulator/slack/multi-workspace.test.ts` exercising the path that
was previously only covered by replay/mock-based tests: the adapter
runs without a hardcoded `botToken`, multiple workspaces are persisted
in the state adapter via `adapter.setInstallation(teamId, ...)`, and
inbound `event_callback`s for either team are routed to the correct
per-tenant bot token end-to-end against the shared emulator.
To make this work, the helper grew two small additions:
- `addEmulatorWorkspace(emulator, seed)` — register an additional
team + bot + channel + token on an already-booted emulator, so two
tenants live side-by-side without needing two emulator instances.
- The inbound forwarder's `augmentEventEnvelope` now accepts an
optional `resolveTeamId(envelope)` callback, defaulting to a constant
teamId for the existing single-workspace tests. The multi-workspace
test passes a resolver that looks up the dispatched event's channel
in the emulator store and returns the owning team's id, so the SDK's
per-team token resolver sees the right `team_id` on the envelope.
Three new tests: team-A routing, team-B routing, and `getInstallation`
returning null for unknown team ids. Follow-up from review feedback on
PR #477.
---------
Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com>
|
||
|
|
2279f1db70 |
Revert "feat(slack): expose direct WebClient access via adapter.client" (#472)
* Revert "feat(slack): expose direct WebClient access via adapter.client (#471)"
This reverts commit
|
||
|
|
8366b8b0fb |
feat(slack): expose direct WebClient access via adapter.client (#471)
* feat(slack): expose direct WebClient access via adapter.client
Mirror the Linear and GitHub adapter pattern by exposing the underlying
@slack/web-api WebClient as `adapter.client` for any Web API call not
covered by the SDK's high-level methods.
Resolution order:
1. Token from the current request context (multi-workspace webhooks,
`withBotToken()`).
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. For both,
bind the token explicitly with `adapter.withBotToken(token, () => ...)`.
Internally, the existing private `client` field is renamed to `_client`
so the public getter can return per-token cached `WebClient` instances.
All internal API calls continue to route through `_client.foo(await
this.withToken(...))` unchanged. Also fixes `createSlackAdapter()`
silently dropping the `apiUrl` config field, surfaced by the new
apiUrl-propagation test.
* docs(slack): document direct WebClient access
Add Slack to the "Direct client access" section of the chat-sdk.dev
docs (api/chat.mdx, usage.mdx) alongside Linear and GitHub. Update the
multi-tenant Callout to spell out both Slack constraints — request
context required in multi-workspace mode, and `withBotToken()` required
when `botToken` is an async resolver.
Add a parallel "Direct WebClient access" section to the Slack adapter
README with a usage example, the token resolution order, and the
async-resolver workaround.
* feat(example): add Channel Info button using slack.client
Demonstrate the new direct WebClient access pattern in the nextjs-chat
demo with a "Channel Info (Slack)" button. The handler resolves the
Slack adapter from the action event, reaches into
`adapter.client.conversations.info` (channels:read scope, already in
the example manifest), and renders the result as a Card with channel
name, member count, topic, purpose, and the standard flags. Falls back
to a friendly message on non-Slack platforms.
* feat(example): add Pin Message button using slack.client.pins.add
Pin the welcome card itself via `adapter.client.pins.add({ channel,
timestamp: event.messageId })` to demonstrate calling a Slack Web API
endpoint not wrapped by the SDK. Adds the required `pins:write` scope
to the example Slack manifest.
* chore(example): render channel info as a table and include num_members
Replace the Fields/Section layout in the Channel Info card with a
two-column Table for a tidier presentation, and pass
`include_num_members: true` so the Members row is actually populated
(Slack's `conversations.info` omits it by default).
* test(slack): expand coverage for adapter.client
Adds three tests:
- Cache differentiation: distinct tokens produce distinct WebClient
instances so per-workspace credentials never bleed across calls.
- apiUrl env var resolution: SLACK_API_URL is honored by the WebClient
the new getter returns (covers GovSlack-style deployments).
- End-to-end multi-workspace token routing: a real block_actions
webhook drives `processAction`, and the handler-side
`event.adapter.client.token` matches the installation's bot token —
proving the request-context-bound client works inside webhook
dispatch.
---------
Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com>
|
||
|
|
0adf3adef6 |
feat(tests): add @chat-adapter/tests test kit (#470)
* feat(tests): add @chat-adapter/tests test kit
New package providing Vitest factories, custom matchers, and a setup file for
people building Chat SDK adapters and bots.
Factories: createMockAdapter, createMockChatInstance, createMockState (with
working in-memory subscriptions/locks/KV/queues), createTestMessage,
mockLogger / createMockLogger.
Matchers: toHavePosted(threadId, textPattern?), toHaveDispatched(handler),
toBeSubscribedTo(threadId). Auto-register via the
'@chat-adapter/tests/setup' subpath in vitest 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.
* test(integration-tests): allow @chat-adapter/tests imports in README check
* docs: add Testing page covering @chat-adapter/tests
New content/docs/testing.mdx walks bot authors and custom-adapter authors
through the kit's factories, custom matchers, and setup file. Added under
the Usage section in the sidebar, after error-handling.
Cross-link from contributing/testing.mdx clarifying that the hand-rolled
patterns there are for repo contributors building first-party adapters,
while consumers of Chat SDK should use @chat-adapter/tests.
* test(integration-tests): allow @chat-adapter/tests imports in docs check
* fix(tests): match real Adapter.postMessage signature in toHavePosted
Adapter.postMessage is (threadId: string, message: AdapterPostableMessage)
— previously the matcher read args[0] as { id: string } and args[1] as
{ text: string }, neither of which match the actual SDK shape. The matcher's
own tests fed the same wrong shape into the mock so they passed locally
while the matcher silently failed against any real bot or adapter.
Now compares args[0] as a string threadId, and extracts a comparable string
from AdapterPostableMessage's union — strings directly, PostableMarkdown
.markdown, PostableRaw.raw, and PostableCard.fallbackText. PostableAst and
fallback-less cards aren't text-matchable; documented in the JSDoc.
Tests updated to call postMessage with the real signature and to cover
each comparable AdapterPostableMessage shape.
* test(tests): add smoke tests driving matchers against a real Chat
Construct a real `Chat` with a `createMockAdapter` + `createMockState` and
exercise `Chat.thread().post()` and `.subscribe()` end-to-end. The matchers
(toHavePosted, toBeSubscribedTo) then assert against the actual call shape
the SDK uses, so a future signature drift breaks here instead of silently
agreeing with whatever wrong shape lives in the unit tests.
This is the regression guard for the postMessage-shape bug fixed in the
prior commit: each new matcher in subsequent PRs should be paired with a
smoke case here.
* feat(tests): round out adapter mutation matchers
Adds toHaveEdited, toHaveDeleted, toHaveReactedWith, toHaveStartedTyping,
and toHavePostedToChannel — covering the common Adapter mutation surface
that bot authors assert on. Each matcher's signature was checked against
packages/chat/src/types.ts, and each is paired with a smoke case that
drives a real Chat through the corresponding Thread/Channel API so
signature drift breaks the smoke test instead of silently agreeing with
the unit tests.
Emoji matching accepts both plain strings and EmojiValue ({ name }).
Text matching reuses the same extraction rules as toHavePosted —
strings, PostableMarkdown.markdown, PostableRaw.raw, and
PostableCard.fallbackText. Documented in matcher JSDoc, README, and
the Testing docs page.
---------
Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com>
|
||
|
|
c1cd9b5da1 |
feat(chat): add callbackUrl to buttons and modals (#454)
* 1 * wfw * 4224 * dfe * wip * f * 22 * tsts * more * ch * dc * t * tm * docs * ex * k * cs * lock * test(chat): expand callbackUrl coverage * docs: document callbackUrl handling for adapter authors * docs: expand changeset for callbackUrl feature * docs(skill): mention callbackUrl on Button and Modal * feat(example): add modal callbackUrl workflow demo * test(integration): add replay tests for callbackUrl flows --------- Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> |
||
|
|
68025ca965 |
[messenger] add messenger (meta) platform adapter to chat sdk (#461)
* [messenger] add messenger (meta) platform adapter to chat sdk - Webhook handling with HMAC-SHA256 signature verification - Generic and Button template support for cards - Postback, reaction, delivery/read confirmation handling - Message caching for fetchMessages (Messenger has no history API) - Replay tests and ~98% code coverage Co-authored-by: Dimitar K. Nikolov <mitkodkn@users.noreply.github.com> Co-authored-by: Ben Sabic <27636870+bensabic@users.noreply.github.com> Co-authored-by: Cursor <cursoragent@cursor.com> * Fix: The `@chat-adapter/messenger` package version is `4.15.0` while all other packages in the Changesets fixed version group are at `4.27.0`, breaking the fixed versioning contract. This commit fixes the issue reported at packages/adapter-messenger/package.json:3 **Bug explanation:** The repository uses Changesets with a `"fixed"` configuration: `[["chat", "@chat-adapter/*"]]`. This means all packages matching these patterns must always share the same version number. Every package in the group (`chat`, `@chat-adapter/discord`, `@chat-adapter/gchat`, `@chat-adapter/github`, `@chat-adapter/linear`, `@chat-adapter/shared`, `@chat-adapter/slack`, `@chat-adapter/teams`, `@chat-adapter/telegram`, `@chat-adapter/web`, `@chat-adapter/whatsapp`, and the state packages) is at version `4.27.0`, except `@chat-adapter/messenger` which is at `4.15.0`. This is likely because the messenger adapter was newly added to the monorepo (copied from a template or created fresh) and its version was never aligned with the rest of the fixed group. This mismatch will cause problems with the Changesets release workflow — when Changesets tries to bump versions for the fixed group, it may produce inconsistent or errored releases because one package is 12 minor versions behind the others. **Fix explanation:** Changed `"version": "4.15.0"` to `"version": "4.27.0"` in `packages/adapter-messenger/package.json` to align it with all other packages in the fixed version group. Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com> Co-authored-by: visyat <vishal.yathish@gmail.com> * Fix: Messenger adapter env var guard only checks `FACEBOOK_APP_SECRET` but `createMessengerAdapter` requires all three env vars, causing a `ValidationError` crash at Next.js build time when only `FACEBOOK_APP_SECRET` is set. This commit fixes the issue reported at examples/nextjs-chat/src/lib/adapters.ts:154 **Bug Analysis:** The build failure is confirmed in the Vercel build log with: ``` Error [ValidationError]: pageAccessToken is required. Set FACEBOOK_PAGE_ACCESS_TOKEN or provide it in config. ``` The root cause is in `examples/nextjs-chat/src/lib/adapters.ts` at line ~154. The messenger adapter guard only checks for `FACEBOOK_APP_SECRET`: ```typescript if (process.env.FACEBOOK_APP_SECRET) { ``` However, `createMessengerAdapter` (in `packages/adapter-messenger/src/index.ts`) validates and throws `ValidationError` for each of three required env vars: `FACEBOOK_APP_SECRET`, `FACEBOOK_PAGE_ACCESS_TOKEN`, and `FACEBOOK_VERIFY_TOKEN`. When only `FACEBOOK_APP_SECRET` is set in the Vercel project environment, the guard passes, `createMessengerAdapter` is called, and it throws a `ValidationError` for the missing `FACEBOOK_PAGE_ACCESS_TOKEN`. Since this code runs at module evaluation time during the Next.js build's "Collecting page data" phase, the uncaught error crashes the entire build. This is inconsistent with other adapters in the same file. For example, the WhatsApp adapter checks both `WHATSAPP_ACCESS_TOKEN` and `WHATSAPP_PHONE_NUMBER_ID`, and the gchat/github/linear/whatsapp adapters all wrap creation in try-catch blocks. **Fix:** 1. Updated the env var guard to check all three required environment variables (`FACEBOOK_APP_SECRET`, `FACEBOOK_PAGE_ACCESS_TOKEN`, and `FACEBOOK_VERIFY_TOKEN`) before attempting to create the adapter. 2. Wrapped the `createMessengerAdapter` call in a try-catch block (matching the pattern used by gchat, github, linear, and whatsapp adapters) so that any unexpected validation errors are caught and logged as warnings instead of crashing the build. Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com> Co-authored-by: visyat <vishal.yathish@gmail.com> --------- Co-authored-by: Dimitar K. Nikolov <mitkodkn@users.noreply.github.com> Co-authored-by: Ben Sabic <27636870+bensabic@users.noreply.github.com> Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com> Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com> |
||
|
|
3490a8c84c |
feat: add @chat-adapter/web — browser chat UI for chat-sdk bots (#444)
* feat(chat): expose awaitable Promise from processMessage
Return the inner task as Promise<void> instead of void so streaming
adapters can await full handler completion and surface user-handler
rejections at the wire level. waitUntil semantics for existing webhook
adapters are unchanged — the SDK still tracks the work with errors
swallowed (and logged) so platforms don't retry on handler bugs.
Required by @chat-adapter/web, whose response body is the user
handler's stream.
* feat(adapter-web): add @chat-adapter/web package
A new platform adapter that lets a chat-sdk bot serve a browser chat
UI alongside Slack/Teams/Discord/etc. without writing any client-side
glue. Speaks the AI SDK UI message stream protocol, so @ai-sdk/react's
useChat and the ai-elements component library work out of the box.
- `@chat-adapter/web` — server: createWebAdapter({ userName, getUser })
- `@chat-adapter/web/react` — client: useChat() preconfigured with
DefaultChatTransport against /api/chat (override via `api`)
Defaults that matter for v1:
- `isDM: true` — every web message routes through onDirectMessage
- `persistMessageHistory: true` — chat-sdk caches each turn in the
configured state adapter so handlers can read prior context via
thread.messages / channel.messages (no platform history API exists)
- channelId === threadId — web has no separate channel concept; this
prevents cross-conversation bleed when a single user has multiple
useChat sessions
- Native `adapter.stream` implementation pumps text-deltas straight
onto the SSE response — no post+edit fallback
Out of scope for v1: cards/JSX rendering, reactions, modals, file
uploads, edit/delete, multi-tab proactive push.
* feat(example-nextjs-chat): wire up web adapter and add /chat page
- Register the web adapter in lib/adapters.ts with a demo getUser
(single shared identity — replace with NextAuth/Clerk/cookie auth
in production)
- Expose POST /api/chat backed by bot.webhooks.web (using next/after
for waitUntil)
- Add a minimal /chat page using @chat-adapter/web/react's useChat —
same bot.onDirectMessage handler that powers Slack now powers the
browser too
Bumps `ai` to ^6.0.174 to align with @ai-sdk/react@^3 (avoids dual
provider-utils versions in the workspace).
* docs: list @chat-adapter/web in registry
- Add an entry to adapters.json so the package shows up on /adapters
- Add a globe SVG to lib/logos.tsx and wire it into the icon map
- Mention the new adapter in docs/adapters.mdx
* feat(adapter-web): tighten request handling and message construction
- Reject user ids containing ':' with HTTP 400 — the character would
corrupt the thread-id round-trip through decodeThreadId
- Skip emitting text-start/text-end in postMessage when the resolved
text is empty so useChat doesn't render blank assistant bubbles
- Derive the parseMessage author from raw.role so rehydrated assistant
messages report the bot identity instead of "unknown"
- Drop the duplicate handler-error log; chat.processMessage already
logs at ERROR level
- Document the actual persistMessageHistory default (true) and the
state-cache rationale; promote the fetchMessages no-op rationale
into its JSDoc
* test(adapter-web): add direct coverage for stream()
- Aborting request.signal mid-stream short-circuits the iterator and
still writes text-end via the finally block
- Non-text StreamChunks (task_update, plan_update) are dropped without
emitting any delta
- The SentMessage returned from thread.post matches the id used in
text-start / text-end events
* docs(adapter-web): expand README into the full adapter docs page
The docs site renders each adapter's README, so flesh out
@chat-adapter/web to match the depth of @chat-adapter/slack:
authentication boundary, threading semantics, streaming,
persistence, React hook reference, configuration table,
feature matrix, and troubleshooting.
* docs(adapter-web): drop unsupported provider import from streaming example
* fix(adapter-web): validate conversationId for reserved colon character
* fix(example): show error state in web chat demo
* fix(example): add thinking indicator to web chat demo
* feat(example): redesign web chat demo with tailwind
* chore: remove redundant changeset
---------
Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com>
Co-authored-by: dancer <josh@afterima.ge>
|
||
|
|
3546b3fddb |
feat(slack): use native markdown_text for outgoing messages (#440)
* feat(slack): use native markdown_text field for outgoing messages
Slack now natively renders markdown via the `markdown_text` parameter on
chat.postMessage / postEphemeral / update / scheduleMessage and via
response_url payloads. The adapter passes markdown through directly instead
of converting to mrkdwn.
- Tables, headings, code fences, blockquotes, and nested lists render
natively in Slack instead of falling back to ASCII / mrkdwn.
- `string` and `{ raw }` messages still go to `text` (preserves literal `*`).
- `{ markdown }` and `{ ast }` messages go to `markdown_text` (12k char limit).
- `renderWithTableBlocks`, `toBlocksWithTable`, `mdastTableToSlackBlock`,
and the AST→mrkdwn renderer (`fromAst` / `nodeToMrkdwn`) are removed.
- `SlackMarkdownConverter` alias is removed; use `SlackFormatConverter`.
- `renderFormatted(ast)` now returns standard markdown (was mrkdwn).
- Incoming `message` events still arrive as mrkdwn and are parsed unchanged.
Net -473 lines across markdown.ts and the five sender call sites.
* fix(slack): use mrkdwn fallback for response_url edits
|
||
|
|
9824d3335e |
Adapter hardening pass (#441)
* Adapter hardening pass * chore: remove redundant changeset --------- Co-authored-by: dancer <josh@afterima.ge> |
||
|
|
8a0c7b308d |
[chat] fix Slack streaming team ID for interactive payloads (#330)
* [chat] fix Slack streaming team ID for interactive payloads * chore: downgrade changeset to patch --------- Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> |
||
|
|
ed46bae52e |
feat(adapter-teams): native streaming for DMs via emit (#416)
* feat(adapter-teams): use native Teams SDK streaming for DMs Use ctx.stream.emit() from the Teams SDK for DM streaming instead of manual post+edit. This sends proper typing activities with streamType channelData, giving the native streaming UI in Teams. - Capture IStreamer from activity context in handleMessageActivity - Block handler with deferred promise so stream stays alive during processing - streamViaEmit() for DMs: uses stream.emit() with incremental text deltas - Group chats: accumulate full response and post as single message (no flicker) - Handle StreamCancelledError and stream.canceled for graceful cancellation Co-Authored-By: Claude <noreply@anthropic.com> * fix(tests): update Teams streaming assertions for accumulate-and-post Group chats now accumulate streamed chunks and post as a single message instead of post+edit, so assertions should check sentActivities not updatedActivities. * style: format replay-streaming test * chore: add changeset for teams native streaming --------- |
||
|
|
2531e9cff5 |
feat(slack): dynamic botToken resolver and custom webhookVerifier (#421)
* feat(slack): dynamic botToken resolver and custom webhookVerifier Allow `botToken` to be a function returning `string | Promise<string>` so apps can rotate or lazily fetch tokens; the resolver is invoked per API call. Add `webhookVerifier: (request) => string | Promise<string>` as an alternative to `signingSecret` for custom request verification — returns the verified body text or throws to produce a 401. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * change verifier signature to make it compatible with function * make scheduleMessage cancel() rotation-safe and honor verifier body - scheduleMessage cancel(): re-resolve token in single-workspace mode so rotation works. Slack rotated tokens have a 12h TTL and scheduled messages can outlive their schedule-time token, leaving cancel() with stale auth. Multi-workspace still snapshots ctx.token since cancel() runs outside the AsyncLocalStorage frame. - webhookVerifier: when it returns a string, use it as the verified body for downstream parsing. JSDoc previously implied this contract; the code only checked truthiness. - webhookVerifier JSDoc: explicit SECURITY note that timestamp/replay protection is the implementer's responsibility when bypassing signingSecret. - Tests: cover Attachment.fetchData snapshot semantics — multi-workspace uses the ctx token captured at attachment creation; single-workspace re-resolves the default provider per fetch (rotation-safe). * docs(slack): document botToken resolver and webhookVerifier in README * opt out of SLACK_SIGNING_SECRET env fallback when webhookVerifier is set A webhookVerifier passed in config was being silently shadowed by SLACK_SIGNING_SECRET in the env (read by both createSlackAdapter and the SlackAdapter constructor). An explicit verifier now opts out of that fallback in both code paths. Added a regression test that stubs the env var via vi.stubEnv. * register handleReactionEvent's outer promise via waitUntil handleReactionEvent does async work (conversations.replies, users.info) before delegating to chat.processReaction, which is the only point that registers a waitUntil task. The outer prep work was untracked, so callers that drained waitUntil tasks could complete before the reaction handler finished — flaky in CI under tight microtask scheduling. Track the outer promise too so the full handler is awaited. * fix(integration-tests): drain waitUntil cascade in test tracker --------- Co-authored-by: dancer <josh@afterima.ge> |
||
|
|
e8c4b1a6c4 |
docs: update adapter docs (#412)
* docs: update adapter docs * docs: update adapter docs * docs: update adapter docs --------- Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> |
||
|
|
0f8b2b150b |
[slack] [bug] preserve self mentions in multi-workspace installs (#355)
* [slack] preserve self mentions in multi-workspace installs * add changeset for slack multi-workspace self-mention fix --------- Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> |
||
|
|
4cc87dd888 | [gchat] [bug] render markdown links with Google Chat custom link syntax (#356) | ||
|
|
097c9b4630 |
[chat] adding plan/update plan blocks for threads (#115)
* [chat] adding plan/update plan blocks for threads * refactor plan impl into its own file * thread.post() instead of thread.postPlan() * fixes * lint fixes * refactor postable objects * knip * Refactor PostableObject into dedicated module and add fallback support (#191) * feat: refactor adapter-slack and types based on Malte's comments Move PostableObject to dedicated file, update type exports, add fallback posts, and make PostableObject generic. Slack-Thread: https://vercel.slack.com/archives/C0977L169MW/p1772755978706959?thread_ts=1772755978.706959&cid=C0977L169MW Co-authored-by: Vishal Yathish <135551666+visyat@users.noreply.github.com> * fix: fallback path for PostableObject and clean up exports - Plan mutations (addTask, updateTask, complete) now work in fallback mode by using editMessage with fallback text instead of no-oping - Revert Slack adapter to throw on unsupported kinds (caller handles fallback, so adapter-level fallback strings are unnecessary) - Remove redundant re-exports of isPostableObject/PostableObject from plan.ts — export from canonical postable-object.ts only - Stop exporting POSTABLE_OBJECT symbol (internal implementation detail) - Fix nested ternary lint error in getFallbackText - Add tests for fallback post/edit path Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: v0 <v0[bot]@users.noreply.github.com> Co-authored-by: Hayden Bleasel <hello@haydenbleasel.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fall back to plain text instead of throwing for unsupported postable object kinds Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor(chat): deduplicate PostableObject handling, improve type safety and test coverage --------- Co-authored-by: v0 <v0[bot]@users.noreply.github.com> Co-authored-by: Hayden Bleasel <hello@haydenbleasel.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: dancer <josh@afterima.ge> |
||
|
|
a0f508eee6 |
Migrate from BotFramework to TeamsSDK (#302)
* Migrate Teams adapter from botbuilder to @microsoft/teams.apps
Replace botbuilder/botframework-connector with @microsoft/teams.apps (TeamsSDK v2.0.6).
Breaking changes:
- Remove certificate auth (TeamsAuthCertificate) — use token or managedIdentityClientId instead
- Env vars changed: TEAMS_APP_ID → CLIENT_ID, TEAMS_APP_PASSWORD → CLIENT_SECRET, TEAMS_APP_TENANT_ID → TENANT_ID
- Reactions now work (addReaction/removeReaction) instead of throwing NotImplementedError
- Graph API calls use @microsoft/teams.graph-endpoints typed endpoints
Key changes:
- BridgeHttpAdapter captures TeamsSDK route handler for serverless dispatch
- Event handlers registered via app.on() (message, messageReaction, card.action, conversationUpdate, installationUpdate)
- Outbound calls use app.send() and app.api.conversations.activities()
- Stream support via post+edit (native HttpStream when SDK exports it)
- Graph API uses typed endpoints from @microsoft/teams.graph-endpoints
- isMention detection via activity entities instead of bot name matching
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Align TeamsAdapterConfig with AppOptions from TeamsSDK
- Replace custom config fields with Pick<AppOptions, ...>
clientId (was appId), clientSecret (was appPassword), tenantId (was appTenantId)
- Remove TeamsAuthFederated, appType — use managedIdentityClientId directly
- Constructor passes config through to App (App handles env var resolution)
- Use this.app.id instead of this.config.appId for bot identity checks
- 3 replay-fetch-messages tests have known failures (type shape mismatch)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Remove api() getter, add handler type safety
- Remove useless private api() getter, use this.app.api directly
- Type handlers with specific activity types:
handleMessageActivity(ctx: IActivityContext<IMessageActivity>)
handleAdaptiveCardAction(ctx: IActivityContext<IAdaptiveCardActionInvokeActivity>)
handleReactionFromContext(ctx: IActivityContext<IMessageReactionActivity>)
- Remove unnecessary casts now that ctx.activity is properly typed
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Revert bot.tsx example changes from migration branch
Keep Azure OpenAI and DM handler changes as local-only, not part of the migration.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Revert example package.json from migration branch
Keep only adapters.ts config changes, revert package.json dep changes.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Remove unrelated skill files from migration branch
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix
* Update README for TeamsSDK migration
- New env vars: CLIENT_ID, CLIENT_SECRET, TENANT_ID
- New config: clientId, clientSecret, tenantId, token, managedIdentityClientId
- Remove certificate auth docs (dropped)
- Reactions now supported (add/remove)
- Typing indicator now supported
- Graph API uses @microsoft/teams.graph-endpoints
- Note streaming and modals status
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Revert "Update README for TeamsSDK migration"
This reverts commit
|
||
|
|
27b34e153b |
fix(chat): use adapter to parse channel id (#286)
* fix(chat): use adapter to parse channel id * test: fix cases use adapter to parse channel id * chore: update changeset |
||
|
|
8337173704 |
Programmatically ensure that SKILL.md is always up-to-date and compiles (#272)
* Update the SKILL.md and add a test that checks its consistency * Refactor docs test * Typed and knip |