Skip to content

Public API for reconstructing a Thread in a worker process from persisted state #46

@patrick-chinchill

Description

@patrick-chinchill

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:

  1. 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.

  2. 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)

  1. Re-export Thread.from_json(...) at module level / on the public Thread symbol, matching TS ThreadImpl.fromJSON.
  2. Add Chat.thread(thread_id) as a public method mirroring TS Chat.thread.
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions