litellm/tests/test_litellm/llms
Deepanshu Lulla 6684bb343b
perf(streaming): add shared JSONFragmentAccumulator for Vertex and Anthropic (#36610)
* perf(streaming): add shared JSONFragmentAccumulator for Vertex and Anthropic

Vertex's handle_accumulated_json_chunk and Anthropic's
_handle_accumulated_json_chunk each independently accumulated SSE fragments
into a JSON envelope with self.accumulated_json += fragment. Because the
attribute holds a live reference, CPython copies the whole prior buffer on
every fragment, making buffer assembly O(n^2) in total payload size.
Anthropic additionally had no completeness heuristic at all and called
json.loads on the whole buffer after every fragment, and could wedge forever
on two concatenated envelopes.

Add JSONFragmentAccumulator in litellm_core_utils/: fragments append to a
list in O(1), a could_close_json heuristic lets callers skip the join+parse
entirely until a value could plausibly be complete, and pop_next_value peels
one JSON value off the front of the buffer at a time using
json.JSONDecoder().raw_decode, keeping any unconsumed remainder instead of
failing on concatenated values. Migrate both providers onto it; Anthropic's
__next__/__anext__ end-of-stream handlers now delegate to
_handle_accumulated_json_chunk(is_final=True) instead of duplicating the
parse-and-reset logic inline.

Fixes #31861.

* test(streaming): close diff-coverage gaps in JSONFragmentAccumulator migration

Codecov flagged 11 uncovered lines in the migration: the accumulated_json
setter, __next__/__anext__'s end-of-stream drain branches in both providers,
and the pop_next_value "not found" path when a buffer's newest fragment ends
in "}" but is genuinely incomplete (an inner object closed, the outer one
didn't). Add targeted tests for each.

* fix(streaming): make JSONFragmentAccumulator's completeness heuristic O(1)

could_close_json rescanned every preceding blank fragment on each call, so a
hostile upstream that sends malformed JSON (never closing) followed by many
blank keepalive fragments could drive that scan, and the join+parse it
gates, to O(n^2) total. Track the last non-blank fragment's trailing byte
incrementally in append/pop_next_value/set instead of rescanning the buffer.

Reported by automated review on PR #36610.

* fix(streaming): make JSONFragmentAccumulator.pop_next_value O(1) per call

pop_next_value previously rebuilt the full remaining string and sliced a
new remainder on every call, so draining N concatenated JSON values
already sitting in one buffer cost O(n^2) total. Replace the rebuild-and-
slice with a materialize-once cursor: pending fragments are joined into
the buffer only when new ones have arrived since the last pop, and
consumed values are dropped by advancing an offset instead of copying
the remaining string.

* test(streaming): make JSONFragmentAccumulator drain regression test CI-stable

The 80k-value drain test used an absolute ms budget that flaked on a
busier CI runner (233.5ms vs a 150ms budget calibrated on a quiet
machine). Replace it with a doubling-ratio check: draining twice as many
concatenated values should take roughly 2x as long for O(n), not
~4x for O(n^2), and that ratio holds regardless of machine speed.

* test(streaming): suppress TQ002 on the append-laziness spy test

A test-quality gate (TQ002: don't assert only that a mock was called)
landed upstream since this branch's last rebase and now flags
test_append_never_calls_raw_decode. The test verifies append() defers
all decoding to pop_next_value, which has no caller-observable proxy
other than spying on the stdlib call it must avoid making.

* test(vertex): spy on raw_decode instead of json.loads in accumulator regression tests

Post-migration to the shared JSONFragmentAccumulator, Vertex's decode
path goes through json.JSONDecoder.raw_decode, not json.loads. The two
O(n^2)/partial-fragment regression tests still patched json.loads, which
that path never calls, so both passed unconditionally regardless of
whether the underlying implementation regressed. Verified by simulating
an eager-reparse regression: both tests now fail against it and pass
against the correct implementation.

* fix(streaming): widen JSONFragmentAccumulator's whitespace skip to match str.strip()

pop_next_value's whitespace skip only matched json.decoder.WHITESPACE's
ASCII set, narrower than str.strip() (Unicode-aware) which the O(1)-cursor
rewrite replaced. A non-ASCII separator like U+00A0 between two
concatenated JSON values on one SSE line made raw_decode fail on it, and
the buffer never advanced past that byte again, permanently stranding
everything after it for the rest of the stream. Use str.isspace() to
match str.strip()'s tolerance.

---------

Co-authored-by: Deepanshu <deepanshu.lulla@alpha-sense.com>
2026-08-25 16:15:47 -07:00
..
a2a/chat fix(a2a): populate response usage in a2a chat transformation (#31980) 2026-07-03 09:28:36 +05:30
aiml/image_generation test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
amazon_nova/chat test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
anthropic perf(streaming): add shared JSONFragmentAccumulator for Vertex and Anthropic (#36610) 2026-08-25 16:15:47 -07:00
apiserpent test: unwind environment writes in tests/test_litellm with monkeypatch (#37806) 2026-08-21 20:28:37 -07:00
azure Merge pull request #38119 from BerriAI/litellm_bing_grounding_search_provider 2026-08-24 19:33:23 -07:00
azure_ai Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_fix_model_router_spend_log_model 2026-08-25 10:55:53 -07:00
base_llm feat(search): add Grounding with Bing Search (bing_grounding) as a search provider 2026-08-24 11:08:24 -07:00
baseten/chat style: run black formatter on files from main merge 2026-04-17 13:02:59 -07:00
bedrock fix(rerank): emit latency and cost headers on /rerank (#35419) 2026-08-25 15:54:25 -07:00
bedrock_mantle Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_mantle_codex_input_items 2026-08-25 11:56:13 -07:00
black_forest_labs test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
bytez/chat test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
cerebras fix(cerebras): add max_retries and extra_headers to get_supported_openai_params (#36601) 2026-08-25 14:10:56 -07:00
chat test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
chatgpt test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
cloudflare fix(cloudflare): route native Workers AI provider through OpenAI-compatible endpoint (#31053) 2026-06-23 12:09:11 -07:00
cohere test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
cometapi/chat test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
compactifai style: run black formatter on files from main merge 2026-04-17 13:02:59 -07:00
crusoe test: unwind environment writes in tests/test_litellm with monkeypatch (#37806) 2026-08-21 20:28:37 -07:00
custom_httpx fix(rerank): emit latency and cost headers on /rerank (#35419) 2026-08-25 15:54:25 -07:00
dashscope test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
databricks test: separate gemini entries storing the promo rate from those storing list 2026-08-22 17:54:44 -07:00
datarobot test: unwind environment writes in tests/test_litellm with monkeypatch (#37806) 2026-08-21 20:28:37 -07:00
deepgram test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
deepinfra test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
deepseek test: merge three stranded twins into the files that shadow them (#37600) 2026-08-20 14:25:23 -07:00
docker_model_runner test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
elevenlabs test: avoid provider test module name collision 2026-04-29 22:36:57 -07:00
fal_ai test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
fastcrw/search chore(oss): litellm oss staging 150626 (#30463) 2026-06-16 12:06:41 -07:00
featherless_ai/chat test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
fireworks_ai fix(anthropic): stop signing replayed thinking blocks and strip reasoning_content 2026-08-22 14:27:20 -07:00
gdc/chat test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
gemini test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
github_copilot test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
gradient_ai test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
groq fix: omit thinking.type=disabled for always-on thinking Claude models (#37510) 2026-08-21 10:27:26 -07:00
heroku style: run black formatter on files from main merge 2026-04-17 13:02:59 -07:00
hosted_vllm fix(anthropic): stop signing replayed thinking blocks and strip reasoning_content 2026-08-22 14:27:20 -07:00
huggingface test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
inception test: unwind environment writes in tests/test_litellm with monkeypatch (#37806) 2026-08-21 20:28:37 -07:00
jina_ai/embedding test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
langflow test: require a match= on broad pytest.raises, and drop duplicate parametrize cases (#37769) 2026-08-20 20:24:49 -07:00
lemonade test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
litellm_proxy test: remove tests that never execute 2026-08-12 10:45:38 -07:00
llamafile/chat style: run black formatter on files from main merge 2026-04-17 13:02:59 -07:00
lm_studio style: run black formatter on files from main merge 2026-04-17 13:02:59 -07:00
manus test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
meta_llama test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
minimax test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
mistral test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
modelscope test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
moonshot test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
nebius test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
neosantara Litellm oss staging 050626 (#29774) 2026-06-05 13:51:51 -07:00
nimble/search feat(search): add Nimble as a search provider (#36347) 2026-08-14 17:09:58 -07:00
novita/chat test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
nscale/chat test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
nvidia_nim/rerank test: drop rerank package marker colliding with voyage test package 2026-08-11 23:37:27 -07:00
nvidia_riva test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
oci test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
ocr test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
ollama Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_ruff_dead_test_code 2026-08-24 09:46:56 -07:00
oobabooga/chat test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
openai Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_reasoning_effort_capability_v2 2026-08-25 09:28:55 -07:00
openai_like Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_scx_ai_provider 2026-08-21 17:27:49 +10:00
openrouter test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
ovhcloud test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
parallel_ai test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
parasail Litellm oss staging 080626 (#29932) 2026-06-08 13:49:52 -07:00
pass_through test: remove four mirror test files that exercise none of their module 2026-07-25 10:57:19 -07:00
perplexity test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
pg_vector/vector_stores test: require a match= on broad pytest.raises, and drop duplicate parametrize cases (#37769) 2026-08-20 20:24:49 -07:00
publicai test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
ragflow/chat test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
recraft test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
reducto Litellm oss staging 04 21 2026 2 (#26569) 2026-05-20 21:25:19 -07:00
runwayml fix(runwayml): skip progress scaling when Runway returns a null progress 2026-08-24 12:20:00 -07:00
s3_vectors Fix extra body error 2026-04-29 08:34:31 +05:30
sagemaker test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
sambanova Feat/sambanova embeddings (#13308) 2025-08-12 17:15:26 -07:00
sap style: run black formatter on files from main merge 2026-04-17 13:02:59 -07:00
scaleway Feature/add audio support for scaleway (#26110) 2026-04-20 14:49:41 -07:00
snowflake chore(oss): litellm oss staging 120626 (#30292) 2026-06-12 09:49:25 -07:00
soniox chore: litellm oss staging (#30745) 2026-06-18 13:55:35 -07:00
stability test: require a match= on broad pytest.raises, and drop duplicate parametrize cases (#37769) 2026-08-20 20:24:49 -07:00
tencent fix: omit thinking.type=disabled for always-on thinking Claude models (#37510) 2026-08-21 10:27:26 -07:00
tinyfish test: require a match= on broad pytest.raises, and drop duplicate parametrize cases (#37769) 2026-08-20 20:24:49 -07:00
together_ai/chat fix(together_ai): pass tools through for models missing from the registry 2026-08-25 14:38:34 -07:00
valkey/vector_stores feat(vector_stores): add Valkey as a managed vector store provider (#37002) 2026-08-18 21:45:22 +00:00
vercel_ai_gateway test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
vertex_ai perf(streaming): add shared JSONFragmentAccumulator for Vertex and Anthropic (#36610) 2026-08-25 16:15:47 -07:00
volcengine test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
voyage test: require a match= on broad pytest.raises, and drop duplicate parametrize cases (#37769) 2026-08-20 20:24:49 -07:00
wandb test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
watsonx Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_ruff_dead_test_code 2026-08-24 09:46:56 -07:00
xai test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
you_com test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
zai test: stop the zai tests from leaking env and litellm globals into the session (#37834) 2026-08-21 22:10:34 -07:00
test_cache_control_and_reasoning.py test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
test_file_content_block.py Litellm oss staging (#28161) 2026-05-18 16:27:44 -07:00
test_file_search_responses.py fix(tests): use canonical litellm_enterprise import path (#27699) 2026-05-12 12:32:57 -07:00
test_lifecycle_fix.py style: run black formatter on files from main merge 2026-04-17 13:02:59 -07:00
test_polling_url_origin_match.py chore(security): close two unaddressed SSRF cases 2026-05-01 18:43:47 +00:00
test_predibase_transformation.py refactor(predibase): migrate transform_request and transform_response… (#25249) 2026-04-27 08:58:22 +05:30