Summary
Backlog issue, not a PR. Upstream 4.32–4.41 added platforms and opt-in adapter modes no current consumer uses. Each is recorded with reason, effort and prerequisites so the 4.41 sync lists them as known non-parity, not silent gaps. An item becomes its own issue only when a consumer asks.
Upstream changes
2a2b2c55 feat(instagram): add native DM adapter (#770) — chat@4.37.0 — new @chat-adapter/instagram: about 1.7k src LOC and 27 tests.
0ec6a736 feat(notion): add Notion comments adapter (#689) — chat@4.37.0 — new @chat-adapter/notion: about 2.3k src LOC and 69 tests.
06b04ac4 Add Vercel Connect support to Notion (#812) — chat@4.38.0 — token resolver function and Connect setup.
ef2542c5 feat(x): add X (Twitter) adapter (#682) — chat@4.33.0 — posts, mentions and DMs over raw REST, with a CRC challenge and OAuth2 refresh.
4bca64f0 feat(x): support image uploads on posts and DMs (#700) — chat@4.34.0 — chunked media upload.
b6749238 fix(x): harden CRC challenge token validation (#775) — chat@4.37.0 — validates the shape of the CRC token before signing it.
caa63253 feat(x): add XChat encrypted messaging support (#745) — chat@4.36.0 — E2E-encrypted x/chat built on WASM chat-xdk + juicebox-sdk.
fe4ed11e docs: add XChat branding and clarify X vs XChat adapters (#777) — chat@4.37.0 — docs only.
043386b5 feat(telegram): add Business mode support (#888) — chat@4.40.0 — opt-in business connections and telegram:biz:{conn}:{chat} thread ids (index.ts +417/−70, +909 test lines).
75cadbf9 feat(twilio): add RCS support for interactive inbound and rich outbound (#590) — chat@4.39.0 — Content API templates, button actions, locations and channel inference (about 2.4k lines).
7a1150ce Add Vercel Connect support to Telegram (#813) — chat@4.38.0 — botToken may be a function, resolved on every Bot API call.
4115c943 feat(linear): add Vercel Connect support (#649) — chat@4.33.0 — access-token function, webhookVerifier, and Connect-mode installs.
961cf454 Recommend agent sessions for Linear Connect bots (#931) — chat@4.41.0 — an info log plus scaffolding.
a0cba028 Add Vercel Connect support to Discord (#808) — chat@4.38.0 — botToken / applicationId functions and a custom webhookVerifier in place of Ed25519.
Current Python behavior
ls src/chat_sdk/adapters/: 10 adapters, no instagram, notion or x. grep -rniE 'instagram|notion|xchat|juicebox' src returns nothing.
- Telegram:
grep -rni business src/chat_sdk/adapters/telegram returns nothing. bot_token is string-only (src/chat_sdk/adapters/telegram/adapter.py:653).
- Twilio:
grep -rniE 'rcs|content_sid|ButtonPayload' src/chat_sdk/adapters/twilio returns nothing. cards.py is 16 lines. _render_postable_text (adapter.py:596-599) renders an actions-only card to empty text.
- Linear requires
webhook_secret (src/chat_sdk/adapters/linear/adapter.py:354-358). Discord requires public_key (src/chat_sdk/adapters/discord/adapter.py:110-114). Neither has a webhook_verifier. The only precedent is Slack (src/chat_sdk/adapters/slack/adapter.py:305-354).
Scope
Instagram DM adapter — defer, M (~700–900 LOC)
Structurally Messenger, which Python already has (messenger/adapter.py: verify handshake :291, signature :308, stream :585, message cache :948, Graph fetch :1012). Factor out a shared Meta base. Differences: the graph.instagram.com base URL, object == "instagram", a 1000-byte limit, window-error codes, edit/delete/reactions raising, and downloads restricted by a CDN host allowlist. Prereq: #204.
Notion comments adapter — defer, L (~1.2–1.5k LOC + 69 tests)
Plain REST plus HMAC (X-Notion-Signature: sha256=…, compared with hmac.compare_digest), a one-time verification-token handshake, claim/release event dedupe, a file-upload poll and a rate limiter. Prereqs:
X (Twitter) adapter — defer, L (~2.1k upstream LOC for the root adapter)
Portable (raw REST + CRC HMAC challenge); the paid Account Activity API tier limits who can use it. Port b6749238's CRC validation from day one. Prereq: move the token crypto helpers out of slack/crypto.py:28,57,88 into chat_sdk/shared rather than cross-adapter imports. OAuth2 refresh tokens are single-use: make refresh single-flight (asyncio.Lock or cached asyncio.Task).
XChat — skip
E2E crypto, signing and PIN-based key recovery all live in WASM chat-xdk + juicebox-sdk. On 2026-09-29, pypi.org/pypi/{chat-xdk,juicebox-sdk,juicebox}/json all returned 404; only xdk exists. Porting would need wasmtime-py embedding or PyO3 bindings: out of proportion to demand.
Telegram Business mode — defer, L
Opt-in, niche. Needs a telegram:biz:{conn}:{chat} decode branch; business_connection_id on every send, edit, typing, upload and callback; a 1h connection cache that ignores connections unless is_enabled and can_reply; echo dropping; deleteBusinessMessages; reactions raising NotImplementedError; and explicit polling allowed_updates. Prereq: #227, because it changes the polling loop.
Twilio RCS — defer, XL (split into Content API client / outbound / inbound actions+location if promoted)
Content API get-or-create templates with SMS fallback, ButtonPayload → process_action, geo: attachments, channel inference and the TWILIO_RCS_SENDER_ID env var. Template-resolution failures fall back to text. Send failures must propagate instead of retrying as text, to avoid duplicate sends. Prereq: #235.
Vercel Connect hooks: Linear, Discord, Telegram, Notion — defer, S–M each
Vercel-hosted credential callables plus a custom webhook_verifier. Follow the Slack precedent: reject non-callables at construction; the verifier takes precedence over the secret, and a string return replaces the body; callables may be sync or async (inspect.isawaitable) and are resolved on every call; any retained native check keeps hmac.compare_digest. Discord's application_id resolves once and is memoized behind a single shared future. The GitHub Connect credential mode from 6750d59e (installation-token callable + verifier) is deferred too; #233 takes only the bot-user-id config.
Out of scope
Porting notes
On promotion: optional SDKs (e.g. xdk) go behind an extra, imported lazily; hmac.compare_digest for every signature check; x if x is not None else os.environ.get(...) for env fallbacks; {adapter}:{channel}:{thread} ids plus an #188 descriptor; dedupe/claim/refresh state awaited and released on failure.
Tests
Nothing to port while items stay deferred. On promotion, port the matching upstream suites. None are fidelity-mapped: packages/adapter-instagram/src/*.test.ts (27), packages/adapter-notion/src/*.test.ts (69), the root cases in packages/adapter-x/src/index.test.ts, the 043386b5 cases in packages/adapter-telegram/src/index.test.ts, the RCS cases in packages/adapter-twilio/src/{api/content,channel,cards,index,webhook/index}.test.ts, and the Connect cases in each adapter's index.test.ts.
Acceptance criteria
This issue closes when:
Dependencies
None (backlog tracking); informs #203. Once promoted, items depend on #204 (Instagram), #192 (Notion), #227 (Telegram Business) and #235 (Twilio RCS).
Metadata
- Effort: n/a (backlog). Per-item estimates are listed above.
- Consumer impact: none (nothing ships; no current consumer uses these).
- Suggested branch: n/a. Promoted items use
sync/4.41-<new-id>.
Part of #184.
Summary
Backlog issue, not a PR. Upstream 4.32–4.41 added platforms and opt-in adapter modes no current consumer uses. Each is recorded with reason, effort and prerequisites so the 4.41 sync lists them as known non-parity, not silent gaps. An item becomes its own issue only when a consumer asks.
Upstream changes
2a2b2c55feat(instagram): add native DM adapter (#770) — chat@4.37.0 — new@chat-adapter/instagram: about 1.7k src LOC and 27 tests.0ec6a736feat(notion): add Notion comments adapter (#689) — chat@4.37.0 — new@chat-adapter/notion: about 2.3k src LOC and 69 tests.06b04ac4Add Vercel Connect support to Notion (#812) — chat@4.38.0 — token resolver function and Connect setup.ef2542c5feat(x): add X (Twitter) adapter (#682) — chat@4.33.0 — posts, mentions and DMs over raw REST, with a CRC challenge and OAuth2 refresh.4bca64f0feat(x): support image uploads on posts and DMs (#700) — chat@4.34.0 — chunked media upload.b6749238fix(x): harden CRC challenge token validation (#775) — chat@4.37.0 — validates the shape of the CRC token before signing it.caa63253feat(x): add XChat encrypted messaging support (#745) — chat@4.36.0 — E2E-encryptedx/chatbuilt on WASMchat-xdk+juicebox-sdk.fe4ed11edocs: add XChat branding and clarify X vs XChat adapters (#777) — chat@4.37.0 — docs only.043386b5feat(telegram): add Business mode support (#888) — chat@4.40.0 — opt-in business connections andtelegram:biz:{conn}:{chat}thread ids (index.ts+417/−70, +909 test lines).75cadbf9feat(twilio): add RCS support for interactive inbound and rich outbound (#590) — chat@4.39.0 — Content API templates, button actions, locations and channel inference (about 2.4k lines).7a1150ceAdd Vercel Connect support to Telegram (#813) — chat@4.38.0 —botTokenmay be a function, resolved on every Bot API call.4115c943feat(linear): add Vercel Connect support (#649) — chat@4.33.0 — access-token function,webhookVerifier, and Connect-mode installs.961cf454Recommend agent sessions for Linear Connect bots (#931) — chat@4.41.0 — an info log plus scaffolding.a0cba028Add Vercel Connect support to Discord (#808) — chat@4.38.0 —botToken/applicationIdfunctions and a customwebhookVerifierin place of Ed25519.Current Python behavior
ls src/chat_sdk/adapters/: 10 adapters, no instagram, notion or x.grep -rniE 'instagram|notion|xchat|juicebox' srcreturns nothing.grep -rni business src/chat_sdk/adapters/telegramreturns nothing.bot_tokenis string-only (src/chat_sdk/adapters/telegram/adapter.py:653).grep -rniE 'rcs|content_sid|ButtonPayload' src/chat_sdk/adapters/twilioreturns nothing.cards.pyis 16 lines._render_postable_text(adapter.py:596-599) renders an actions-only card to empty text.webhook_secret(src/chat_sdk/adapters/linear/adapter.py:354-358). Discord requirespublic_key(src/chat_sdk/adapters/discord/adapter.py:110-114). Neither has awebhook_verifier. The only precedent is Slack (src/chat_sdk/adapters/slack/adapter.py:305-354).Scope
Instagram DM adapter — defer, M (~700–900 LOC)
Structurally Messenger, which Python already has (
messenger/adapter.py: verify handshake:291, signature:308,stream:585, message cache:948, Graph fetch:1012). Factor out a shared Meta base. Differences: thegraph.instagram.combase URL,object == "instagram", a 1000-byte limit, window-error codes, edit/delete/reactions raising, and downloads restricted by a CDN host allowlist. Prereq: #204.Notion comments adapter — defer, L (~1.2–1.5k LOC + 69 tests)
Plain REST plus HMAC (
X-Notion-Signature: sha256=…, compared withhmac.compare_digest), a one-time verification-token handshake, claim/release event dedupe, a file-upload poll and a rate limiter. Prereqs:is_mentionundetermined (None), notFalse.X (Twitter) adapter — defer, L (~2.1k upstream LOC for the root adapter)
Portable (raw REST + CRC HMAC challenge); the paid Account Activity API tier limits who can use it. Port b6749238's CRC validation from day one. Prereq: move the token crypto helpers out of
slack/crypto.py:28,57,88intochat_sdk/sharedrather than cross-adapter imports. OAuth2 refresh tokens are single-use: make refresh single-flight (asyncio.Lockor cachedasyncio.Task).XChat — skip
E2E crypto, signing and PIN-based key recovery all live in WASM
chat-xdk+juicebox-sdk. On 2026-09-29,pypi.org/pypi/{chat-xdk,juicebox-sdk,juicebox}/jsonall returned 404; onlyxdkexists. Porting would needwasmtime-pyembedding or PyO3 bindings: out of proportion to demand.chat-xdk.Telegram Business mode — defer, L
Opt-in, niche. Needs a
telegram:biz:{conn}:{chat}decode branch;business_connection_idon every send, edit, typing, upload and callback; a 1h connection cache that ignores connections unlessis_enabledandcan_reply; echo dropping;deleteBusinessMessages; reactions raisingNotImplementedError; and explicit pollingallowed_updates. Prereq: #227, because it changes the polling loop.Twilio RCS — defer, XL (split into Content API client / outbound / inbound actions+location if promoted)
Content API get-or-create templates with SMS fallback,
ButtonPayload→process_action,geo:attachments, channel inference and theTWILIO_RCS_SENDER_IDenv var. Template-resolution failures fall back to text. Send failures must propagate instead of retrying as text, to avoid duplicate sends. Prereq: #235.TWILIO_EMPTY_CARD_FALLBACK("Message from bot") instead of empty text; may ride along with [4.41/TW1] Twilio: isolate locks and channels per conversation, restrict authenticated media downloads #235 at the maintainer's option.Vercel Connect hooks: Linear, Discord, Telegram, Notion — defer, S–M each
Vercel-hosted credential callables plus a custom
webhook_verifier. Follow the Slack precedent: reject non-callables at construction; the verifier takes precedence over the secret, and a string return replaces the body; callables may be sync or async (inspect.isawaitable) and are resolved on every call; any retained native check keepshmac.compare_digest. Discord'sapplication_idresolves once and is memoized behind a single shared future. The GitHub Connect credential mode from6750d59e(installation-token callable + verifier) is deferred too; #233 takes only the bot-user-id config.Out of scope
chat/adapterscatalog, create-chat-sdk, TanStack AI and Workflow approvals. These are skipped with non-parity rows in [4.41/C11] Bump fidelity pin + UPSTREAM_PARITY to chat@4.41.1, record non-parity rows, cut 0.4.41 #203.connectWebhookContracttest helper. [4.41/X1] Shared adapter test contracts (thread-id + self-message) — optional #188 defers it until two or more adapters havewebhook_verifier; promoting the Connect hooks is what would trigger it.Porting notes
On promotion: optional SDKs (e.g.
xdk) go behind an extra, imported lazily;hmac.compare_digestfor every signature check;x if x is not None else os.environ.get(...)for env fallbacks;{adapter}:{channel}:{thread}ids plus an #188 descriptor; dedupe/claim/refresh state awaited and released on failure.Tests
Nothing to port while items stay deferred. On promotion, port the matching upstream suites. None are fidelity-mapped:
packages/adapter-instagram/src/*.test.ts(27),packages/adapter-notion/src/*.test.ts(69), the root cases inpackages/adapter-x/src/index.test.ts, the043386b5cases inpackages/adapter-telegram/src/index.test.ts, the RCS cases inpackages/adapter-twilio/src/{api/content,channel,cards,index,webhook/index}.test.ts, and the Connect cases in each adapter'sindex.test.ts.Acceptance criteria
This issue closes when:
docs/UPSTREAM_SYNC.md§ Known Non-Parity with the reason given here. The rows land via [4.41/C11] Bump fidelity pin + UPSTREAM_PARITY to chat@4.41.1, record non-parity rows, cut 0.4.41 #203.docs/UPSTREAM_SYNC.mdupdated, CHANGELOG under "Unreleased (4.41 wave)", consumer-visible changes called out).Dependencies
None (backlog tracking); informs #203. Once promoted, items depend on #204 (Instagram), #192 (Notion), #227 (Telegram Business) and #235 (Twilio RCS).
Metadata
sync/4.41-<new-id>.Part of #184.