Commit 4d10adb
authored
* feat(core): optional ThinkingChunk StreamChunk variant (default-off, upstream-compatible; supersedes #39)
Adds a fourth, opt-in StreamChunk variant for streaming agent
reasoning/"thinking" to chat platforms. The whole design is default-off:
with no opt-in, the normalized stream and the posted message are
byte-for-byte identical to upstream chat@4.31.
- Additive type: ThinkingChunk(type="thinking", content=str) added to the
StreamChunk union. The existing three variants are unaffected.
- Opt-in emit: from_full_stream(stream, emit_thinking=False) and a
thread-level emit_thinking config flag (threaded into the internal
_from_full_stream) surface AI-SDK reasoning/reasoning-delta (and
pydantic-ai part_kind=="thinking") parts as ThinkingChunk only when
enabled. Default False drops reasoning exactly as upstream does.
- Graceful consume: Thread._handle_stream never accumulates a ThinkingChunk
into the posted-message text, and every adapter's stream handler skips it.
Slack/Teams expose an optional render_thinking hook (via
shared.adapter_utils.maybe_render_thinking); the text-accumulate adapters
ignore it structurally — no crash, posted message unchanged.
- No state pollution: ThinkingChunk is streaming-only. Message has no
thinking field, to_json() is unchanged, and a round-tripped Message is
byte-identical, so cross-SDK Redis/Postgres state stays compatible.
- Docs: UPSTREAM_SYNC.md Known Non-Parity row added.
Rationale: upstream's chat-platform SDK drops reasoning (leaves it to the
AI-SDK web UI); chinchill streams thinking to Slack/Teams out-of-band today
because there is no path. This gives the SDK a first-class, opt-in one
without changing any default behavior.
Gauntlet: ruff check + format, audit_test_quality (0 hard failures),
verify_test_fidelity --strict (732/732, 0 missing), pyrefly src (0 errors),
pytest (5121 passed, 4 pre-existing skips).
* refactor(core): keep StreamChunk upstream-exact, ThinkingChunk as opt-in StreamInput
Revert the public ``StreamChunk`` union to upstream's three variants
(``MarkdownTextChunk | TaskUpdateChunk | PlanUpdateChunk``) so a consumer
doing an exhaustive ``match`` over it sees zero change on upgrade. The
Python-only ``ThinkingChunk`` is no longer a member of that union.
Introduce a public ``StreamInput = str | StreamChunk | ThinkingChunk``
alias for what a stream may yield, and widen only the stream-input/output
boundaries to accept it: the ``Adapter.stream()`` protocol signature,
``from_full_stream``/``_from_full_stream`` returns, ``Thread._wrapped_stream``,
and each receiving adapter's ``stream()`` signature. A producer can yield
``ThinkingChunk`` (opt-in) and the adapters type-check; code referencing
``StreamChunk`` itself is unaffected.
All other thinking behavior is preserved byte-for-byte: ``emit_thinking``
defaults to False (default stream identical to upstream), the
``_handle_stream`` graceful skip, the adapter skip / ``render_thinking``
branches, ``maybe_render_thinking``, and the no-``Message.thinking``-field /
round-trip-identical guarantee. The UPSTREAM_SYNC divergence row is updated
to state that ``StreamChunk`` is NOT widened and ``ThinkingChunk`` is a
separate opt-in input type.
Tests now assert ``get_args(StreamChunk)`` has exactly the three upstream
variants and that ``ThinkingChunk`` is excluded from ``StreamChunk`` but
accepted by ``StreamInput``.
1 parent 8a819f4 commit 4d10adb
21 files changed
Lines changed: 968 additions & 37 deletions
File tree
- docs
- src/chat_sdk
- adapters
- github
- google_chat
- messenger
- slack
- teams
- telegram
- twilio
- whatsapp
- tests
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
684 | 684 | | |
685 | 685 | | |
686 | 686 | | |
| 687 | + | |
687 | 688 | | |
688 | 689 | | |
689 | 690 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
210 | 210 | | |
211 | 211 | | |
212 | 212 | | |
| 213 | + | |
213 | 214 | | |
214 | 215 | | |
| 216 | + | |
215 | 217 | | |
216 | 218 | | |
217 | 219 | | |
| |||
448 | 450 | | |
449 | 451 | | |
450 | 452 | | |
| 453 | + | |
451 | 454 | | |
452 | 455 | | |
| 456 | + | |
453 | 457 | | |
454 | 458 | | |
455 | 459 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
55 | 55 | | |
56 | 56 | | |
57 | 57 | | |
58 | | - | |
| 58 | + | |
59 | 59 | | |
60 | 60 | | |
61 | 61 | | |
| |||
645 | 645 | | |
646 | 646 | | |
647 | 647 | | |
648 | | - | |
| 648 | + | |
649 | 649 | | |
650 | 650 | | |
651 | 651 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
77 | 77 | | |
78 | 78 | | |
79 | 79 | | |
80 | | - | |
| 80 | + | |
81 | 81 | | |
82 | 82 | | |
83 | 83 | | |
| |||
1729 | 1729 | | |
1730 | 1730 | | |
1731 | 1731 | | |
1732 | | - | |
| 1732 | + | |
1733 | 1733 | | |
1734 | 1734 | | |
1735 | 1735 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
70 | 70 | | |
71 | 71 | | |
72 | 72 | | |
73 | | - | |
| 73 | + | |
74 | 74 | | |
75 | 75 | | |
76 | 76 | | |
| |||
585 | 585 | | |
586 | 586 | | |
587 | 587 | | |
588 | | - | |
| 588 | + | |
589 | 589 | | |
590 | 590 | | |
591 | 591 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
64 | 64 | | |
65 | 65 | | |
66 | 66 | | |
67 | | - | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
68 | 73 | | |
69 | 74 | | |
70 | 75 | | |
| |||
100 | 105 | | |
101 | 106 | | |
102 | 107 | | |
| 108 | + | |
103 | 109 | | |
| 110 | + | |
104 | 111 | | |
105 | 112 | | |
106 | 113 | | |
| |||
3873 | 3880 | | |
3874 | 3881 | | |
3875 | 3882 | | |
3876 | | - | |
| 3883 | + | |
3877 | 3884 | | |
3878 | 3885 | | |
3879 | 3886 | | |
| |||
3945 | 3952 | | |
3946 | 3953 | | |
3947 | 3954 | | |
3948 | | - | |
| 3955 | + | |
| 3956 | + | |
| 3957 | + | |
| 3958 | + | |
| 3959 | + | |
3949 | 3960 | | |
3950 | 3961 | | |
3951 | 3962 | | |
| |||
4006 | 4017 | | |
4007 | 4018 | | |
4008 | 4019 | | |
| 4020 | + | |
| 4021 | + | |
| 4022 | + | |
| 4023 | + | |
| 4024 | + | |
| 4025 | + | |
| 4026 | + | |
| 4027 | + | |
| 4028 | + | |
4009 | 4029 | | |
4010 | 4030 | | |
4011 | 4031 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
37 | | - | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
38 | 43 | | |
39 | 44 | | |
40 | 45 | | |
| |||
1724 | 1729 | | |
1725 | 1730 | | |
1726 | 1731 | | |
| 1732 | + | |
| 1733 | + | |
| 1734 | + | |
| 1735 | + | |
| 1736 | + | |
| 1737 | + | |
1727 | 1738 | | |
1728 | 1739 | | |
1729 | 1740 | | |
| |||
1796 | 1807 | | |
1797 | 1808 | | |
1798 | 1809 | | |
| 1810 | + | |
| 1811 | + | |
| 1812 | + | |
| 1813 | + | |
| 1814 | + | |
| 1815 | + | |
| 1816 | + | |
1799 | 1817 | | |
1800 | 1818 | | |
1801 | 1819 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
89 | 89 | | |
90 | 90 | | |
91 | 91 | | |
92 | | - | |
| 92 | + | |
93 | 93 | | |
94 | 94 | | |
95 | 95 | | |
| |||
1729 | 1729 | | |
1730 | 1730 | | |
1731 | 1731 | | |
1732 | | - | |
| 1732 | + | |
1733 | 1733 | | |
1734 | 1734 | | |
1735 | 1735 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
85 | 85 | | |
86 | 86 | | |
87 | 87 | | |
88 | | - | |
| 88 | + | |
89 | 89 | | |
90 | 90 | | |
91 | 91 | | |
| |||
327 | 327 | | |
328 | 328 | | |
329 | 329 | | |
330 | | - | |
| 330 | + | |
331 | 331 | | |
332 | 332 | | |
333 | 333 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
57 | 57 | | |
58 | 58 | | |
59 | 59 | | |
60 | | - | |
| 60 | + | |
61 | 61 | | |
62 | 62 | | |
63 | 63 | | |
| |||
887 | 887 | | |
888 | 888 | | |
889 | 889 | | |
890 | | - | |
| 890 | + | |
891 | 891 | | |
892 | 892 | | |
893 | 893 | | |
| |||
0 commit comments