kalibr 1.1.3a0__py3-none-any.whl → 1.4.0__py3-none-any.whl
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/__init__.py +41 -3
- kalibr/cli/capsule_cmd.py +3 -3
- kalibr/cli/main.py +3 -3
- kalibr/cli/run.py +2 -2
- kalibr/client.py +1 -1
- kalibr/collector.py +227 -48
- kalibr/context.py +42 -0
- kalibr/cost_adapter.py +36 -104
- kalibr/instrumentation/anthropic_instr.py +34 -40
- kalibr/instrumentation/base.py +27 -9
- kalibr/instrumentation/google_instr.py +34 -39
- kalibr/instrumentation/openai_instr.py +34 -28
- kalibr/instrumentation/registry.py +38 -13
- kalibr/intelligence.py +662 -0
- kalibr/middleware/auto_tracer.py +1 -1
- kalibr/pricing.py +245 -0
- kalibr/router.py +545 -0
- kalibr/simple_tracer.py +16 -15
- kalibr/tokens.py +20 -5
- kalibr/trace_capsule.py +19 -12
- kalibr/utils.py +2 -2
- kalibr-1.4.0.dist-info/LICENSE +190 -0
- kalibr-1.4.0.dist-info/METADATA +306 -0
- kalibr-1.4.0.dist-info/RECORD +52 -0
- {kalibr-1.1.3a0.dist-info → kalibr-1.4.0.dist-info}/WHEEL +1 -1
- kalibr_crewai/__init__.py +1 -1
- kalibr_crewai/callbacks.py +122 -14
- kalibr_crewai/instrumentor.py +196 -33
- kalibr_langchain/__init__.py +4 -2
- kalibr_langchain/callback.py +26 -0
- kalibr_langchain/chat_model.py +103 -0
- kalibr_openai_agents/__init__.py +1 -1
- kalibr-1.1.3a0.dist-info/METADATA +0 -236
- kalibr-1.1.3a0.dist-info/RECORD +0 -48
- kalibr-1.1.3a0.dist-info/licenses/LICENSE +0 -21
- {kalibr-1.1.3a0.dist-info → kalibr-1.4.0.dist-info}/entry_points.txt +0 -0
- {kalibr-1.1.3a0.dist-info → kalibr-1.4.0.dist-info}/top_level.txt +0 -0
|
@@ -3,18 +3,25 @@ Instrumentation Registry
|
|
|
3
3
|
|
|
4
4
|
Handles auto-discovery and registration of LLM SDK instrumentations.
|
|
5
5
|
Provides a central place to manage which SDKs are instrumented.
|
|
6
|
+
|
|
7
|
+
Thread-safe registry using locks to protect shared state.
|
|
6
8
|
"""
|
|
7
9
|
|
|
8
10
|
import os
|
|
11
|
+
import threading
|
|
9
12
|
from typing import Dict, List, Set
|
|
10
13
|
|
|
11
14
|
# Track which providers have been instrumented
|
|
12
15
|
_instrumented_providers: Set[str] = set()
|
|
16
|
+
# Lock to protect concurrent access to the registry
|
|
17
|
+
_registry_lock = threading.Lock()
|
|
13
18
|
|
|
14
19
|
|
|
15
20
|
def auto_instrument(providers: List[str] = None) -> Dict[str, bool]:
|
|
16
21
|
"""
|
|
17
22
|
Auto-discover and instrument LLM SDKs
|
|
23
|
+
|
|
24
|
+
Thread-safe: Uses internal lock to protect registry state.
|
|
18
25
|
|
|
19
26
|
Args:
|
|
20
27
|
providers: List of provider names to instrument.
|
|
@@ -35,10 +42,11 @@ def auto_instrument(providers: List[str] = None) -> Dict[str, bool]:
|
|
|
35
42
|
for provider in providers:
|
|
36
43
|
provider_lower = provider.lower()
|
|
37
44
|
|
|
38
|
-
#
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
45
|
+
# Check if already instrumented (thread-safe read)
|
|
46
|
+
with _registry_lock:
|
|
47
|
+
if provider_lower in _instrumented_providers:
|
|
48
|
+
results[provider_lower] = True
|
|
49
|
+
continue
|
|
42
50
|
|
|
43
51
|
try:
|
|
44
52
|
if provider_lower == "openai":
|
|
@@ -47,7 +55,8 @@ def auto_instrument(providers: List[str] = None) -> Dict[str, bool]:
|
|
|
47
55
|
success = openai_instr.instrument()
|
|
48
56
|
results[provider_lower] = success
|
|
49
57
|
if success:
|
|
50
|
-
|
|
58
|
+
with _registry_lock:
|
|
59
|
+
_instrumented_providers.add(provider_lower)
|
|
51
60
|
print(f"✅ Instrumented OpenAI SDK")
|
|
52
61
|
|
|
53
62
|
elif provider_lower == "anthropic":
|
|
@@ -56,7 +65,8 @@ def auto_instrument(providers: List[str] = None) -> Dict[str, bool]:
|
|
|
56
65
|
success = anthropic_instr.instrument()
|
|
57
66
|
results[provider_lower] = success
|
|
58
67
|
if success:
|
|
59
|
-
|
|
68
|
+
with _registry_lock:
|
|
69
|
+
_instrumented_providers.add(provider_lower)
|
|
60
70
|
print(f"✅ Instrumented Anthropic SDK")
|
|
61
71
|
|
|
62
72
|
elif provider_lower == "google":
|
|
@@ -65,7 +75,8 @@ def auto_instrument(providers: List[str] = None) -> Dict[str, bool]:
|
|
|
65
75
|
success = google_instr.instrument()
|
|
66
76
|
results[provider_lower] = success
|
|
67
77
|
if success:
|
|
68
|
-
|
|
78
|
+
with _registry_lock:
|
|
79
|
+
_instrumented_providers.add(provider_lower)
|
|
69
80
|
print(f"✅ Instrumented Google Generative AI SDK")
|
|
70
81
|
|
|
71
82
|
else:
|
|
@@ -85,6 +96,8 @@ def auto_instrument(providers: List[str] = None) -> Dict[str, bool]:
|
|
|
85
96
|
def uninstrument_all() -> Dict[str, bool]:
|
|
86
97
|
"""
|
|
87
98
|
Remove instrumentation from all previously instrumented SDKs
|
|
99
|
+
|
|
100
|
+
Thread-safe: Uses internal lock to protect registry state.
|
|
88
101
|
|
|
89
102
|
Returns:
|
|
90
103
|
Dictionary mapping provider names to uninstrumentation success status
|
|
@@ -92,7 +105,10 @@ def uninstrument_all() -> Dict[str, bool]:
|
|
|
92
105
|
global _instrumented_providers
|
|
93
106
|
|
|
94
107
|
results = {}
|
|
95
|
-
|
|
108
|
+
|
|
109
|
+
# Get snapshot of providers to uninstrument (thread-safe)
|
|
110
|
+
with _registry_lock:
|
|
111
|
+
providers_to_uninstrument = list(_instrumented_providers)
|
|
96
112
|
|
|
97
113
|
for provider in providers_to_uninstrument:
|
|
98
114
|
try:
|
|
@@ -102,7 +118,8 @@ def uninstrument_all() -> Dict[str, bool]:
|
|
|
102
118
|
success = openai_instr.uninstrument()
|
|
103
119
|
results[provider] = success
|
|
104
120
|
if success:
|
|
105
|
-
|
|
121
|
+
with _registry_lock:
|
|
122
|
+
_instrumented_providers.discard(provider)
|
|
106
123
|
print(f"✅ Uninstrumented OpenAI SDK")
|
|
107
124
|
|
|
108
125
|
elif provider == "anthropic":
|
|
@@ -111,7 +128,8 @@ def uninstrument_all() -> Dict[str, bool]:
|
|
|
111
128
|
success = anthropic_instr.uninstrument()
|
|
112
129
|
results[provider] = success
|
|
113
130
|
if success:
|
|
114
|
-
|
|
131
|
+
with _registry_lock:
|
|
132
|
+
_instrumented_providers.discard(provider)
|
|
115
133
|
print(f"✅ Uninstrumented Anthropic SDK")
|
|
116
134
|
|
|
117
135
|
elif provider == "google":
|
|
@@ -120,7 +138,8 @@ def uninstrument_all() -> Dict[str, bool]:
|
|
|
120
138
|
success = google_instr.uninstrument()
|
|
121
139
|
results[provider] = success
|
|
122
140
|
if success:
|
|
123
|
-
|
|
141
|
+
with _registry_lock:
|
|
142
|
+
_instrumented_providers.discard(provider)
|
|
124
143
|
print(f"✅ Uninstrumented Google Generative AI SDK")
|
|
125
144
|
|
|
126
145
|
except Exception as e:
|
|
@@ -133,16 +152,21 @@ def uninstrument_all() -> Dict[str, bool]:
|
|
|
133
152
|
def get_instrumented_providers() -> List[str]:
|
|
134
153
|
"""
|
|
135
154
|
Get list of currently instrumented providers
|
|
155
|
+
|
|
156
|
+
Thread-safe: Returns a snapshot of the current state.
|
|
136
157
|
|
|
137
158
|
Returns:
|
|
138
159
|
List of provider names that are currently instrumented
|
|
139
160
|
"""
|
|
140
|
-
|
|
161
|
+
with _registry_lock:
|
|
162
|
+
return list(_instrumented_providers)
|
|
141
163
|
|
|
142
164
|
|
|
143
165
|
def is_instrumented(provider: str) -> bool:
|
|
144
166
|
"""
|
|
145
167
|
Check if a specific provider is instrumented
|
|
168
|
+
|
|
169
|
+
Thread-safe: Protected by internal lock.
|
|
146
170
|
|
|
147
171
|
Args:
|
|
148
172
|
provider: Provider name to check
|
|
@@ -150,4 +174,5 @@ def is_instrumented(provider: str) -> bool:
|
|
|
150
174
|
Returns:
|
|
151
175
|
True if provider is instrumented, False otherwise
|
|
152
176
|
"""
|
|
153
|
-
|
|
177
|
+
with _registry_lock:
|
|
178
|
+
return provider.lower() in _instrumented_providers
|