You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
CHANGELOG: add 'Pre-existing parity gaps closed (4.30 audit)' subsection
covering the 7 ported fixes (PRs #147-#150) and a documented-exceptions
note (Linear agent-sessions #151 deferred to 4.31 / #152; adapter-web and
the GitHub/Linear native-client + message.subject halves stay Known
Non-Parity).
UPSTREAM_SYNC:
- file-mapping table: add state-ioredis -> redis.py (IoRedisStateAdapter)
and state-pg -> postgres.py rows (both ported + tested, were missing).
- Known Non-Parity (platform gaps): add Linear agent-sessions row (#151)
and an adapter-web row that splits the portable server-side WebAdapter
(deferred) from the genuinely browser-only client subpaths, correcting
the earlier over-broad 'browser-only; no Python runtime' note.
- Correct the Google Chat file-uploads row: inbound attachment parsing is
fully implemented (_create_attachment), so the gap is outbound file
delivery only (post_message still logs 'not yet supported').
Copy file name to clipboardExpand all lines: CHANGELOG.md
+11Lines changed: 11 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -33,6 +33,17 @@ The residual adapter-level divergences (we keep the SDK as the auth + transport
33
33
34
34
-**Twilio media-download SSRF guard.**`rehydrate_attachment` validates the rehydrated media URL (https + Twilio-owned host) inside the download closure before forwarding the account SID / auth token as HTTP Basic, where upstream `fetchTwilioMedia` GETs the URL blindly. Folded into the existing `rehydrate_attachment` URL allowlist non-parity row (Slack / Teams / Google Chat / **Twilio**); enforces `CLAUDE.md`'s SSRF rule. Regression: `tests/test_twilio_adapter.py::TestRehydrateAttachment::test_media_downloader_refuses_untrusted_hosts`.
35
35
36
+
### Pre-existing parity gaps closed (4.30 audit)
37
+
38
+
A pre-ship parity audit (the CI fidelity check covers only the mapped CORE `packages/chat` tests, never the adapters) surfaced 9 gaps present since 0.4.29 — the `chat@4.29.0` and `chat@4.30.0` tags are content-identical for the mapped core — and the 7 portable ones were closed in this wave:
39
+
40
+
-**Google Chat: clear `cardsV2` on edit-to-plain-text** (PR #148). BUG — editing a card message down to plain text left the old card stranded on the message; `edit_message` now sends an explicit empty `cardsV2` so the card is dropped (streaming finalization is the common trigger). Plus **`Select` / `RadioSelect` → `selectionInput` widgets**: these card elements now render as Google Chat `selectionInput` widgets and the selected option is read back from `formInputs`.
41
+
-**Teams: ChoiceSet auto-submit fan-out** (PR #149). BUG / contract break — an Adaptive Card `Action.Submit` carrying multiple input keys now fires one `process_action` per input key, so each `on_action(input_key)` handler runs, instead of a single `__auto_submit` dispatch that no handler matched. Plus **`list_threads` / `post_channel_message`** (were raising `ChatNotImplementedError`, now implemented) and **`api_url` / `TEAMS_API_URL`** for a custom Bot Framework endpoint (GCC-High / sovereign cloud).
42
+
-**`api_url` custom-endpoint config across Slack / Discord / GitHub / Linear** (PR #150). Custom base URLs for GovSlack / Enterprise Grid / GitHub Enterprise / self-hosted Linear; an empty string falls back to the default, matching upstream's truthy-spread default. Plus **GitHub public `get_installation_id()`**.
43
+
-**Core: root `chat_sdk` re-exports the deprecated `chat/ai` type aliases** (PR #147). `AiMessage`, `AiMessagePart`, `ToAiMessagesOptions`, … resolve from the package root again (they had moved to `chat_sdk.ai`); `chat_sdk.ai` stays the canonical home.
44
+
45
+
**Documented exceptions.** 0.4.30 matches `chat@4.30.0`*with documented exceptions*. The **Linear agent-sessions** surface (#151) is the largest single gap from the audit and is deferred to the 4.31 wave. `adapter-web`, plus the GitHub / Linear native-client (`octokit` / `linearClient`) and `message.subject` halves, remain documented Known Non-Parity in `docs/UPSTREAM_SYNC.md`. The 4.31 wave is tracked in #152.
46
+
36
47
## 0.4.29 (2026-06-12)
37
48
38
49
Synced to upstream `vercel/chat@4.29.0` (release commit `6581d31`, May 18 2026; upstream never tagged `chat@4.27.0`/`chat@4.28.0`). Headlines: **Meta Messenger adapter** (9th platform), **`chat/ai` tool factories** (`create_chat_tools`), **`callback_url` on buttons and modals**, **Transcripts API + `thread_history` rename**, **`burst` concurrency strategy**, a Slack feature wave (verifier precedence flip, external installation providers, native `markdown_text`, `web_client`), the upstream adapter-hardening security pass, and a Python floor bump to 3.12. Sets `UPSTREAM_PARITY = "4.29.0"`; CI fidelity re-pinned to `chat@4.29.0`.
@@ -655,13 +657,15 @@ stay explicit instead of being rediscovered in code review.
655
657
|------|--------|-----|-----------|
656
658
| Teams certificate auth | Rejected (app password only) | Supported | Low demand; can add later |
657
659
| Teams `dialog_open_timeout_ms` config | Not implemented | Configurable | Low demand |
658
-
| Google Chat file uploads|Ignored in message parse | Supported |API complexity; can add later |
660
+
| Google Chat outbound file delivery|Files attached to an outbound message are dropped — `post_message` logs "File uploads are not yet supported for Google Chat" and posts text/cards only (no media upload). Inbound attachments **are** parsed: `_create_attachment` builds a full `Attachment` (type detection, `fetch_data` download closure, `fetch_metadata`) for every `message.attachment` entry. | Both directions supported (multipart media upload on send) | Outbound upload (multipart to the Media API) not yet ported; API complexity, can add later. Inbound parity is complete, so this row is outbound-only.|
659
661
| Discord Gateway WebSocket | HTTP interactions only | Both HTTP and Gateway | Gateway requires persistent connection |
660
662
| Discord gateway-only interactions (vercel/chat#490) | Handled on the forwarded-event surface: a `GATEWAY_INTERACTION_CREATE` envelope (raw INTERACTION_CREATE dispatch payload in `data`) is deferred via `POST /interactions/{id}/{token}/callback` (type 5 slash / type 6 component) and routed through the existing HTTP interaction handlers; a malformed forward missing `id`/`token` is logged and skipped | Upstream handles `Events.InteractionCreate` directly on the resident discord.js client via `deferReply()`/`deferUpdate()`; the upstream forwarder never forwards interactions | Python has no resident Gateway client (row above), so gateway-only deployments run an external listener shim that forwards raw dispatch payloads (`x-discord-gateway-token`). Observable wire behavior is identical — same callback REST calls, same handler routing, same `@original` deferred-response resolution. |
661
663
| Teams `User-Agent: Vercel.ChatSDK` outbound header | Not set on `aiohttp` calls | Propagated by `botbuilder` 2.0.8 | Python Teams adapter doesn't use `botbuilder` (raw `aiohttp`). Upstream's vercel/chat#415 was a JS-only `botbuilder` SDK bump that flipped `X-User-Agent` → `User-Agent`. No equivalent dependency to bump on the Python side. Setting a `User-Agent` on the ~9 outbound `aiohttp` call sites would be a defense-in-depth nice-to-have; deferred to a follow-up. |
662
664
| Teams adapter on `microsoft-teams-apps` (official MS Python SDK) | Inbound webhook + JWT auth, outbound send/edit/delete/typing, and native DM streaming all delegate to the official `microsoft-teams-apps` SDK `App`; Graph reads stay hand-rolled over `aiohttp`|`@microsoft/teams.apps` owns the wire format, throttling, and activity routing |**Delivered in 0.4.30** (issue #93, PRs 1–4). The migration shipped as four PRs: inbound + auth (#143), outbound (#144), native streaming via the SDK `IStreamer` (#145), and this release cut. The 3.12 floor bump (#111) — the migration's prerequisite — landed in 0.4.29. The residual adapter-level divergences (we keep the SDK as auth + transport but route the authenticated activity ourselves; close the streamer in our own `finally` because our bridge owns dispatch) are documented in the Teams divergence rows above. Graph stays hand-rolled (no `msgraph-sdk` / `[graph]` extra). |
663
665
| Telegram `get_user().is_bot`| Always `False` (matches upstream — `getChat` does not expose `is_bot`) | Always `false` (same caveat documented in upstream code comment) | The Telegram Bot API's `getChat` endpoint does not surface the `is_bot` field that's available on the `User` object inside incoming `Message` updates. Callers needing bot detection must use `message.author.is_bot` from webhooks instead of `chat.get_user(...).is_bot`. |
664
666
| WhatsApp `get_user`| Raises `ChatNotImplementedError` (`Chat.get_user` translates to "does not support get_user") | Not implemented upstream either (no `getUser` on the WhatsApp adapter) | WhatsApp Cloud API has no user lookup endpoint — phone numbers are the only stable identifier and there's no equivalent of `users.info` exposed to business apps. Documented explicitly so callers don't expect parity with Slack/Teams/Discord. |
667
+
| Linear agent sessions | Not ported — the ~120-reference agent-sessions surface (`parseMessageFromAgentSessionEvent`, `agentActivity`, `AgentSessionEventWebhookPayload`, `LinearAgentSessionThreadId`, …) is absent from the Python `LinearAdapter`| Full agent-sessions support (`adapter-linear` 4.27.0, `bc94f0a`): parses agent-session webhook events into messages, emits agent activity, and routes the agent-session thread id | Largest single gap from the 0.4.30 audit; pre-existing (present since 0.4.29). Deferred to the 4.31 wave — tracked in **#151**. |
668
+
|`adapter-web` (`@chat-adapter/web`) | Neither half ported. (a) The server-side `WebAdapter` is **deferred** — not yet ported; (b) the client subpaths are out of scope (see Rationale). | Two distinct things: (a) a server-side `WebAdapter` — an `Adapter` implementation serving a browser chat UI over the AI SDK UI stream protocol (`3490a8c`, vercel/chat#444); (b) React/Vue/Svelte client subpaths (`716e934`) | The `WebAdapter` (a) **is portable** to a Python server SDK (it's a standard `Adapter`) and is deferred, not excluded — a future wave can port it. The client subpaths (b) are genuinely browser-only (front-end framework bindings) and are out of scope for a Python server SDK. (Corrects the earlier over-broad "browser-only; no Python runtime" note in CHANGELOG.) |
0 commit comments