Commit a3c3a01
authored
fix: enable fine-grained tool streaming when include_partial_messages=True (#644)
## Problem
When `include_partial_messages=True`, the SDK passes
`--include-partial-messages` to the CLI, which tells the CLI to emit
`stream_event` messages. However, tool input parameters are still
**buffered by the API** and never streamed — `input_json_delta` events
are withheld until the entire tool input is assembled.
**Root cause:** CLI v2.1.40 (shipped Feb 10 2026) removed the always-on
`fine-grained-tool-streaming-2025-05-14` beta header and replaced it
with two opt-in paths:
1. A GrowthBook feature flag (`tengu_fgts`, default: `false`)
2. The `CLAUDE_CODE_ENABLE_FINE_GRAINED_TOOL_STREAMING` env var → sets
`eager_input_streaming: true` per-tool in the API request
The SDK was never updated to set the env var, so
`include_partial_messages=True` silently stopped delivering tool input
deltas for users without the GrowthBook flag.
**Regression window:** **v0.1.36** (released Feb 13 2026, bundled CLI
2.1.42) through present. Last working version: **v0.1.35** (bundled CLI
2.1.39).
Fixes #608. Same fix applied to the TypeScript SDK in parallel.
## Fix
When `include_partial_messages=True`, inject
`CLAUDE_CODE_ENABLE_FINE_GRAINED_TOOL_STREAMING=1` into the subprocess
environment via `setdefault` (user-supplied values take precedence).
## Tests
Three new unit tests in `test_transport.py`:
- `include_partial_messages=True` → env var set to `"1"`
- `include_partial_messages=False` → env var not set
- User-supplied value in `options.env` is respected
```
$ python -m pytest tests/test_transport.py -v -k fgts
tests/test_transport.py::TestSubprocessCLITransport::test_include_partial_messages_enables_fgts PASSED
tests/test_transport.py::TestSubprocessCLITransport::test_include_partial_messages_false_does_not_set_fgts PASSED
tests/test_transport.py::TestSubprocessCLITransport::test_user_can_override_fgts_env_var PASSED
3 passed in 0.35s
```
## Live E2E verification
Ran against the bundled CLI (v2.1.49, post-regression) with fix applied
— confirmed `input_json_delta` events stream through the wire:
```
$ env -u CLAUDECODE PYTHONPATH=src python e2e_fgts.py
Running E2E FGTS test...
Prompt: "Use the Bash tool to run: echo 'Fine-grained tool streaming test'"
input_json_delta [ 1]: ''
input_json_delta [ 2]: '{"command":'
input_json_delta [ 3]: ' "echo'
input_json_delta [ 4]: ' \'Fine-gra'
input_json_delta [ 5]: 'ined tool st'
input_json_delta [ 6]: 'reamin'
input_json_delta [ 7]: 'g tes'
input_json_delta [ 8]: 't\'"}'
Total stream_event messages: 23
input_json_delta events: 8
Assembled tool input JSON: '{"command": "echo \'Fine-grained tool streaming test\'"}'
PASS: tool input deltas streamed correctly
```
**Note:** The "before" (broken) path cannot be demonstrated on this
account because the `tengu_fgts` GrowthBook flag is currently on for
authenticated users, which is the second condition in the CLI's FGTS
check:
```typescript
if (getFeatureValue_CACHED_MAY_BE_STALE('tengu_fgts', false) || // on for us
isEnvTruthy(process.env.CLAUDE_CODE_ENABLE_FINE_GRAINED_TOOL_STREAMING)) {
schema.eager_input_streaming = true
}
```
The fix matters for users where the GrowthBook flag is off (the default
is `false`).1 parent f7e5955 commit a3c3a01
File tree
2 files changed
+141
-0
lines changed- src/claude_agent_sdk/_internal/transport
- tests
2 files changed
+141
-0
lines changedLines changed: 9 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
354 | 354 | | |
355 | 355 | | |
356 | 356 | | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
357 | 366 | | |
358 | 367 | | |
359 | 368 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
883 | 883 | | |
884 | 884 | | |
885 | 885 | | |
| 886 | + | |
| 887 | + | |
| 888 | + | |
| 889 | + | |
| 890 | + | |
| 891 | + | |
| 892 | + | |
| 893 | + | |
| 894 | + | |
| 895 | + | |
| 896 | + | |
| 897 | + | |
| 898 | + | |
| 899 | + | |
| 900 | + | |
| 901 | + | |
| 902 | + | |
| 903 | + | |
| 904 | + | |
| 905 | + | |
| 906 | + | |
| 907 | + | |
| 908 | + | |
| 909 | + | |
| 910 | + | |
| 911 | + | |
| 912 | + | |
| 913 | + | |
| 914 | + | |
| 915 | + | |
| 916 | + | |
| 917 | + | |
| 918 | + | |
| 919 | + | |
| 920 | + | |
| 921 | + | |
| 922 | + | |
| 923 | + | |
| 924 | + | |
| 925 | + | |
| 926 | + | |
| 927 | + | |
| 928 | + | |
| 929 | + | |
| 930 | + | |
| 931 | + | |
| 932 | + | |
| 933 | + | |
| 934 | + | |
| 935 | + | |
| 936 | + | |
| 937 | + | |
| 938 | + | |
| 939 | + | |
| 940 | + | |
| 941 | + | |
| 942 | + | |
| 943 | + | |
| 944 | + | |
| 945 | + | |
| 946 | + | |
| 947 | + | |
| 948 | + | |
| 949 | + | |
| 950 | + | |
| 951 | + | |
| 952 | + | |
| 953 | + | |
| 954 | + | |
| 955 | + | |
| 956 | + | |
| 957 | + | |
| 958 | + | |
| 959 | + | |
| 960 | + | |
| 961 | + | |
| 962 | + | |
| 963 | + | |
| 964 | + | |
| 965 | + | |
| 966 | + | |
| 967 | + | |
| 968 | + | |
| 969 | + | |
| 970 | + | |
| 971 | + | |
| 972 | + | |
| 973 | + | |
| 974 | + | |
| 975 | + | |
| 976 | + | |
| 977 | + | |
| 978 | + | |
| 979 | + | |
| 980 | + | |
| 981 | + | |
| 982 | + | |
| 983 | + | |
| 984 | + | |
| 985 | + | |
| 986 | + | |
| 987 | + | |
| 988 | + | |
| 989 | + | |
| 990 | + | |
| 991 | + | |
| 992 | + | |
| 993 | + | |
| 994 | + | |
| 995 | + | |
| 996 | + | |
| 997 | + | |
| 998 | + | |
| 999 | + | |
| 1000 | + | |
| 1001 | + | |
| 1002 | + | |
| 1003 | + | |
| 1004 | + | |
| 1005 | + | |
| 1006 | + | |
| 1007 | + | |
| 1008 | + | |
| 1009 | + | |
| 1010 | + | |
| 1011 | + | |
| 1012 | + | |
| 1013 | + | |
| 1014 | + | |
| 1015 | + | |
| 1016 | + | |
| 1017 | + | |
886 | 1018 | | |
887 | 1019 | | |
888 | 1020 | | |
| |||
0 commit comments