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.
- litellm_haystack-1.2.0/CHANGELOG.md +31 -0
- {litellm_haystack-1.1.1 → litellm_haystack-1.2.0}/PKG-INFO +2 -2
- {litellm_haystack-1.1.1 → litellm_haystack-1.2.0}/pyproject.toml +3 -1
- {litellm_haystack-1.1.1 → litellm_haystack-1.2.0}/src/haystack_integrations/components/generators/litellm/chat/chat_generator.py +4 -8
- {litellm_haystack-1.1.1 → litellm_haystack-1.2.0}/tests/test_litellm_chat_generator.py +28 -8
- litellm_haystack-1.1.1/CHANGELOG.md +0 -16
- {litellm_haystack-1.1.1 → litellm_haystack-1.2.0}/.gitignore +0 -0
- {litellm_haystack-1.1.1 → litellm_haystack-1.2.0}/LICENSE.txt +0 -0
- {litellm_haystack-1.1.1 → litellm_haystack-1.2.0}/README.md +0 -0
- {litellm_haystack-1.1.1 → litellm_haystack-1.2.0}/pydoc/config_docusaurus.yml +0 -0
- {litellm_haystack-1.1.1 → litellm_haystack-1.2.0}/src/haystack_integrations/components/generators/litellm/__init__.py +0 -0
- {litellm_haystack-1.1.1 → litellm_haystack-1.2.0}/src/haystack_integrations/components/generators/litellm/chat/__init__.py +0 -0
- {litellm_haystack-1.1.1 → litellm_haystack-1.2.0}/src/haystack_integrations/components/generators/py.typed +0 -0
- {litellm_haystack-1.1.1 → litellm_haystack-1.2.0}/tests/__init__.py +0 -0
|
@@ -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.
|
|
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<
|
|
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
|
-
|
|
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,
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 -->
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|