litellm-haystack 1.1.1__tar.gz → 1.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,31 @@
1
+ # Changelog
2
+
3
+ ## [integrations/litellm-v1.1.2] - 2026-07-15
4
+
5
+ ### 🧹 Chores
6
+
7
+ - Cap litellm below 1.92.0
8
+
9
+
10
+ ## [integrations/litellm-v1.1.1] - 2026-07-15
11
+
12
+ ### 🧹 Chores
13
+
14
+ - Support sync streaming callbacks in async contexts for Haystack 2.x/3.x compatibility (#3534)
15
+ - Update litellm dependency version in pyproject.toml (#3599)
16
+
17
+
18
+ ## [integrations/litellm-v1.1.0] - 2026-06-04
19
+
20
+ ### 🚀 Features
21
+
22
+ - LiteLLM - accept str as ChatGenerator input (#3393)
23
+
24
+
25
+ ## [integrations/litellm-v1.0.0] - 2026-05-29
26
+
27
+ ### 🚀 Features
28
+
29
+ - Add LiteLLM integration with LiteLLMChatGenerator component (#3257)
30
+
31
+ <!-- generated by git-cliff -->
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: litellm-haystack
3
- Version: 1.1.1
3
+ Version: 1.2.0
4
4
  Summary: An integration of LiteLLM AI gateway into the Haystack framework, routing to 100+ LLM providers.
5
5
  Project-URL: Documentation, https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/litellm#readme
6
6
  Project-URL: Issues, https://github.com/deepset-ai/haystack-core-integrations/issues
@@ -20,7 +20,7 @@ Classifier: Programming Language :: Python :: 3.14
20
20
  Classifier: Programming Language :: Python :: Implementation :: CPython
21
21
  Requires-Python: >=3.10
22
22
  Requires-Dist: haystack-ai>=2.30.0
23
- Requires-Dist: litellm<2.0,>=1.84.0
23
+ Requires-Dist: litellm<1.92.0,>=1.84.0
24
24
  Description-Content-Type: text/markdown
25
25
 
26
26
  # litellm-haystack
@@ -22,7 +22,9 @@ classifiers = [
22
22
  "Programming Language :: Python :: 3.14",
23
23
  "Programming Language :: Python :: Implementation :: CPython",
24
24
  ]
25
- dependencies = ["haystack-ai>=2.30.0", "litellm>=1.84.0,<2.0"]
25
+ # litellm capped below 1.92.0: that release ships cp310-cp313-only compiled wheels
26
+ # (source build fails on Python 3.14) and imports fastapi (proxy extra) on any tool call
27
+ dependencies = ["haystack-ai>=2.30.0", "litellm>=1.84.0,<1.92.0"]
26
28
 
27
29
  [project.urls]
28
30
  Documentation = "https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/litellm#readme"
@@ -266,16 +266,12 @@ _FINISH_REASON_MAPPING: dict[str, FinishReason] = {
266
266
  }
267
267
 
268
268
 
269
- def _extract_usage(obj: Any) -> dict[str, int]:
269
+ def _extract_usage(obj: Any) -> dict[str, Any]:
270
270
  """Pull token usage off a litellm response or chunk, tolerating its absence."""
271
271
  usage = getattr(obj, "usage", None)
272
- if not usage:
273
- return {}
274
- return {
275
- "prompt_tokens": getattr(usage, "prompt_tokens", 0),
276
- "completion_tokens": getattr(usage, "completion_tokens", 0),
277
- "total_tokens": getattr(usage, "total_tokens", 0),
278
- }
272
+ if usage is not None and hasattr(usage, "model_dump"):
273
+ return usage.model_dump(exclude_none=True)
274
+ return {}
279
275
 
280
276
 
281
277
  def _build_chat_message(response: Any, choice: Any) -> ChatMessage:
@@ -13,6 +13,7 @@ import pytest
13
13
  from haystack.dataclasses import ChatMessage, StreamingChunk
14
14
  from haystack.tools import Tool
15
15
  from haystack.utils.auth import Secret
16
+ from litellm.types.utils import Usage
16
17
 
17
18
  from haystack_integrations.components.generators.litellm import LiteLLMChatGenerator
18
19
 
@@ -29,14 +30,9 @@ def _make_mock_response(content="Hello!", model="openai/gpt-4o", tool_calls=None
29
30
  choice.index = 0
30
31
  choice.finish_reason = "stop"
31
32
 
32
- usage = MagicMock()
33
- usage.prompt_tokens = 10
34
- usage.completion_tokens = 5
35
- usage.total_tokens = 15
36
-
37
33
  resp = MagicMock()
38
34
  resp.choices = [choice]
39
- resp.usage = usage
35
+ resp.usage = Usage(prompt_tokens=10, completion_tokens=5, total_tokens=15)
40
36
  resp.model = model
41
37
  return resp
42
38
 
@@ -235,6 +231,30 @@ class TestRun:
235
231
  meta = result["replies"][0].meta
236
232
  assert meta["usage"]["prompt_tokens"] == 10
237
233
  assert meta["usage"]["completion_tokens"] == 5
234
+ assert set(meta["usage"]) == {"prompt_tokens", "completion_tokens", "total_tokens"}
235
+
236
+ def test_cache_tokens_in_meta(self):
237
+ gen = LiteLLMChatGenerator(model="anthropic/claude-sonnet-4-20250514")
238
+ mock_resp = _make_mock_response(model="anthropic/claude-sonnet-4-20250514")
239
+ mock_resp.usage = Usage(
240
+ prompt_tokens=2010,
241
+ completion_tokens=5,
242
+ total_tokens=2015,
243
+ cache_creation_input_tokens=1200,
244
+ cache_read_input_tokens=800,
245
+ )
246
+
247
+ fake_litellm = types.ModuleType("litellm")
248
+ fake_litellm.completion = MagicMock(return_value=mock_resp)
249
+
250
+ with mock.patch.dict(sys.modules, {"litellm": fake_litellm}):
251
+ usage = gen.run(messages=[ChatMessage.from_user("hi")])["replies"][0].meta["usage"]
252
+ assert usage["cache_creation_input_tokens"] == 1200
253
+ assert usage["cache_read_input_tokens"] == 800
254
+ assert usage["prompt_tokens"] == 2010
255
+ # litellm also normalizes cache counts into the OpenAI-style nested breakdown
256
+ assert usage["prompt_tokens_details"]["cached_tokens"] == 800
257
+ assert usage["prompt_tokens_details"]["cache_creation_tokens"] == 1200
238
258
 
239
259
  def test_tool_calls_parsed(self):
240
260
  tc = MagicMock()
@@ -258,7 +278,7 @@ class TestRun:
258
278
 
259
279
  def test_streaming_content_accumulated(self):
260
280
  gen = LiteLLMChatGenerator(model="openai/gpt-4o")
261
- usage = SimpleNamespace(prompt_tokens=10, completion_tokens=5, total_tokens=15)
281
+ usage = Usage(prompt_tokens=10, completion_tokens=5, total_tokens=15)
262
282
  chunks = _make_mock_stream_chunks("Hi!", usage=usage)
263
283
 
264
284
  fake_litellm = types.ModuleType("litellm")
@@ -452,7 +472,7 @@ class TestAsync:
452
472
  @pytest.mark.asyncio
453
473
  async def test_run_async_streaming(self):
454
474
  gen = LiteLLMChatGenerator(model="openai/gpt-4o")
455
- usage = SimpleNamespace(prompt_tokens=10, completion_tokens=5, total_tokens=15)
475
+ usage = Usage(prompt_tokens=10, completion_tokens=5, total_tokens=15)
456
476
  chunks = _make_mock_stream_chunks("Hi!", usage=usage)
457
477
 
458
478
  async def _aiter():
@@ -1,16 +0,0 @@
1
- # Changelog
2
-
3
- ## [integrations/litellm-v1.1.0] - 2026-06-04
4
-
5
- ### 🚀 Features
6
-
7
- - LiteLLM - accept str as ChatGenerator input (#3393)
8
-
9
-
10
- ## [integrations/litellm-v1.0.0] - 2026-05-29
11
-
12
- ### 🚀 Features
13
-
14
- - Add LiteLLM integration with LiteLLMChatGenerator component (#3257)
15
-
16
- <!-- generated by git-cliff -->