kalibr 1.2.11__tar.gz → 1.4.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.
- {kalibr-1.2.11 → kalibr-1.4.0}/PKG-INFO +15 -5
- {kalibr-1.2.11 → kalibr-1.4.0}/README.md +11 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/router.py +71 -25
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/tokens.py +20 -5
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr.egg-info/PKG-INFO +15 -5
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr.egg-info/requires.txt +3 -1
- {kalibr-1.2.11 → kalibr-1.4.0}/pyproject.toml +6 -5
- {kalibr-1.2.11 → kalibr-1.4.0}/LICENSE +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/__init__.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/__main__.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/capsule_middleware.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/cli/__init__.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/cli/capsule_cmd.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/cli/deploy_cmd.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/cli/main.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/cli/run.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/cli/serve.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/client.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/collector.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/context.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/cost_adapter.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/decorators.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/instrumentation/__init__.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/instrumentation/anthropic_instr.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/instrumentation/base.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/instrumentation/google_instr.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/instrumentation/openai_instr.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/instrumentation/registry.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/intelligence.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/kalibr.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/kalibr_app.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/middleware/__init__.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/middleware/auto_tracer.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/models.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/pricing.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/redaction.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/schemas.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/simple_tracer.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/trace_capsule.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/trace_models.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/tracer.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/types.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr/utils.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr.egg-info/SOURCES.txt +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr.egg-info/dependency_links.txt +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr.egg-info/entry_points.txt +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr.egg-info/top_level.txt +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr_crewai/__init__.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr_crewai/callbacks.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr_crewai/instrumentor.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr_langchain/__init__.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr_langchain/async_callback.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr_langchain/callback.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr_langchain/chat_model.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr_openai_agents/__init__.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/kalibr_openai_agents/processor.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/setup.cfg +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/tests/test_capsule_builder.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/tests/test_cost_adapter.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/tests/test_http_client_leak.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/tests/test_instrumentation.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/tests/test_intelligence.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/tests/test_langchain_routing.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/tests/test_pricing.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/tests/test_router.py +0 -0
- {kalibr-1.2.11 → kalibr-1.4.0}/tests/test_thread_safety.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: kalibr
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0
|
|
4
4
|
Summary: Adaptive routing for AI agents. Learns which models work best and routes automatically.
|
|
5
5
|
Author-email: Kalibr Team <support@kalibr.systems>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -13,18 +13,15 @@ Classifier: Development Status :: 4 - Beta
|
|
|
13
13
|
Classifier: Intended Audience :: Developers
|
|
14
14
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
15
15
|
Classifier: Programming Language :: Python :: 3
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
18
16
|
Classifier: Programming Language :: Python :: 3.10
|
|
19
17
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
18
|
Classifier: Programming Language :: Python :: 3.12
|
|
21
19
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
20
|
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
23
|
-
Requires-Python: >=3.
|
|
21
|
+
Requires-Python: >=3.10
|
|
24
22
|
Description-Content-Type: text/markdown
|
|
25
23
|
License-File: LICENSE
|
|
26
24
|
Requires-Dist: httpx>=0.27.0
|
|
27
|
-
Requires-Dist: tiktoken>=0.8.0
|
|
28
25
|
Requires-Dist: fastapi>=0.110.1
|
|
29
26
|
Requires-Dist: uvicorn>=0.25.0
|
|
30
27
|
Requires-Dist: pydantic>=2.6.4
|
|
@@ -35,6 +32,8 @@ Requires-Dist: requests>=2.31.0
|
|
|
35
32
|
Requires-Dist: opentelemetry-api>=1.20.0
|
|
36
33
|
Requires-Dist: opentelemetry-sdk>=1.20.0
|
|
37
34
|
Requires-Dist: opentelemetry-exporter-otlp>=1.20.0
|
|
35
|
+
Provides-Extra: tokens
|
|
36
|
+
Requires-Dist: tiktoken>=0.8.0; extra == "tokens"
|
|
38
37
|
Provides-Extra: langchain
|
|
39
38
|
Requires-Dist: langchain-core>=0.1.0; extra == "langchain"
|
|
40
39
|
Provides-Extra: langchain-openai
|
|
@@ -73,11 +72,21 @@ Adaptive routing for AI agents. Kalibr learns which models work best for your ta
|
|
|
73
72
|
[](https://pypi.org/project/kalibr/)
|
|
74
73
|
[](LICENSE)
|
|
75
74
|
|
|
75
|
+
## Requirements
|
|
76
|
+
|
|
77
|
+
- Python 3.10 or higher
|
|
78
|
+
- pip 21.0 or higher
|
|
79
|
+
|
|
76
80
|
## Installation
|
|
77
81
|
```bash
|
|
78
82
|
pip install kalibr
|
|
79
83
|
```
|
|
80
84
|
|
|
85
|
+
For accurate token counting, install with:
|
|
86
|
+
```bash
|
|
87
|
+
pip install kalibr[tokens]
|
|
88
|
+
```
|
|
89
|
+
|
|
81
90
|
## Setup
|
|
82
91
|
|
|
83
92
|
Get your credentials from [dashboard.kalibr.systems/settings](https://dashboard.kalibr.systems/settings), then:
|
|
@@ -259,6 +268,7 @@ report_outcome(trace_id="...", goal="book_meeting", success=True)
|
|
|
259
268
|
|
|
260
269
|
## Other Integrations
|
|
261
270
|
```bash
|
|
271
|
+
pip install kalibr[tokens] # Accurate token counting (tiktoken)
|
|
262
272
|
pip install kalibr[crewai] # CrewAI
|
|
263
273
|
pip install kalibr[openai-agents] # OpenAI Agents SDK
|
|
264
274
|
pip install kalibr[langchain-all] # LangChain with all providers
|
|
@@ -6,11 +6,21 @@ Adaptive routing for AI agents. Kalibr learns which models work best for your ta
|
|
|
6
6
|
[](https://pypi.org/project/kalibr/)
|
|
7
7
|
[](LICENSE)
|
|
8
8
|
|
|
9
|
+
## Requirements
|
|
10
|
+
|
|
11
|
+
- Python 3.10 or higher
|
|
12
|
+
- pip 21.0 or higher
|
|
13
|
+
|
|
9
14
|
## Installation
|
|
10
15
|
```bash
|
|
11
16
|
pip install kalibr
|
|
12
17
|
```
|
|
13
18
|
|
|
19
|
+
For accurate token counting, install with:
|
|
20
|
+
```bash
|
|
21
|
+
pip install kalibr[tokens]
|
|
22
|
+
```
|
|
23
|
+
|
|
14
24
|
## Setup
|
|
15
25
|
|
|
16
26
|
Get your credentials from [dashboard.kalibr.systems/settings](https://dashboard.kalibr.systems/settings), then:
|
|
@@ -192,6 +202,7 @@ report_outcome(trace_id="...", goal="book_meeting", success=True)
|
|
|
192
202
|
|
|
193
203
|
## Other Integrations
|
|
194
204
|
```bash
|
|
205
|
+
pip install kalibr[tokens] # Accurate token counting (tiktoken)
|
|
195
206
|
pip install kalibr[crewai] # CrewAI
|
|
196
207
|
pip install kalibr[openai-agents] # OpenAI Agents SDK
|
|
197
208
|
pip install kalibr[langchain-all] # LangChain with all providers
|
|
@@ -260,34 +260,80 @@ class Router:
|
|
|
260
260
|
else:
|
|
261
261
|
router_span.set_attribute("kalibr.fallback", True)
|
|
262
262
|
|
|
263
|
-
# Step 5:
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
263
|
+
# Step 5: Build ordered candidate paths for fallback
|
|
264
|
+
# First: intelligence-selected path, then remaining registered paths
|
|
265
|
+
candidate_paths = []
|
|
266
|
+
selected_path = {"model": model_id, "tools": tool_id, "params": params}
|
|
267
|
+
candidate_paths.append(selected_path)
|
|
268
|
+
|
|
269
|
+
# Add remaining paths, skipping duplicates of the selected model
|
|
270
|
+
for path in self._paths:
|
|
271
|
+
if path["model"] != model_id:
|
|
272
|
+
candidate_paths.append(path)
|
|
273
|
+
|
|
274
|
+
# Step 6: Try each candidate path with fallback
|
|
275
|
+
from kalibr.intelligence import report_outcome
|
|
276
|
+
|
|
277
|
+
last_exception = None
|
|
278
|
+
for i, candidate in enumerate(candidate_paths):
|
|
279
|
+
candidate_model = candidate["model"]
|
|
280
|
+
candidate_tools = candidate.get("tools")
|
|
281
|
+
candidate_params = candidate.get("params") or {}
|
|
282
|
+
|
|
283
|
+
is_fallback = (i > 0)
|
|
284
|
+
if is_fallback:
|
|
285
|
+
logger.warning(f"Primary path failed, trying fallback: {candidate_model}")
|
|
286
|
+
|
|
287
|
+
try:
|
|
288
|
+
response = self._dispatch(
|
|
289
|
+
candidate_model,
|
|
290
|
+
messages,
|
|
291
|
+
candidate_tools,
|
|
292
|
+
**{**candidate_params, **kwargs}
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
# Success! Update state to reflect which model succeeded
|
|
296
|
+
self._last_model_id = candidate_model
|
|
297
|
+
|
|
298
|
+
# Auto-report success if success_when provided
|
|
299
|
+
if self.success_when and not self._outcome_reported:
|
|
300
|
+
try:
|
|
301
|
+
output = response.choices[0].message.content or ""
|
|
302
|
+
success = self.success_when(output)
|
|
303
|
+
self.report(success=success)
|
|
304
|
+
except Exception as e:
|
|
305
|
+
logger.warning(f"Auto-outcome evaluation failed: {e}")
|
|
306
|
+
|
|
307
|
+
# Add trace_id to response for explicit linkage
|
|
308
|
+
response.kalibr_trace_id = trace_id
|
|
309
|
+
return response
|
|
310
|
+
|
|
311
|
+
except Exception as e:
|
|
312
|
+
last_exception = e
|
|
313
|
+
|
|
314
|
+
# Log the failure with model name and error
|
|
315
|
+
logger.warning(f"Model {candidate_model} failed: {type(e).__name__}: {e}")
|
|
316
|
+
|
|
317
|
+
# Report failure for this path to enable Thompson Sampling learning
|
|
269
318
|
try:
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
319
|
+
report_outcome(
|
|
320
|
+
trace_id=trace_id,
|
|
321
|
+
goal=self.goal,
|
|
322
|
+
success=False,
|
|
323
|
+
failure_reason=f"provider_error: {type(e).__name__}",
|
|
324
|
+
model_id=candidate_model,
|
|
325
|
+
)
|
|
326
|
+
except Exception:
|
|
327
|
+
pass
|
|
275
328
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
return response
|
|
329
|
+
# Continue to next candidate
|
|
330
|
+
continue
|
|
279
331
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
if not self._outcome_reported:
|
|
286
|
-
try:
|
|
287
|
-
self.report(success=False, reason=f"provider_error: {type(e).__name__}")
|
|
288
|
-
except:
|
|
289
|
-
pass
|
|
290
|
-
raise
|
|
332
|
+
# All paths failed - set error attributes and raise
|
|
333
|
+
router_span.set_attribute("error", True)
|
|
334
|
+
router_span.set_attribute("error.type", type(last_exception).__name__)
|
|
335
|
+
self._outcome_reported = True # Prevent double-reporting on raise
|
|
336
|
+
raise last_exception
|
|
291
337
|
|
|
292
338
|
def report(
|
|
293
339
|
self,
|
|
@@ -2,13 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
from typing import Optional
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
# Import tiktoken optionally for token counting
|
|
6
|
+
try:
|
|
7
|
+
import tiktoken
|
|
8
|
+
HAS_TIKTOKEN = True
|
|
9
|
+
except ImportError:
|
|
10
|
+
HAS_TIKTOKEN = False
|
|
6
11
|
|
|
7
12
|
# Cache for tokenizer instances
|
|
8
13
|
_tokenizer_cache = {}
|
|
9
14
|
|
|
10
15
|
|
|
11
|
-
def count_tokens(text: str, model_id: str) -> int:
|
|
16
|
+
def count_tokens(text: str, model_id: str = "gpt-4o") -> int:
|
|
12
17
|
"""Count tokens for given text and model.
|
|
13
18
|
|
|
14
19
|
Args:
|
|
@@ -16,11 +21,15 @@ def count_tokens(text: str, model_id: str) -> int:
|
|
|
16
21
|
model_id: Model identifier
|
|
17
22
|
|
|
18
23
|
Returns:
|
|
19
|
-
Token count (approximate)
|
|
24
|
+
Token count (approximate if tiktoken is not installed)
|
|
20
25
|
"""
|
|
21
26
|
if not text:
|
|
22
27
|
return 0
|
|
23
28
|
|
|
29
|
+
if not HAS_TIKTOKEN:
|
|
30
|
+
# Fallback: rough estimate of 4 chars per token
|
|
31
|
+
return len(text) // 4
|
|
32
|
+
|
|
24
33
|
# Try to get exact tokenizer for OpenAI models
|
|
25
34
|
if "gpt" in model_id.lower():
|
|
26
35
|
try:
|
|
@@ -34,7 +43,13 @@ def count_tokens(text: str, model_id: str) -> int:
|
|
|
34
43
|
|
|
35
44
|
|
|
36
45
|
def get_openai_encoding(model_id: str):
|
|
37
|
-
"""Get tiktoken encoding for OpenAI model.
|
|
46
|
+
"""Get tiktoken encoding for OpenAI model.
|
|
47
|
+
|
|
48
|
+
Returns None if tiktoken is not installed.
|
|
49
|
+
"""
|
|
50
|
+
if not HAS_TIKTOKEN:
|
|
51
|
+
return None
|
|
52
|
+
|
|
38
53
|
if model_id in _tokenizer_cache:
|
|
39
54
|
return _tokenizer_cache[model_id]
|
|
40
55
|
|
|
@@ -48,5 +63,5 @@ def get_openai_encoding(model_id: str):
|
|
|
48
63
|
_tokenizer_cache[model_id] = encoding
|
|
49
64
|
return encoding
|
|
50
65
|
except Exception as e:
|
|
51
|
-
print(f"
|
|
66
|
+
print(f"Warning: Failed to load tokenizer for {model_id}: {e}")
|
|
52
67
|
raise
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: kalibr
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0
|
|
4
4
|
Summary: Adaptive routing for AI agents. Learns which models work best and routes automatically.
|
|
5
5
|
Author-email: Kalibr Team <support@kalibr.systems>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -13,18 +13,15 @@ Classifier: Development Status :: 4 - Beta
|
|
|
13
13
|
Classifier: Intended Audience :: Developers
|
|
14
14
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
15
15
|
Classifier: Programming Language :: Python :: 3
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
18
16
|
Classifier: Programming Language :: Python :: 3.10
|
|
19
17
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
18
|
Classifier: Programming Language :: Python :: 3.12
|
|
21
19
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
20
|
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
23
|
-
Requires-Python: >=3.
|
|
21
|
+
Requires-Python: >=3.10
|
|
24
22
|
Description-Content-Type: text/markdown
|
|
25
23
|
License-File: LICENSE
|
|
26
24
|
Requires-Dist: httpx>=0.27.0
|
|
27
|
-
Requires-Dist: tiktoken>=0.8.0
|
|
28
25
|
Requires-Dist: fastapi>=0.110.1
|
|
29
26
|
Requires-Dist: uvicorn>=0.25.0
|
|
30
27
|
Requires-Dist: pydantic>=2.6.4
|
|
@@ -35,6 +32,8 @@ Requires-Dist: requests>=2.31.0
|
|
|
35
32
|
Requires-Dist: opentelemetry-api>=1.20.0
|
|
36
33
|
Requires-Dist: opentelemetry-sdk>=1.20.0
|
|
37
34
|
Requires-Dist: opentelemetry-exporter-otlp>=1.20.0
|
|
35
|
+
Provides-Extra: tokens
|
|
36
|
+
Requires-Dist: tiktoken>=0.8.0; extra == "tokens"
|
|
38
37
|
Provides-Extra: langchain
|
|
39
38
|
Requires-Dist: langchain-core>=0.1.0; extra == "langchain"
|
|
40
39
|
Provides-Extra: langchain-openai
|
|
@@ -73,11 +72,21 @@ Adaptive routing for AI agents. Kalibr learns which models work best for your ta
|
|
|
73
72
|
[](https://pypi.org/project/kalibr/)
|
|
74
73
|
[](LICENSE)
|
|
75
74
|
|
|
75
|
+
## Requirements
|
|
76
|
+
|
|
77
|
+
- Python 3.10 or higher
|
|
78
|
+
- pip 21.0 or higher
|
|
79
|
+
|
|
76
80
|
## Installation
|
|
77
81
|
```bash
|
|
78
82
|
pip install kalibr
|
|
79
83
|
```
|
|
80
84
|
|
|
85
|
+
For accurate token counting, install with:
|
|
86
|
+
```bash
|
|
87
|
+
pip install kalibr[tokens]
|
|
88
|
+
```
|
|
89
|
+
|
|
81
90
|
## Setup
|
|
82
91
|
|
|
83
92
|
Get your credentials from [dashboard.kalibr.systems/settings](https://dashboard.kalibr.systems/settings), then:
|
|
@@ -259,6 +268,7 @@ report_outcome(trace_id="...", goal="book_meeting", success=True)
|
|
|
259
268
|
|
|
260
269
|
## Other Integrations
|
|
261
270
|
```bash
|
|
271
|
+
pip install kalibr[tokens] # Accurate token counting (tiktoken)
|
|
262
272
|
pip install kalibr[crewai] # CrewAI
|
|
263
273
|
pip install kalibr[openai-agents] # OpenAI Agents SDK
|
|
264
274
|
pip install kalibr[langchain-all] # LangChain with all providers
|
|
@@ -4,11 +4,11 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "kalibr"
|
|
7
|
-
version = "1.
|
|
7
|
+
version = "1.4.0"
|
|
8
8
|
description = "Adaptive routing for AI agents. Learns which models work best and routes automatically."
|
|
9
9
|
authors = [{name = "Kalibr Team", email = "support@kalibr.systems"}]
|
|
10
10
|
readme = "README.md"
|
|
11
|
-
requires-python = ">=3.
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
12
|
license = {text = "Apache-2.0"}
|
|
13
13
|
keywords = [
|
|
14
14
|
"ai", "mcp", "gpt", "claude", "gemini", "copilot",
|
|
@@ -21,8 +21,6 @@ classifiers = [
|
|
|
21
21
|
"Intended Audience :: Developers",
|
|
22
22
|
"License :: OSI Approved :: Apache Software License",
|
|
23
23
|
"Programming Language :: Python :: 3",
|
|
24
|
-
"Programming Language :: Python :: 3.8",
|
|
25
|
-
"Programming Language :: Python :: 3.9",
|
|
26
24
|
"Programming Language :: Python :: 3.10",
|
|
27
25
|
"Programming Language :: Python :: 3.11",
|
|
28
26
|
"Programming Language :: Python :: 3.12",
|
|
@@ -31,7 +29,6 @@ classifiers = [
|
|
|
31
29
|
]
|
|
32
30
|
dependencies = [
|
|
33
31
|
"httpx>=0.27.0",
|
|
34
|
-
"tiktoken>=0.8.0",
|
|
35
32
|
"fastapi>=0.110.1",
|
|
36
33
|
"uvicorn>=0.25.0",
|
|
37
34
|
"pydantic>=2.6.4",
|
|
@@ -46,6 +43,10 @@ dependencies = [
|
|
|
46
43
|
]
|
|
47
44
|
|
|
48
45
|
[project.optional-dependencies]
|
|
46
|
+
# Token counting (optional - for accurate token counts)
|
|
47
|
+
tokens = [
|
|
48
|
+
"tiktoken>=0.8.0",
|
|
49
|
+
]
|
|
49
50
|
# LangChain integration
|
|
50
51
|
langchain = [
|
|
51
52
|
"langchain-core>=0.1.0",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|