Skip to content

Commit 4346178

Browse files
chore(release): cut 0.4.30 — Teams SDK migration + 4.30.0 parity (#93 PR 4/4)
Final PR of the Teams SDK migration (issue #93). PRs 1-3 (inbound+auth, outbound, native streaming) are merged; this cuts the 0.4.30 release. - Version bump: pyproject 0.4.29 -> 0.4.30; UPSTREAM_PARITY "4.29.0" -> "4.30.0". - Fidelity re-pin chat@4.29.0 -> chat@4.30.0 in lint.yml + verify_test_fidelity.py (docstring, default parity fallback, clone hint). packages/chat/src is byte-for-byte identical between the two tags, so zero new test ports: strict fidelity stays 100% (732/732, 0 missing) against chat@4.30.0. Baseline regenerated (ts_parity -> chat@4.30.0; the recorded total_ts_tests literal 731 -> 732 corrects a stale count from the merged adapter waves, not the re-pin — the count is identical against both tags). - Docs: project-instructions version map + fidelity pin; README status line; CHANGELOG 0.4.30 entry (Twilio adapter, Telegram streaming, Slack subpaths, WhatsApp/Slack/gchat fixes, Teams #93 PRs 1-4); UPSTREAM_SYNC.md parity header + the Teams deferral row flipped to delivered. - Version-label normalization: malformed `adapter-teams@chat@4.30.0` and loose `adapter-teams@4.30.0` -> `@chat-adapter/teams@4.30.0` in adapter.py (5), bridge.py (1), UPSTREAM_SYNC.md (4). Comment/doc-only. Does NOT tag/publish — the release is a separate maintainer-gated step (live Teams 429 streaming check + PyPI authorization).
1 parent 17aa41a commit 4346178

11 files changed

Lines changed: 52 additions & 30 deletions

File tree

.github/workflows/lint.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ jobs:
6060
- name: Clone upstream vercel/chat at pinned parity tag
6161
id: clone_upstream
6262
run: |
63-
git clone --depth 1 --branch chat@4.29.0 \
63+
git clone --depth 1 --branch chat@4.30.0 \
6464
https://github.com/vercel/chat.git /tmp/vercel-chat
6565
6666
- name: Test fidelity check (strict — zero missing in mapped core files)

CHANGELOG.md

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,33 @@
11
# Changelog
22

3-
## Unreleased
3+
## 0.4.30
44

5-
In flight toward `vercel/chat@4.30.0` (landing incrementally; `UPSTREAM_PARITY`
6-
stays `4.29.0` until the wave completes).
5+
Synced to upstream `vercel/chat@4.30.0`. The mapped core (`packages/chat/src`) is byte-for-byte unchanged from `4.29.0`, so this wave is all adapter work: a **new Twilio adapter**, a **Telegram native-streaming** port, a **Slack primitives-subpath** wave, a batch of **WhatsApp / Slack / Google Chat** fixes, and the headline — the **Teams adapter migration to the official `microsoft-teams-apps` SDK** (issue #93, delivered across four PRs). Sets `UPSTREAM_PARITY = "4.30.0"`; CI fidelity re-pinned to `chat@4.30.0` (732/732 mapped-core tests still pass, 0 missing).
76

87
### New adapter: Twilio (SMS / MMS / Voice)
98

10-
- **`chat_sdk.adapters.twilio`** (vercel/chat#558). Twilio Programmable Messaging adapter (10th platform): inbound message webhooks with `X-Twilio-Signature` HMAC-SHA1 verification (`hmac.compare_digest`), outbound SMS/MMS through the Messages REST API (hand-rolled over an injectable transport — no official `twilio` SDK, mirroring upstream), 1:1 DM threads keyed `twilio:{sender}:{recipient}`, plus standalone `api` / `webhook` / `voice` helpers (TwiML builders, call + transcription parsing). New extra: `chat-sdk-python[twilio]`. Imports stay lazy so the package loads without `aiohttp` installed.
9+
- **`chat_sdk.adapters.twilio`** (vercel/chat#558; PRs #142 + the scaffolding PR). Twilio Programmable Messaging adapter (10th platform): inbound message webhooks with `X-Twilio-Signature` HMAC-SHA1 verification (`hmac.compare_digest`), outbound SMS/MMS through the Messages REST API (hand-rolled over an injectable transport — no official `twilio` SDK, mirroring upstream), 1:1 DM threads keyed `twilio:{sender}:{recipient}`, plus standalone `api` / `webhook` / `voice` helpers (TwiML builders, call + transcription parsing). New extra: `chat-sdk-python[twilio]`. Imports stay lazy so the package loads without `aiohttp` installed.
10+
11+
### Teams adapter: migration to the official `microsoft-teams-apps` SDK (issue #93)
12+
13+
The hand-rolled Bot Framework REST + JWT stack is replaced by the official Microsoft Teams Python SDK (`microsoft-teams-apps` ≥ 2.0.13, added to the `[teams]` extra), mirroring upstream `@chat-adapter/teams@4.30.0`. Landed as four PRs:
14+
15+
- **PR 1 — inbound + auth** (#143). New `adapters/teams/bridge.py`: a `BridgeHttpAdapter` implementing the SDK `HttpServerAdapter` protocol routes already-authenticated webhooks through the SDK `App`. JWT validation now runs through the SDK's `TokenValidator` (RS256 + audience + Bot Framework issuer via the live JWKS) in place of the hand-rolled `_verify_bot_framework_token` block. Graph reads stay hand-rolled (no `msgraph-sdk` / `[graph]` extra).
16+
- **PR 2 — outbound** (#144). `post_message` / `start_typing` route through `App.send`; `edit_message` / `delete_message` route through `App.api.conversations.activities(...).update` / `.delete`. Per-thread service-URL routing retargets the SDK `ApiClient`'s service-url chain (validated against the SSRF allow-list). The camelCase wire dict is still returned as `RawMessage.raw`, preserving the public contract (attachment shape, file delivery, returned id).
17+
- **PR 3 — native streaming** (#145). DM streaming uses the SDK's native `IStreamer` (`microsoft-teams-apps` `HttpStream`) via `app.activity_sender.create_stream(...)` and `stream.emit(...)` per chunk, replacing the hand-rolled Bot Framework streaming wire format. The SDK owns the streamType/streamSequence framing, the inter-flush throttle (~500ms, 429-safe), and 429 retry. Atomically unwinds the two transitional public-type divergences (`RawMessage.text`, `update_interval_ms`) that PR 3 made unnecessary.
18+
- **PR 4 — release cut** (this entry). Version bump to `0.4.30`, fidelity re-pin to `chat@4.30.0`, docs, and the `@chat-adapter/teams@4.30.0` version-label normalization.
19+
20+
The residual adapter-level divergences (we keep the SDK as the auth + transport layer but route the authenticated activity ourselves through a lenient `CoreActivity`; the streamer is closed in our own `_handle_message_activity` `finally` because our bridge owns dispatch) are documented in `docs/UPSTREAM_SYNC.md`.
21+
22+
### Adapter ports — Telegram, Slack
23+
24+
- **Telegram: native DM draft streaming** (vercel/chat#340; PR #140). DMs stream via the `sendMessageDraft` Bot API method (the draft bubble updates in place, throttled to `update_interval_ms`, default 250ms), then a regular `sendMessage` persists the final text; non-DM threads return `None` before consuming any chunks so the SDK's post+edit fallback handles groups/channels. Adds a shared `with_telegram_markdown_fallback()` retry-without-`parse_mode` path wrapping `post_message` / `edit_message` / `send_document` / `send_attachment`.
25+
- **Slack: webhook + primitives subpaths** (vercel/chat#538, #547, #548, #555, #559; PR #139). New runtime-free `chat_sdk.adapters.slack.webhook` (and `slack.api`) subpaths for lower-level Slack request verification, signed-body reading, and Events/slash/interactive payload parsing into typed dataclasses. The adapter now verifies through the shared `verify_slack_request` / `verify_slack_signature` primitives (the inline `_verify_signature` method is removed, matching upstream); the slack package `__init__` is now lazy (PEP 562) so importing a subpath does not pull in the full adapter runtime. The new `slack/api` primitives carry SSRF/token-leak guards (`send_slack_response_url` + `fetch_slack_file` host allowlists).
26+
27+
### Adapter fixes — WhatsApp, Slack, Google Chat
28+
29+
- **WhatsApp: typing-indicator support** (vercel/chat#320; PR #141). `start_typing` resolves the latest inbound message id from the `ThreadHistoryCache` and posts a `typing_indicator` payload (also marking the message read); Graph API default bumped v21.0 → v25.0; `_graph_api_request` and the typing-indicator failure path raise `AdapterError` instead of `RuntimeError`.
30+
- **Slack / Google Chat: 4.30 rendering fixes** (vercel/chat#523, #553, #573; PR #141). Includes collapsing redundant autolink formatting for Google Chat email/`mailto:` links (port of upstream `177735a`).
1131

1232
#### Python-specific (divergence from upstream)
1333

CLAUDE.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Claude Code Quick Reference -- chat-sdk-python
22

33
## What is this?
4-
Python port of [Vercel Chat SDK](https://github.com/vercel/chat) (synced to upstream v4.29.0; next wave 4.30.0 is tracked separately). Multi-platform async chat framework.
4+
Python port of [Vercel Chat SDK](https://github.com/vercel/chat) (synced to upstream v4.30.0). Multi-platform async chat framework.
55

66
## Key Commands
77
```bash
@@ -27,6 +27,7 @@ Our version embeds the upstream Vercel Chat version: `0.{upstream_major}.{upstre
2727
- `0.4.27` = synced to upstream `4.27.0`
2828
- `0.4.27.1` = Python-only fix on top of `4.27.0`
2929
- `0.4.29` = synced to upstream `4.29.0` (upstream never tagged 4.27/4.28 as `chat@*`)
30+
- `0.4.30` = synced to upstream `4.30.0`
3031
- `UPSTREAM_PARITY` constant in `__init__.py` = programmatic access
3132

3233
## Architecture
@@ -109,7 +110,7 @@ will not pass CI.
109110

110111
**Fidelity check** (`scripts/verify_test_fidelity.py`) verifies every TS
111112
`it("...")` in the mapped core files has a matching Python `def test_*()`,
112-
pinned to `chat@4.29.0` (matches `UPSTREAM_PARITY`; upstream never tagged
113+
pinned to `chat@4.30.0` (matches `UPSTREAM_PARITY`; upstream never tagged
113114
`chat@4.27.0`/`chat@4.28.0`). The `MAPPING` dict in that script is the
114115
authoritative scope list — extending it to the remaining unmapped
115116
`packages/chat/src/*.test.ts` files is tracked as issue #78.
@@ -124,7 +125,7 @@ divergence in `docs/UPSTREAM_SYNC.md`.
124125
Before the fidelity check can run locally, clone the pinned upstream
125126
checkout (same command CI uses in `lint.yml`):
126127
```bash
127-
git clone --depth 1 --branch chat@4.29.0 \
128+
git clone --depth 1 --branch chat@4.30.0 \
128129
https://github.com/vercel/chat.git /tmp/vercel-chat
129130
```
130131
Then `TS_ROOT=/tmp/vercel-chat uv run python scripts/verify_test_fidelity.py --strict`.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
Multi-platform async chat SDK for Python. Port of [Vercel Chat](https://github.com/vercel/chat).
99

10-
> **Status: 0.4.29 — synced to [Vercel Chat 4.29.0](https://github.com/vercel/chat)** (`UPSTREAM_PARITY = "4.29.0"`). The 4.30 sync wave is tracked in [#135](https://github.com/Chinchill-AI/chat-sdk-python/issues/135). See [CHANGELOG.md](CHANGELOG.md).
10+
> **Status: 0.4.30 — synced to [Vercel Chat 4.30.0](https://github.com/vercel/chat)** (`UPSTREAM_PARITY = "4.30.0"`). See [CHANGELOG.md](CHANGELOG.md).
1111
1212
## Why chat-sdk?
1313

0 commit comments

Comments
 (0)