Summary
The Python port doesn't re-export the public Thread / Chat construction surface that upstream TS already has. Downstream code that needs to reconstruct a thread in a worker process (e.g. durable-execution or queued-worker patterns) currently has to import private symbols.
Today (Python port)
ThreadImpl.__init__(config: _ThreadImplConfig) — _ThreadImplConfig is underscore-prefixed and not re-exported.
ThreadImpl.from_json(...) exists but is reached via the private ThreadImpl class.
- No public factory on
Chat that takes a fully-qualified thread_id.
Consumers end up importing ThreadImpl and _ThreadImplConfig directly, coupling to internal module layout.
Upstream TS parity (what's missing in Python)
Vercel TS already exposes the equivalent construction paths as public API. The Python port just needs to match:
-
packages/chat/src/thread.ts ~L945:
static fromJSON<TState = Record<string, unknown>>(
json: SerializedThread,
adapter?: Adapter,
): ThreadImpl<TState>
→ Python should expose Thread.from_json(...) on the public re-export.
-
packages/chat/src/chat.ts — public chat.thread(threadId) method returning a Thread with auto-inferred adapter.
→ Python should add Chat.thread(thread_id) as a public method mirroring TS.
Why current_message matters for the worker case
_handle_stream reads self._current_message to populate StreamOptions.recipient_user_id (thread.py ~L626). Without it, Slack's native streaming validation rejects the request. The public construction path needs to accept / propagate a current_message so worker reconstruction stays functional for streaming.
Proposed fix (Python-only, strictly additive)
- Re-export
Thread.from_json(...) at module level / on the public Thread symbol, matching TS ThreadImpl.fromJSON.
- Add
Chat.thread(thread_id) as a public method mirroring TS Chat.thread.
- Confirm both paths preserve
current_message so Slack native streaming works post-reconstruction; add a regression test covering the worker case.
This is pure port-drift cleanup — the TS public surface already exists, Python just kept the equivalents private. No upstream coordination needed.
Summary
The Python port doesn't re-export the public
Thread/Chatconstruction surface that upstream TS already has. Downstream code that needs to reconstruct a thread in a worker process (e.g. durable-execution or queued-worker patterns) currently has to import private symbols.Today (Python port)
ThreadImpl.__init__(config: _ThreadImplConfig)—_ThreadImplConfigis underscore-prefixed and not re-exported.ThreadImpl.from_json(...)exists but is reached via the privateThreadImplclass.Chatthat takes a fully-qualifiedthread_id.Consumers end up importing
ThreadImpland_ThreadImplConfigdirectly, coupling to internal module layout.Upstream TS parity (what's missing in Python)
Vercel TS already exposes the equivalent construction paths as public API. The Python port just needs to match:
packages/chat/src/thread.ts~L945:→ Python should expose
Thread.from_json(...)on the public re-export.packages/chat/src/chat.ts— publicchat.thread(threadId)method returning aThreadwith auto-inferred adapter.→ Python should add
Chat.thread(thread_id)as a public method mirroring TS.Why
current_messagematters for the worker case_handle_streamreadsself._current_messageto populateStreamOptions.recipient_user_id(thread.py~L626). Without it, Slack's native streaming validation rejects the request. The public construction path needs to accept / propagate acurrent_messageso worker reconstruction stays functional for streaming.Proposed fix (Python-only, strictly additive)
Thread.from_json(...)at module level / on the publicThreadsymbol, matching TSThreadImpl.fromJSON.Chat.thread(thread_id)as a public method mirroring TSChat.thread.current_messageso Slack native streaming works post-reconstruction; add a regression test covering the worker case.This is pure port-drift cleanup — the TS public surface already exists, Python just kept the equivalents private. No upstream coordination needed.