Skip to content

Commit fc60b5e

Browse files
committed
merge: resolve CHANGELOG conflict with #108 (alpha bump)
2 parents 9fecb88 + f1a1d4f commit fc60b5e

5 files changed

Lines changed: 152 additions & 11 deletions

File tree

CHANGELOG.md

Lines changed: 142 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,151 @@
11
# Changelog
22

3-
## Unreleased
3+
## 0.4.29a1 (2026-05-28)
44

5-
Part of the 0.4.29 sync wave (tracking issue #98).
5+
Alpha sync starter for upstream `4.29.0` (`vercel/chat` release commit
6+
`6581d31`, May 18 2026). Upstream skipped tagging `chat@4.27.0` and
7+
`chat@4.28.0` (only `@chat-adapter/shared@4.27.0` and `@chat-adapter/shared@4.28.0`
8+
got tags); `chat@4.29.0` is the next real tag and the target of this
9+
wave. **No feature ports in this release** — parity-bookkeeping bump
10+
that sets `UPSTREAM_PARITY = "4.29.0"` and lays out the porting plan
11+
below.
12+
13+
Each substantive commit lands as its own PR (matching the cadence used
14+
during the 4.27 sync: #83, #85, #86, #87, #88, #89, #90, #91, #92, #99,
15+
#101, #103, #104, #105). Tracking issue: #98.
616

717
### Behavior changes (Slack)
818

9-
- **`webhook_verifier` now takes precedence over `signing_secret`** (#108, vercel/chat#468, commit `0f0c203`). When a Slack adapter is constructed with both `webhook_verifier` and `signing_secret` (or with `webhook_verifier` while `SLACK_SIGNING_SECRET` is set in the env), the verifier wins and the signing-secret path is dropped entirely. This **reverses** the precedence the Python port shipped in 0.4.27 (PR #87), which preferred `signing_secret` to match upstream's intent at that time. Upstream reversed itself in vercel/chat#468 (`chat@4.29.0`) so an env-configured `SLACK_SIGNING_SECRET` could not silently shadow a verifier the caller wired up; this port now follows. **Migration:** if you relied on a configured `signing_secret` overriding `webhook_verifier`, drop the `webhook_verifier` from your `SlackAdapterConfig` (or, if you wired the verifier in deliberately, your signing-secret path is now correctly inert and you can remove it). The built-in HMAC + 5-minute timestamp tolerance only applies on the signing-secret path; verifier implementers remain responsible for replay protection (`slack/types.py` SECURITY contract).
19+
- **`webhook_verifier` now takes precedence over `signing_secret`** (vercel/chat#468, commit `0f0c203`). When a Slack adapter is constructed with both `webhook_verifier` and `signing_secret` (or with `webhook_verifier` while `SLACK_SIGNING_SECRET` is set in the env), the verifier wins and the signing-secret path is dropped entirely. This **reverses** the precedence the Python port shipped in 0.4.27 (PR #87), which preferred `signing_secret` to match upstream's intent at that time. Upstream reversed itself in vercel/chat#468 (`chat@4.29.0`) so an env-configured `SLACK_SIGNING_SECRET` could not silently shadow a verifier the caller wired up; this port now follows. **Migration:** if you relied on a configured `signing_secret` overriding `webhook_verifier`, drop the `webhook_verifier` from your `SlackAdapterConfig` (or, if you wired the verifier in deliberately, your signing-secret path is now correctly inert and you can remove it). The built-in HMAC + 5-minute timestamp tolerance only applies on the signing-secret path; verifier implementers remain responsible for replay protection (`slack/types.py` SECURITY contract).
20+
21+
### Sync scope (37 substantive upstream commits between `f55378a..chat@4.29.0`)
22+
23+
#### Core (`packages/chat`)
24+
25+
- [ ] **`chat/ai` subpath for AI SDK utilities** (vercel/chat#492). New
26+
public API surface: `createChatTools`, `toAiMessages` for LLM/agent
27+
integration. Vercel AI SDK is TS-only; the Python equivalent needs a
28+
design call (see open question). Likely the biggest single PR in the
29+
wave.
30+
- [ ] **`queue-debounce` concurrency strategy** (vercel/chat#495). New
31+
strategy beyond the existing `drop` / `queue` / `debounce` /
32+
`concurrent`.
33+
- [ ] **Transcripts API + per-thread cache rename to `threadHistory`**
34+
(vercel/chat#448). New API surface; the cache rename has chinchill-api
35+
blast radius.
36+
- [ ] **`callbackUrl` on buttons and modals** (vercel/chat#454).
37+
- [ ] **`message.subject` + adapter client access** (vercel/chat#459).
38+
39+
#### All adapters
40+
41+
- [ ] **`adapter.client` rename → `adapter.octokit` / `adapter.linearClient`
42+
/ `adapter.webClient`** (vercel/chat#478). Public API rename across
43+
all adapters; deprecation shims advisable for one release.
44+
- [x] **`private``protected` for subclassing** (vercel/chat#475).
45+
Already addressed — Python convention uses `_underscore` (de-facto
46+
protected); audit confirmed no `__name_mangled` internals across all
47+
8 adapters. No work needed.
48+
49+
#### Slack (`packages/adapter-slack`)
50+
51+
- [ ] **Native `markdown_text` for outgoing messages** (vercel/chat#440).
52+
Was listed as "deferred" in 0.4.27.
53+
- [ ] **External installation provider for bot token management**
54+
(vercel/chat#467). Multi-workspace token mgmt extension.
55+
- [ ] **Flip `webhook_verifier > signing_secret` precedence**
56+
(vercel/chat#468). Our 0.4.27 explicitly went the other direction
57+
("match upstream" intent, with comment). Upstream has since reversed
58+
itself in #468. The comment on `adapter.py:385` is now stale; flip
59+
precedence + refresh comment + update tests.
60+
- [ ] **Expose direct `WebClient` via `adapter.client`** (vercel/chat#471,
61+
reverted in #472, reapplied in #476). Pairs with the #478 rename.
62+
63+
#### Discord (`packages/adapter-discord`)
64+
65+
- [ ] **Handle interactions in gateway-only mode** (vercel/chat#490).
66+
Related to issue #57 (Discord native Gateway). Decide if Gateway
67+
support lands in this wave or stays on a separate track.
68+
69+
#### Telegram (`packages/adapter-telegram`)
70+
71+
- [ ] **Typed attachment uploads** (vercel/chat#485). Bundled with
72+
related Telegram polish.
73+
- [ ] **`video_note` (round video messages) in `extractAttachments`**
74+
(vercel/chat#457).
75+
- [x] **MarkdownV2 entity safety trim to streaming chunks**
76+
(vercel/chat#446). Already addressed in our 0.4.27 — the
77+
`_trim_to_markdown_v2_safe_boundary` / `_find_unclosed_link_dest_open_bracket`
78+
/ `_slice_to_utf16_units` helpers from PR #89 cover this. No work
79+
needed.
80+
81+
#### Teams (`packages/adapter-teams`)
82+
83+
- [ ] **Migrate to `microsoft-teams-apps` SDK** (issue #93). Replaces our
84+
hand-rolled Bot Framework REST streaming with `ctx.stream.emit()`.
85+
Requires Python 3.12 floor bump. Headline Teams change for this wave
86+
(or 0.4.29.1 if the migration slips).
87+
88+
#### New packages
89+
90+
- [ ] **`@chat-adapter/messenger`** (vercel/chat#461). Brand-new Meta
91+
Messenger Platform adapter. Similar scope to porting WhatsApp or
92+
Telegram from scratch — own file tree under `src/chat_sdk/adapters/messenger/`,
93+
full webhook / message / attachment surface, ~1,500 LOC estimate.
94+
- [⏭️] **`@chat-adapter/web`** (vercel/chat#444). Vue + Svelte browser
95+
UI for chat-sdk bots. **Out of scope** — no browser runtime in
96+
chat-sdk-python.
97+
- [ ] **`@chat-adapter/tests` test kit** (vercel/chat#470). Test
98+
utilities for adapter authors. We already have an adapter-test
99+
pattern; evaluate whether to mirror.
100+
101+
#### Out of scope for this Python port
102+
103+
- **`@chat-adapter/web`** as above.
104+
- **Documentation site changes**`apps/docs/`, MDX refreshes, etc.
105+
- **Vercel-specific release/CI automation** (#465, #466, #511, #512,
106+
#520).
107+
108+
### Open questions (resolve before implementation)
109+
110+
1. **`chat/ai` subpath — Python design.** Detailed scoping in design
111+
issue (see below). Recommended shape: shared SDK-agnostic core in
112+
`chat_sdk/ai/tools.py` + thin per-SDK adapters (Anthropic, OpenAI)
113+
via optional extras (`chat-sdk-python[ai-anthropic]`,
114+
`chat-sdk-python[ai-openai]`). 17 tool factories + the existing
115+
`to_ai_messages` (already in `chat_sdk/ai.py`). ~7 engineer-days.
116+
Three sub-questions: approval-flow contract, hand-written JSON
117+
Schema vs Pydantic v2, ship OpenAI extras in first cut?
118+
2. **Messenger adapter (vercel/chat#461) — Python port.** Detailed
119+
scoping in design issue (see below). Mirrors WhatsApp adapter
120+
conventions; ~1,500 LOC prod + ~2,500 LOC tests; 2 PRs (scaffolding
121+
then adapter); ~5–6 days. Three sub-questions: init-failure
122+
semantics, postback `value` passthrough, signature-failure HTTP
123+
status code (upstream returns 403, our other adapters return 401).
124+
3. **Cadence**: ship as one wave (4.27 → 4.29) or split into 0.4.28
125+
then 0.4.29?
126+
4. **Python floor bump to 3.12** (required for Teams SDK migration —
127+
issue #93). Confirm chinchill-api compatibility before committing.
128+
5. **Discord Gateway scope**: ship Gateway support in this wave
129+
(issue #57) or keep gateway-only mode fix (vercel/chat#490)
130+
isolated?
131+
6. **`adapter.client` rename**: ship deprecation shim for one release,
132+
or hard cutover?
133+
134+
### Workflow
135+
136+
1. This alpha PR establishes the sync. CI on this draft is intentionally
137+
not invoked (lint.yml is gated on `!github.event.pull_request.draft`).
138+
2. Each item above lands as its own PR. Each port PR:
139+
- Updates the relevant `MAPPING` / fidelity coverage and removes its
140+
entries from `scripts/fidelity_baseline.json` if previously baselined.
141+
- Bumps lint.yml's pinned upstream ref to `chat@4.29.0` (the new tag)
142+
once the first feature port lands.
143+
- Adds an entry under the next CHANGELOG heading (`0.4.29a2`,
144+
`0.4.29a3`, …).
145+
3. Once all items are ported (or explicitly documented as divergence in
146+
`docs/UPSTREAM_SYNC.md`), the final PR cuts `0.4.29` and switches CI
147+
back to strict fidelity at the upstream tag.
148+
>>>>>>> origin/main
10149
11150
## 0.4.27 (2026-05-28)
12151

CLAUDE.md

Lines changed: 7 additions & 5 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 v4.27.0; last fully-synced release `0.4.27`). Multi-platform async chat framework.
4+
Python port of [Vercel Chat SDK](https://github.com/vercel/chat) (porting v4.29.0; last fully-synced release `0.4.27` at upstream `4.27.0`). Multi-platform async chat framework.
55

66
## Key Commands
77
```bash
@@ -24,7 +24,8 @@ Our version embeds the upstream Vercel Chat version: `0.{upstream_major}.{upstre
2424
- `0.4.25.1` = Python-only fix on top of `4.25.0`
2525
- `0.4.26` = synced to upstream `4.26.0`
2626
- `0.4.26.3` = Python-only fixes on top of `4.26.0`
27-
- `0.4.27` = synced to upstream `4.27.0` (current release)
27+
- `0.4.27` = synced to upstream `4.27.0`
28+
- `0.4.29a1` = alpha while porting upstream `4.29.0` (current branch; upstream skipped 4.28 tag)
2829
- `UPSTREAM_PARITY` constant in `__init__.py` = programmatic access
2930

3031
## Architecture
@@ -107,8 +108,9 @@ will not pass CI.
107108

108109
**Fidelity check** (`scripts/verify_test_fidelity.py`) verifies every TS
109110
`it("...")` in the mapped core files has a matching Python `def test_*()`,
110-
pinned to `chat@4.26.0` (the last fully-synced upstream tag — `chat@4.27.0`
111-
is in flight; pin moves as ports land in this sync cycle). The `MAPPING`
111+
pinned to `chat@4.26.0` (upstream skipped tagging `chat@4.27.0` and
112+
`chat@4.28.0`, then resumed at `chat@4.29.0`; pin moves to `chat@4.29.0`
113+
once the in-flight 4.29 sync lands). The `MAPPING`
112114
dict in that script is the authoritative scope list — it currently covers 8
113115
of 17 `packages/chat/src/*.test.ts` files (extending it is tracked as a
114116
follow-up). **CI runs `--strict`** (see `.github/workflows/lint.yml`):
@@ -119,7 +121,7 @@ retained for local workflows where a few ports land in flight —
119121
regenerate via `--update-baseline` after documenting intentional
120122
divergence in `docs/UPSTREAM_SYNC.md`. During this sync cycle baseline
121123
mode reports a parity mismatch (baseline pinned at `chat@4.26.0`,
122-
`UPSTREAM_PARITY` says `4.27.0`); that's the intended signal until the
124+
`UPSTREAM_PARITY` says `4.29.0`); that's the intended signal until the
123125
sync lands.
124126

125127
Before the fidelity check can run locally, clone the pinned upstream

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.27**synced to upstream [Vercel Chat 4.27.0](https://github.com/vercel/chat) (release commit `f55378a`). See [CHANGELOG.md](CHANGELOG.md) for release notes and [docs/UPSTREAM_SYNC.md](docs/UPSTREAM_SYNC.md) for the known non-parity list.
10+
> **Status: Alpha (0.4.29a1porting [Vercel Chat 4.29.0](https://github.com/vercel/chat))** — API may change. Last fully-synced release: `0.4.27` (parity with upstream `chat@4.27.0`). See [CHANGELOG.md](CHANGELOG.md) for the in-flight sync plan.
1111
1212
## Why chat-sdk?
1313

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "chat-sdk"
3-
version = "0.4.27"
3+
version = "0.4.29a1"
44
description = "Multi-platform async chat SDK for Python — port of Vercel Chat"
55
keywords = [
66
"chat",

src/chat_sdk/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@
191191
)
192192

193193
# The upstream Vercel Chat version this release is synced to.
194-
UPSTREAM_PARITY = "4.27.0"
194+
UPSTREAM_PARITY = "4.29.0"
195195

196196
__all__ = [
197197
"UPSTREAM_PARITY",

0 commit comments

Comments
 (0)