kalibr 1.2.3__tar.gz → 1.2.4__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.4/PKG-INFO +233 -0
- kalibr-1.2.4/README.md +166 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/__init__.py +2 -0
- kalibr-1.2.4/kalibr/router.py +370 -0
- kalibr-1.2.4/kalibr.egg-info/PKG-INFO +233 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr.egg-info/SOURCES.txt +5 -1
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr_langchain/__init__.py +3 -1
- kalibr-1.2.4/kalibr_langchain/chat_model.py +103 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/pyproject.toml +1 -1
- kalibr-1.2.4/tests/test_langchain_routing.py +122 -0
- kalibr-1.2.4/tests/test_router.py +56 -0
- kalibr-1.2.3/PKG-INFO +0 -384
- kalibr-1.2.3/README.md +0 -317
- kalibr-1.2.3/kalibr.egg-info/PKG-INFO +0 -384
- {kalibr-1.2.3 → kalibr-1.2.4}/LICENSE +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/__main__.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/capsule_middleware.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/cli/__init__.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/cli/capsule_cmd.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/cli/deploy_cmd.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/cli/main.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/cli/run.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/cli/serve.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/client.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/collector.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/context.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/cost_adapter.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/decorators.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/instrumentation/__init__.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/instrumentation/anthropic_instr.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/instrumentation/base.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/instrumentation/google_instr.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/instrumentation/openai_instr.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/instrumentation/registry.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/intelligence.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/kalibr.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/kalibr_app.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/middleware/__init__.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/middleware/auto_tracer.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/models.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/redaction.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/schemas.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/simple_tracer.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/tokens.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/trace_capsule.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/trace_models.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/tracer.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/types.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr/utils.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr.egg-info/dependency_links.txt +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr.egg-info/entry_points.txt +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr.egg-info/requires.txt +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr.egg-info/top_level.txt +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr_crewai/__init__.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr_crewai/callbacks.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr_crewai/instrumentor.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr_langchain/async_callback.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr_langchain/callback.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr_openai_agents/__init__.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/kalibr_openai_agents/processor.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/setup.cfg +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/tests/test_capsule_builder.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/tests/test_instrumentation.py +0 -0
- {kalibr-1.2.3 → kalibr-1.2.4}/tests/test_intelligence.py +0 -0
kalibr-1.2.4/PKG-INFO
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
|
+
Name: kalibr
|
|
3
|
+
Version: 1.2.4
|
|
4
|
+
Summary: Unified LLM Observability & Multi-Model AI Integration Framework - Deploy to GPT, Claude, Gemini, Copilot with full telemetry.
|
|
5
|
+
Author-email: Kalibr Team <support@kalibr.systems>
|
|
6
|
+
License: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/kalibr-ai/kalibr-sdk-python
|
|
8
|
+
Project-URL: Documentation, https://kalibr.systems/docs
|
|
9
|
+
Project-URL: Repository, https://github.com/kalibr-ai/kalibr-sdk-python
|
|
10
|
+
Project-URL: Issues, https://github.com/kalibr-ai/kalibr-sdk-python/issues
|
|
11
|
+
Keywords: ai,mcp,gpt,claude,gemini,copilot,openai,anthropic,google,microsoft,observability,telemetry,tracing,llm,schema-generation,api,multi-model,langchain,crewai
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
23
|
+
Requires-Python: >=3.9
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: httpx>=0.27.0
|
|
27
|
+
Requires-Dist: tiktoken>=0.8.0
|
|
28
|
+
Requires-Dist: fastapi>=0.110.1
|
|
29
|
+
Requires-Dist: uvicorn>=0.25.0
|
|
30
|
+
Requires-Dist: pydantic>=2.6.4
|
|
31
|
+
Requires-Dist: typer>=0.9.0
|
|
32
|
+
Requires-Dist: python-multipart>=0.0.9
|
|
33
|
+
Requires-Dist: rich>=10.0.0
|
|
34
|
+
Requires-Dist: requests>=2.31.0
|
|
35
|
+
Requires-Dist: opentelemetry-api>=1.20.0
|
|
36
|
+
Requires-Dist: opentelemetry-sdk>=1.20.0
|
|
37
|
+
Requires-Dist: opentelemetry-exporter-otlp>=1.20.0
|
|
38
|
+
Provides-Extra: langchain
|
|
39
|
+
Requires-Dist: langchain-core>=0.1.0; extra == "langchain"
|
|
40
|
+
Provides-Extra: langchain-openai
|
|
41
|
+
Requires-Dist: langchain-core>=0.1.0; extra == "langchain-openai"
|
|
42
|
+
Requires-Dist: langchain-openai>=0.1.0; extra == "langchain-openai"
|
|
43
|
+
Provides-Extra: langchain-anthropic
|
|
44
|
+
Requires-Dist: langchain-core>=0.1.0; extra == "langchain-anthropic"
|
|
45
|
+
Requires-Dist: langchain-anthropic>=0.1.0; extra == "langchain-anthropic"
|
|
46
|
+
Provides-Extra: langchain-google
|
|
47
|
+
Requires-Dist: langchain-core>=0.1.0; extra == "langchain-google"
|
|
48
|
+
Requires-Dist: langchain-google-genai>=0.0.10; extra == "langchain-google"
|
|
49
|
+
Provides-Extra: langchain-all
|
|
50
|
+
Requires-Dist: langchain-core>=0.1.0; extra == "langchain-all"
|
|
51
|
+
Requires-Dist: langchain-openai>=0.1.0; extra == "langchain-all"
|
|
52
|
+
Requires-Dist: langchain-anthropic>=0.1.0; extra == "langchain-all"
|
|
53
|
+
Requires-Dist: langchain-google-genai>=0.0.10; extra == "langchain-all"
|
|
54
|
+
Provides-Extra: crewai
|
|
55
|
+
Requires-Dist: crewai>=0.28.0; extra == "crewai"
|
|
56
|
+
Provides-Extra: openai-agents
|
|
57
|
+
Requires-Dist: openai-agents>=0.0.3; extra == "openai-agents"
|
|
58
|
+
Provides-Extra: integrations
|
|
59
|
+
Requires-Dist: langchain-core>=0.1.0; extra == "integrations"
|
|
60
|
+
Requires-Dist: crewai>=0.28.0; extra == "integrations"
|
|
61
|
+
Requires-Dist: openai-agents>=0.0.3; extra == "integrations"
|
|
62
|
+
Provides-Extra: dev
|
|
63
|
+
Requires-Dist: pytest>=7.4.0; extra == "dev"
|
|
64
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
65
|
+
Requires-Dist: black>=23.0.0; extra == "dev"
|
|
66
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
67
|
+
|
|
68
|
+
# Kalibr SDK
|
|
69
|
+
|
|
70
|
+
**Intelligent routing for AI agents.** Kalibr picks the best model for each request, learns from outcomes, and shifts traffic to what works.
|
|
71
|
+
|
|
72
|
+
## Installation
|
|
73
|
+
```bash
|
|
74
|
+
pip install kalibr
|
|
75
|
+
```
|
|
76
|
+
```bash
|
|
77
|
+
export KALIBR_API_KEY=kal_xxx # Get from dashboard.kalibr.dev
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Quick Start
|
|
81
|
+
```python
|
|
82
|
+
from kalibr import Router
|
|
83
|
+
|
|
84
|
+
router = Router(
|
|
85
|
+
goal="book_meeting",
|
|
86
|
+
paths=["gpt-4o", "claude-3-sonnet", "gpt-4o-mini"],
|
|
87
|
+
success_when=lambda output: "confirmed" in output.lower()
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
response = router.completion(
|
|
91
|
+
messages=[{"role": "user", "content": "Book a meeting with John tomorrow"}]
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
print(response.choices[0].message.content)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
That's it. Kalibr handles:
|
|
98
|
+
- ✅ Picking the best model (Thompson Sampling)
|
|
99
|
+
- ✅ Making the API call
|
|
100
|
+
- ✅ Checking success
|
|
101
|
+
- ✅ Learning for next time
|
|
102
|
+
- ✅ Tracing everything
|
|
103
|
+
|
|
104
|
+
## How It Works
|
|
105
|
+
|
|
106
|
+
1. **Define a goal** - What is your agent trying to do?
|
|
107
|
+
2. **Register paths** - Which models/tools can achieve it?
|
|
108
|
+
3. **Report outcomes** - Did it work?
|
|
109
|
+
4. **Kalibr routes** - Traffic shifts to winners
|
|
110
|
+
|
|
111
|
+
## Paths
|
|
112
|
+
|
|
113
|
+
A path is a model + optional tools + optional params:
|
|
114
|
+
```python
|
|
115
|
+
# Simple: just models
|
|
116
|
+
paths = ["gpt-4o", "claude-3-sonnet"]
|
|
117
|
+
|
|
118
|
+
# With tools
|
|
119
|
+
paths = [
|
|
120
|
+
{"model": "gpt-4o", "tools": ["web_search"]},
|
|
121
|
+
{"model": "claude-3-sonnet", "tools": ["web_search", "browser"]},
|
|
122
|
+
]
|
|
123
|
+
|
|
124
|
+
# With params
|
|
125
|
+
paths = [
|
|
126
|
+
{"model": "gpt-4o", "params": {"temperature": 0.7}},
|
|
127
|
+
{"model": "gpt-4o", "params": {"temperature": 0.2}},
|
|
128
|
+
]
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Success Criteria
|
|
132
|
+
|
|
133
|
+
### Auto-detect from output
|
|
134
|
+
```python
|
|
135
|
+
router = Router(
|
|
136
|
+
goal="summarize",
|
|
137
|
+
paths=["gpt-4o", "claude-3-sonnet"],
|
|
138
|
+
success_when=lambda output: len(output) > 100
|
|
139
|
+
)
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Manual reporting
|
|
143
|
+
```python
|
|
144
|
+
router = Router(goal="book_meeting", paths=["gpt-4o", "claude-3-sonnet"])
|
|
145
|
+
|
|
146
|
+
response = router.completion(messages=[...])
|
|
147
|
+
|
|
148
|
+
# Your verification logic
|
|
149
|
+
meeting_created = check_calendar_api()
|
|
150
|
+
|
|
151
|
+
router.report(success=meeting_created)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Framework Integration
|
|
155
|
+
|
|
156
|
+
### LangChain
|
|
157
|
+
```python
|
|
158
|
+
from kalibr import Router
|
|
159
|
+
|
|
160
|
+
router = Router(goal="summarize", paths=["gpt-4o", "claude-3-sonnet"])
|
|
161
|
+
llm = router.as_langchain()
|
|
162
|
+
|
|
163
|
+
chain = prompt | llm | parser
|
|
164
|
+
result = chain.invoke({"text": "..."})
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### CrewAI
|
|
168
|
+
```python
|
|
169
|
+
from kalibr import Router
|
|
170
|
+
|
|
171
|
+
router = Router(goal="research", paths=["gpt-4o", "claude-3-sonnet"])
|
|
172
|
+
|
|
173
|
+
agent = Agent(
|
|
174
|
+
role="Researcher",
|
|
175
|
+
llm=router.as_langchain(),
|
|
176
|
+
...
|
|
177
|
+
)
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Observability (Included)
|
|
181
|
+
|
|
182
|
+
Every call is automatically traced:
|
|
183
|
+
|
|
184
|
+
- Token counts and costs
|
|
185
|
+
- Latency (p50, p95, p99)
|
|
186
|
+
- Tool usage
|
|
187
|
+
- Errors with stack traces
|
|
188
|
+
|
|
189
|
+
View in the [dashboard](https://dashboard.kalibr.dev) or use callback handlers directly:
|
|
190
|
+
```python
|
|
191
|
+
from kalibr_langchain import KalibrCallbackHandler
|
|
192
|
+
|
|
193
|
+
handler = KalibrCallbackHandler()
|
|
194
|
+
chain.invoke({"input": "..."}, config={"callbacks": [handler]})
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Pricing
|
|
198
|
+
|
|
199
|
+
| Tier | Routing Decisions | Price |
|
|
200
|
+
|------|-------------------|-------|
|
|
201
|
+
| Free | 1,000/month | $0 |
|
|
202
|
+
| Pro | 50,000/month | $49/month |
|
|
203
|
+
| Enterprise | Unlimited | Custom |
|
|
204
|
+
|
|
205
|
+
## API Reference
|
|
206
|
+
|
|
207
|
+
### Router
|
|
208
|
+
```python
|
|
209
|
+
Router(
|
|
210
|
+
goal: str, # Required: name of the goal
|
|
211
|
+
paths: List[str | dict], # Models/tools to route between
|
|
212
|
+
success_when: Callable, # Optional: auto-evaluate success
|
|
213
|
+
exploration_rate: float, # Optional: 0.0-1.0, default 0.1
|
|
214
|
+
)
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Methods
|
|
218
|
+
```python
|
|
219
|
+
router.completion(messages, **kwargs) # Make routed request
|
|
220
|
+
router.report(success, reason=None) # Report outcome manually
|
|
221
|
+
router.add_path(model, tools=None) # Add path dynamically
|
|
222
|
+
router.as_langchain() # Get LangChain-compatible LLM
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Links
|
|
226
|
+
|
|
227
|
+
- [Documentation](https://docs.kalibr.dev)
|
|
228
|
+
- [Dashboard](https://dashboard.kalibr.dev)
|
|
229
|
+
- [GitHub](https://github.com/kalibr-ai/kalibr-sdk-python)
|
|
230
|
+
|
|
231
|
+
## License
|
|
232
|
+
|
|
233
|
+
MIT
|
kalibr-1.2.4/README.md
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# Kalibr SDK
|
|
2
|
+
|
|
3
|
+
**Intelligent routing for AI agents.** Kalibr picks the best model for each request, learns from outcomes, and shifts traffic to what works.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
```bash
|
|
7
|
+
pip install kalibr
|
|
8
|
+
```
|
|
9
|
+
```bash
|
|
10
|
+
export KALIBR_API_KEY=kal_xxx # Get from dashboard.kalibr.dev
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
```python
|
|
15
|
+
from kalibr import Router
|
|
16
|
+
|
|
17
|
+
router = Router(
|
|
18
|
+
goal="book_meeting",
|
|
19
|
+
paths=["gpt-4o", "claude-3-sonnet", "gpt-4o-mini"],
|
|
20
|
+
success_when=lambda output: "confirmed" in output.lower()
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
response = router.completion(
|
|
24
|
+
messages=[{"role": "user", "content": "Book a meeting with John tomorrow"}]
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
print(response.choices[0].message.content)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
That's it. Kalibr handles:
|
|
31
|
+
- ✅ Picking the best model (Thompson Sampling)
|
|
32
|
+
- ✅ Making the API call
|
|
33
|
+
- ✅ Checking success
|
|
34
|
+
- ✅ Learning for next time
|
|
35
|
+
- ✅ Tracing everything
|
|
36
|
+
|
|
37
|
+
## How It Works
|
|
38
|
+
|
|
39
|
+
1. **Define a goal** - What is your agent trying to do?
|
|
40
|
+
2. **Register paths** - Which models/tools can achieve it?
|
|
41
|
+
3. **Report outcomes** - Did it work?
|
|
42
|
+
4. **Kalibr routes** - Traffic shifts to winners
|
|
43
|
+
|
|
44
|
+
## Paths
|
|
45
|
+
|
|
46
|
+
A path is a model + optional tools + optional params:
|
|
47
|
+
```python
|
|
48
|
+
# Simple: just models
|
|
49
|
+
paths = ["gpt-4o", "claude-3-sonnet"]
|
|
50
|
+
|
|
51
|
+
# With tools
|
|
52
|
+
paths = [
|
|
53
|
+
{"model": "gpt-4o", "tools": ["web_search"]},
|
|
54
|
+
{"model": "claude-3-sonnet", "tools": ["web_search", "browser"]},
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
# With params
|
|
58
|
+
paths = [
|
|
59
|
+
{"model": "gpt-4o", "params": {"temperature": 0.7}},
|
|
60
|
+
{"model": "gpt-4o", "params": {"temperature": 0.2}},
|
|
61
|
+
]
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Success Criteria
|
|
65
|
+
|
|
66
|
+
### Auto-detect from output
|
|
67
|
+
```python
|
|
68
|
+
router = Router(
|
|
69
|
+
goal="summarize",
|
|
70
|
+
paths=["gpt-4o", "claude-3-sonnet"],
|
|
71
|
+
success_when=lambda output: len(output) > 100
|
|
72
|
+
)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Manual reporting
|
|
76
|
+
```python
|
|
77
|
+
router = Router(goal="book_meeting", paths=["gpt-4o", "claude-3-sonnet"])
|
|
78
|
+
|
|
79
|
+
response = router.completion(messages=[...])
|
|
80
|
+
|
|
81
|
+
# Your verification logic
|
|
82
|
+
meeting_created = check_calendar_api()
|
|
83
|
+
|
|
84
|
+
router.report(success=meeting_created)
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Framework Integration
|
|
88
|
+
|
|
89
|
+
### LangChain
|
|
90
|
+
```python
|
|
91
|
+
from kalibr import Router
|
|
92
|
+
|
|
93
|
+
router = Router(goal="summarize", paths=["gpt-4o", "claude-3-sonnet"])
|
|
94
|
+
llm = router.as_langchain()
|
|
95
|
+
|
|
96
|
+
chain = prompt | llm | parser
|
|
97
|
+
result = chain.invoke({"text": "..."})
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### CrewAI
|
|
101
|
+
```python
|
|
102
|
+
from kalibr import Router
|
|
103
|
+
|
|
104
|
+
router = Router(goal="research", paths=["gpt-4o", "claude-3-sonnet"])
|
|
105
|
+
|
|
106
|
+
agent = Agent(
|
|
107
|
+
role="Researcher",
|
|
108
|
+
llm=router.as_langchain(),
|
|
109
|
+
...
|
|
110
|
+
)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Observability (Included)
|
|
114
|
+
|
|
115
|
+
Every call is automatically traced:
|
|
116
|
+
|
|
117
|
+
- Token counts and costs
|
|
118
|
+
- Latency (p50, p95, p99)
|
|
119
|
+
- Tool usage
|
|
120
|
+
- Errors with stack traces
|
|
121
|
+
|
|
122
|
+
View in the [dashboard](https://dashboard.kalibr.dev) or use callback handlers directly:
|
|
123
|
+
```python
|
|
124
|
+
from kalibr_langchain import KalibrCallbackHandler
|
|
125
|
+
|
|
126
|
+
handler = KalibrCallbackHandler()
|
|
127
|
+
chain.invoke({"input": "..."}, config={"callbacks": [handler]})
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Pricing
|
|
131
|
+
|
|
132
|
+
| Tier | Routing Decisions | Price |
|
|
133
|
+
|------|-------------------|-------|
|
|
134
|
+
| Free | 1,000/month | $0 |
|
|
135
|
+
| Pro | 50,000/month | $49/month |
|
|
136
|
+
| Enterprise | Unlimited | Custom |
|
|
137
|
+
|
|
138
|
+
## API Reference
|
|
139
|
+
|
|
140
|
+
### Router
|
|
141
|
+
```python
|
|
142
|
+
Router(
|
|
143
|
+
goal: str, # Required: name of the goal
|
|
144
|
+
paths: List[str | dict], # Models/tools to route between
|
|
145
|
+
success_when: Callable, # Optional: auto-evaluate success
|
|
146
|
+
exploration_rate: float, # Optional: 0.0-1.0, default 0.1
|
|
147
|
+
)
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Methods
|
|
151
|
+
```python
|
|
152
|
+
router.completion(messages, **kwargs) # Make routed request
|
|
153
|
+
router.report(success, reason=None) # Report outcome manually
|
|
154
|
+
router.add_path(model, tools=None) # Add path dynamically
|
|
155
|
+
router.as_langchain() # Get LangChain-compatible LLM
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Links
|
|
159
|
+
|
|
160
|
+
- [Documentation](https://docs.kalibr.dev)
|
|
161
|
+
- [Dashboard](https://dashboard.kalibr.dev)
|
|
162
|
+
- [GitHub](https://github.com/kalibr-ai/kalibr-sdk-python)
|
|
163
|
+
|
|
164
|
+
## License
|
|
165
|
+
|
|
166
|
+
MIT
|
|
@@ -92,6 +92,7 @@ from .intelligence import (
|
|
|
92
92
|
register_path,
|
|
93
93
|
decide,
|
|
94
94
|
)
|
|
95
|
+
from .router import Router
|
|
95
96
|
|
|
96
97
|
if os.getenv("KALIBR_AUTO_INSTRUMENT", "true").lower() == "true":
|
|
97
98
|
# Setup OpenTelemetry collector
|
|
@@ -163,4 +164,5 @@ __all__ = [
|
|
|
163
164
|
"get_recommendation",
|
|
164
165
|
"register_path",
|
|
165
166
|
"decide",
|
|
167
|
+
"Router",
|
|
166
168
|
]
|