execlave-sdk 1.0.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.
- execlave_sdk-1.0.0/PKG-INFO +309 -0
- execlave_sdk-1.0.0/README.md +281 -0
- execlave_sdk-1.0.0/execlave/__init__.py +40 -0
- execlave_sdk-1.0.0/execlave/agent.py +204 -0
- execlave_sdk-1.0.0/execlave/client.py +1217 -0
- execlave_sdk-1.0.0/execlave/connectors.py +89 -0
- execlave_sdk-1.0.0/execlave/errors.py +110 -0
- execlave_sdk-1.0.0/execlave/otel.py +149 -0
- execlave_sdk-1.0.0/execlave/trace.py +150 -0
- execlave_sdk-1.0.0/pyproject.toml +52 -0
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: execlave-sdk
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Official Python SDK for the Execlave AI Governance Platform
|
|
5
|
+
Author-email: Execlave <support@execlave.com>
|
|
6
|
+
Requires-Python: >=3.11
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Classifier: Development Status :: 4 - Beta
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
15
|
+
Requires-Dist: requests>=2.33.0
|
|
16
|
+
Requires-Dist: opentelemetry-sdk>=1.20.0 ; extra == "otel"
|
|
17
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.20.0 ; extra == "otel"
|
|
18
|
+
Requires-Dist: python-socketio>=5.0 ; extra == "realtime"
|
|
19
|
+
Requires-Dist: pytest>=7.0 ; extra == "test"
|
|
20
|
+
Requires-Dist: pytest-cov>=4.0 ; extra == "test"
|
|
21
|
+
Project-URL: Documentation, https://www.execlave.com/docs/sdk-reference
|
|
22
|
+
Project-URL: Homepage, https://execlave.com
|
|
23
|
+
Project-URL: Repository, https://github.com/rishitmavani/execlave
|
|
24
|
+
Provides-Extra: otel
|
|
25
|
+
Provides-Extra: realtime
|
|
26
|
+
Provides-Extra: test
|
|
27
|
+
|
|
28
|
+
# Execlave Python SDK
|
|
29
|
+
|
|
30
|
+
Official Python SDK for the **Execlave** AI Governance Platform. Provides tracing, agent registration, prompt-injection scanning, PII scrubbing, and OpenTelemetry integration for AI agents.
|
|
31
|
+
|
|
32
|
+
[](https://python.org)
|
|
33
|
+
[](LICENSE)
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Installation
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
pip install execlave-sdk
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
With OpenTelemetry support:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
pip install execlave-sdk[otel]
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Quick Start
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
from execlave import Execlave
|
|
53
|
+
|
|
54
|
+
# Initialize the SDK
|
|
55
|
+
ag = Execlave(
|
|
56
|
+
api_key="exe_prod_your_key_here", # or set EXECLAVE_API_KEY env var
|
|
57
|
+
base_url="https://api.execlave.com", # defaults to https://api.execlave.com
|
|
58
|
+
environment="production",
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
# Register an agent
|
|
62
|
+
agent = ag.register_agent(
|
|
63
|
+
agent_id="my-assistant",
|
|
64
|
+
name="Customer Support Bot",
|
|
65
|
+
description="Handles tier-1 support queries",
|
|
66
|
+
model="gpt-4o",
|
|
67
|
+
framework="langchain",
|
|
68
|
+
tags=["support", "production"],
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
# Record a trace using the decorator
|
|
72
|
+
@ag.trace
|
|
73
|
+
def answer(question: str) -> str:
|
|
74
|
+
# Your LLM call here
|
|
75
|
+
return llm.invoke(question)
|
|
76
|
+
|
|
77
|
+
result = answer("How do I reset my password?")
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Agent Registration
|
|
81
|
+
|
|
82
|
+
Register agents to monitor them from the Execlave dashboard:
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
agent = ag.register_agent(
|
|
86
|
+
agent_id="order-processor",
|
|
87
|
+
name="Order Processor",
|
|
88
|
+
description="Processes and validates customer orders",
|
|
89
|
+
model="claude-3-sonnet",
|
|
90
|
+
framework="custom",
|
|
91
|
+
tags=["orders", "production"],
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
# Check agent status
|
|
95
|
+
print(agent.status) # "active", "paused", etc.
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Tracing
|
|
99
|
+
|
|
100
|
+
### Decorator
|
|
101
|
+
|
|
102
|
+
The simplest way to trace function calls:
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
@ag.trace
|
|
106
|
+
def process_order(order_data: dict) -> dict:
|
|
107
|
+
result = llm.invoke(json.dumps(order_data))
|
|
108
|
+
return json.loads(result)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Context Manager
|
|
112
|
+
|
|
113
|
+
For more control over trace metadata:
|
|
114
|
+
|
|
115
|
+
```python
|
|
116
|
+
with ag.start_trace(agent_id="my-assistant", session_id="sess_abc") as trace:
|
|
117
|
+
trace.set_input({"question": "What is the refund policy?"})
|
|
118
|
+
|
|
119
|
+
result = llm.invoke("What is the refund policy?")
|
|
120
|
+
|
|
121
|
+
trace.set_output({"answer": result})
|
|
122
|
+
trace.set_model("gpt-4o")
|
|
123
|
+
trace.set_tokens(input=150, output=320)
|
|
124
|
+
trace.set_cost(0.0045)
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Manual Trace
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
trace = ag.start_trace(agent_id="my-assistant")
|
|
131
|
+
trace.set_input(user_query)
|
|
132
|
+
|
|
133
|
+
try:
|
|
134
|
+
response = llm.invoke(user_query)
|
|
135
|
+
trace.set_output(response)
|
|
136
|
+
trace.set_status("success")
|
|
137
|
+
except Exception as e:
|
|
138
|
+
trace.set_error(e)
|
|
139
|
+
finally:
|
|
140
|
+
trace.end()
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Trace Fields
|
|
144
|
+
|
|
145
|
+
| Method | Description |
|
|
146
|
+
| --------------------------- | ------------------------------------ |
|
|
147
|
+
| `set_input(data)` | Input data (auto-serialized) |
|
|
148
|
+
| `set_output(data)` | Output data (auto-serialized) |
|
|
149
|
+
| `set_model(name)` | Model name (e.g., `"gpt-4o"`) |
|
|
150
|
+
| `set_tokens(input, output)` | Token counts |
|
|
151
|
+
| `set_cost(amount)` | Cost in USD |
|
|
152
|
+
| `set_status(status)` | `"success"` or `"error"` |
|
|
153
|
+
| `set_error(exception)` | Records error info from an exception |
|
|
154
|
+
| `set_metadata(dict)` | Arbitrary key-value metadata |
|
|
155
|
+
| `set_duration(ms)` | Override duration in milliseconds |
|
|
156
|
+
|
|
157
|
+
## Privacy & PII Scrubbing
|
|
158
|
+
|
|
159
|
+
Built-in client-side PII scrubbing before data leaves your infrastructure:
|
|
160
|
+
|
|
161
|
+
```python
|
|
162
|
+
ag = Execlave(
|
|
163
|
+
api_key="exe_prod_xxx",
|
|
164
|
+
privacy={
|
|
165
|
+
"scrub_pii": True, # Enable PII detection & redaction
|
|
166
|
+
"scrub_fields": ["input", "output"], # Fields to scan
|
|
167
|
+
},
|
|
168
|
+
)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Detected PII types: email addresses, SSNs, credit card numbers, US phone numbers, IP addresses, API keys.
|
|
172
|
+
|
|
173
|
+
## Prompt Injection Scanning
|
|
174
|
+
|
|
175
|
+
The SDK scans inputs for prompt-injection patterns before sending them to your LLM:
|
|
176
|
+
|
|
177
|
+
```python
|
|
178
|
+
ag = Execlave(
|
|
179
|
+
api_key="exe_prod_xxx",
|
|
180
|
+
enable_injection_scan=True, # Default: True
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
# Traces with detected injection attempts are flagged automatically
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Detected patterns include: "ignore previous instructions", jailbreak attempts, system prompt extraction, and more.
|
|
187
|
+
|
|
188
|
+
## Kill Switch / Pause Support
|
|
189
|
+
|
|
190
|
+
Execlave supports remote agent pausing via the dashboard:
|
|
191
|
+
|
|
192
|
+
```python
|
|
193
|
+
from execlave import AgentPausedError
|
|
194
|
+
|
|
195
|
+
try:
|
|
196
|
+
result = answer("Process this order")
|
|
197
|
+
except AgentPausedError:
|
|
198
|
+
# Agent was paused by an admin — handle gracefully
|
|
199
|
+
return "Service temporarily unavailable"
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
The SDK polls for status changes in the background (configurable interval).
|
|
203
|
+
|
|
204
|
+
## OpenTelemetry Integration
|
|
205
|
+
|
|
206
|
+
Export Execlave traces as OpenTelemetry spans for unified observability:
|
|
207
|
+
|
|
208
|
+
```python
|
|
209
|
+
from execlave import Execlave
|
|
210
|
+
from execlave.otel import configure_otel
|
|
211
|
+
|
|
212
|
+
# Initialize with OTel mode
|
|
213
|
+
ag = Execlave(
|
|
214
|
+
api_key="exe_prod_xxx",
|
|
215
|
+
mode="otel",
|
|
216
|
+
otlp_endpoint="http://localhost:4318", # Your OTel collector
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
# Configure the OTel pipeline
|
|
220
|
+
configure_otel(ag)
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
Requires the `otel` extra: `pip install execlave-sdk[otel]`
|
|
224
|
+
|
|
225
|
+
## Configuration
|
|
226
|
+
|
|
227
|
+
### Constructor Options
|
|
228
|
+
|
|
229
|
+
| Parameter | Type | Default | Description |
|
|
230
|
+
| ------------------------ | ------ | -------------------------- | ---------------------------- |
|
|
231
|
+
| `api_key` | `str` | `EXECLAVE_API_KEY` env | Your Execlave API key |
|
|
232
|
+
| `base_url` | `str` | `https://api.execlave.com` | Execlave API URL |
|
|
233
|
+
| `environment` | `str` | `"production"` | Environment tag |
|
|
234
|
+
| `async_mode` | `bool` | `True` | Non-blocking trace ingestion |
|
|
235
|
+
| `mode` | `str` | `"native"` | `"native"` or `"otel"` |
|
|
236
|
+
| `otlp_endpoint` | `str` | `None` | OTel collector endpoint |
|
|
237
|
+
| `batch_size` | `int` | `100` | Traces per flush batch |
|
|
238
|
+
| `flush_interval_seconds` | `int` | `10` | Seconds between flushes |
|
|
239
|
+
| `debug` | `bool` | `False` | Enable debug logging |
|
|
240
|
+
| `privacy` | `dict` | `{}` | PII scrubbing config |
|
|
241
|
+
| `enable_control_channel` | `bool` | `True` | Enable status polling |
|
|
242
|
+
| `enable_injection_scan` | `bool` | `True` | Enable injection scanning |
|
|
243
|
+
|
|
244
|
+
### Environment Variables
|
|
245
|
+
|
|
246
|
+
| Variable | Description |
|
|
247
|
+
| ------------------- | ------------------------------------- |
|
|
248
|
+
| `EXECLAVE_API_KEY` | API key (alternative to constructor) |
|
|
249
|
+
| `EXECLAVE_BASE_URL` | Base URL (alternative to constructor) |
|
|
250
|
+
|
|
251
|
+
## Error Handling
|
|
252
|
+
|
|
253
|
+
```python
|
|
254
|
+
from execlave import ExeclaveError, ExeclaveAuthError, AgentPausedError
|
|
255
|
+
|
|
256
|
+
try:
|
|
257
|
+
ag = Execlave(api_key="exe_invalid")
|
|
258
|
+
ag.register_agent(agent_id="test")
|
|
259
|
+
except ExeclaveAuthError:
|
|
260
|
+
print("Invalid API key")
|
|
261
|
+
except AgentPausedError:
|
|
262
|
+
print("Agent is paused")
|
|
263
|
+
except ExeclaveError as e:
|
|
264
|
+
print(f"SDK error: {e}")
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## Async Trace Buffer
|
|
268
|
+
|
|
269
|
+
The SDK uses a non-blocking circular buffer (max 10,000 traces) with a background flush thread. Traces are batched and sent to the Execlave API automatically.
|
|
270
|
+
|
|
271
|
+
```python
|
|
272
|
+
# Manual flush (e.g., before shutdown)
|
|
273
|
+
ag.flush()
|
|
274
|
+
|
|
275
|
+
# Graceful shutdown
|
|
276
|
+
ag.shutdown()
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
## Development
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
# Clone the repo
|
|
283
|
+
git clone https://github.com/execlave/sdk-python.git
|
|
284
|
+
cd execlave/sdk-python
|
|
285
|
+
|
|
286
|
+
# Install dev dependencies
|
|
287
|
+
pip install -e ".[test]"
|
|
288
|
+
|
|
289
|
+
# Run tests
|
|
290
|
+
pytest # 130 tests
|
|
291
|
+
pytest --cov=execlave # With coverage
|
|
292
|
+
|
|
293
|
+
# Type checking
|
|
294
|
+
mypy execlave/
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
## Legal
|
|
298
|
+
|
|
299
|
+
By using this SDK, you agree to the [Execlave Terms of Service](https://execlave.com/terms).
|
|
300
|
+
|
|
301
|
+
- [Privacy Policy](https://execlave.com/privacy)
|
|
302
|
+
- [Acceptable Use Policy](https://execlave.com/acceptable-use)
|
|
303
|
+
- [Responsible AI](https://execlave.com/responsible-ai)
|
|
304
|
+
- [Security](https://execlave.com/security)
|
|
305
|
+
|
|
306
|
+
## License
|
|
307
|
+
|
|
308
|
+
MIT — see [LICENSE](../LICENSE) for details.
|
|
309
|
+
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
# Execlave Python SDK
|
|
2
|
+
|
|
3
|
+
Official Python SDK for the **Execlave** AI Governance Platform. Provides tracing, agent registration, prompt-injection scanning, PII scrubbing, and OpenTelemetry integration for AI agents.
|
|
4
|
+
|
|
5
|
+
[](https://python.org)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
pip install execlave-sdk
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
With OpenTelemetry support:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pip install execlave-sdk[otel]
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
from execlave import Execlave
|
|
26
|
+
|
|
27
|
+
# Initialize the SDK
|
|
28
|
+
ag = Execlave(
|
|
29
|
+
api_key="exe_prod_your_key_here", # or set EXECLAVE_API_KEY env var
|
|
30
|
+
base_url="https://api.execlave.com", # defaults to https://api.execlave.com
|
|
31
|
+
environment="production",
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
# Register an agent
|
|
35
|
+
agent = ag.register_agent(
|
|
36
|
+
agent_id="my-assistant",
|
|
37
|
+
name="Customer Support Bot",
|
|
38
|
+
description="Handles tier-1 support queries",
|
|
39
|
+
model="gpt-4o",
|
|
40
|
+
framework="langchain",
|
|
41
|
+
tags=["support", "production"],
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
# Record a trace using the decorator
|
|
45
|
+
@ag.trace
|
|
46
|
+
def answer(question: str) -> str:
|
|
47
|
+
# Your LLM call here
|
|
48
|
+
return llm.invoke(question)
|
|
49
|
+
|
|
50
|
+
result = answer("How do I reset my password?")
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Agent Registration
|
|
54
|
+
|
|
55
|
+
Register agents to monitor them from the Execlave dashboard:
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
agent = ag.register_agent(
|
|
59
|
+
agent_id="order-processor",
|
|
60
|
+
name="Order Processor",
|
|
61
|
+
description="Processes and validates customer orders",
|
|
62
|
+
model="claude-3-sonnet",
|
|
63
|
+
framework="custom",
|
|
64
|
+
tags=["orders", "production"],
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
# Check agent status
|
|
68
|
+
print(agent.status) # "active", "paused", etc.
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Tracing
|
|
72
|
+
|
|
73
|
+
### Decorator
|
|
74
|
+
|
|
75
|
+
The simplest way to trace function calls:
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
@ag.trace
|
|
79
|
+
def process_order(order_data: dict) -> dict:
|
|
80
|
+
result = llm.invoke(json.dumps(order_data))
|
|
81
|
+
return json.loads(result)
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Context Manager
|
|
85
|
+
|
|
86
|
+
For more control over trace metadata:
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
with ag.start_trace(agent_id="my-assistant", session_id="sess_abc") as trace:
|
|
90
|
+
trace.set_input({"question": "What is the refund policy?"})
|
|
91
|
+
|
|
92
|
+
result = llm.invoke("What is the refund policy?")
|
|
93
|
+
|
|
94
|
+
trace.set_output({"answer": result})
|
|
95
|
+
trace.set_model("gpt-4o")
|
|
96
|
+
trace.set_tokens(input=150, output=320)
|
|
97
|
+
trace.set_cost(0.0045)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Manual Trace
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
trace = ag.start_trace(agent_id="my-assistant")
|
|
104
|
+
trace.set_input(user_query)
|
|
105
|
+
|
|
106
|
+
try:
|
|
107
|
+
response = llm.invoke(user_query)
|
|
108
|
+
trace.set_output(response)
|
|
109
|
+
trace.set_status("success")
|
|
110
|
+
except Exception as e:
|
|
111
|
+
trace.set_error(e)
|
|
112
|
+
finally:
|
|
113
|
+
trace.end()
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Trace Fields
|
|
117
|
+
|
|
118
|
+
| Method | Description |
|
|
119
|
+
| --------------------------- | ------------------------------------ |
|
|
120
|
+
| `set_input(data)` | Input data (auto-serialized) |
|
|
121
|
+
| `set_output(data)` | Output data (auto-serialized) |
|
|
122
|
+
| `set_model(name)` | Model name (e.g., `"gpt-4o"`) |
|
|
123
|
+
| `set_tokens(input, output)` | Token counts |
|
|
124
|
+
| `set_cost(amount)` | Cost in USD |
|
|
125
|
+
| `set_status(status)` | `"success"` or `"error"` |
|
|
126
|
+
| `set_error(exception)` | Records error info from an exception |
|
|
127
|
+
| `set_metadata(dict)` | Arbitrary key-value metadata |
|
|
128
|
+
| `set_duration(ms)` | Override duration in milliseconds |
|
|
129
|
+
|
|
130
|
+
## Privacy & PII Scrubbing
|
|
131
|
+
|
|
132
|
+
Built-in client-side PII scrubbing before data leaves your infrastructure:
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
ag = Execlave(
|
|
136
|
+
api_key="exe_prod_xxx",
|
|
137
|
+
privacy={
|
|
138
|
+
"scrub_pii": True, # Enable PII detection & redaction
|
|
139
|
+
"scrub_fields": ["input", "output"], # Fields to scan
|
|
140
|
+
},
|
|
141
|
+
)
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Detected PII types: email addresses, SSNs, credit card numbers, US phone numbers, IP addresses, API keys.
|
|
145
|
+
|
|
146
|
+
## Prompt Injection Scanning
|
|
147
|
+
|
|
148
|
+
The SDK scans inputs for prompt-injection patterns before sending them to your LLM:
|
|
149
|
+
|
|
150
|
+
```python
|
|
151
|
+
ag = Execlave(
|
|
152
|
+
api_key="exe_prod_xxx",
|
|
153
|
+
enable_injection_scan=True, # Default: True
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
# Traces with detected injection attempts are flagged automatically
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Detected patterns include: "ignore previous instructions", jailbreak attempts, system prompt extraction, and more.
|
|
160
|
+
|
|
161
|
+
## Kill Switch / Pause Support
|
|
162
|
+
|
|
163
|
+
Execlave supports remote agent pausing via the dashboard:
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
from execlave import AgentPausedError
|
|
167
|
+
|
|
168
|
+
try:
|
|
169
|
+
result = answer("Process this order")
|
|
170
|
+
except AgentPausedError:
|
|
171
|
+
# Agent was paused by an admin — handle gracefully
|
|
172
|
+
return "Service temporarily unavailable"
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
The SDK polls for status changes in the background (configurable interval).
|
|
176
|
+
|
|
177
|
+
## OpenTelemetry Integration
|
|
178
|
+
|
|
179
|
+
Export Execlave traces as OpenTelemetry spans for unified observability:
|
|
180
|
+
|
|
181
|
+
```python
|
|
182
|
+
from execlave import Execlave
|
|
183
|
+
from execlave.otel import configure_otel
|
|
184
|
+
|
|
185
|
+
# Initialize with OTel mode
|
|
186
|
+
ag = Execlave(
|
|
187
|
+
api_key="exe_prod_xxx",
|
|
188
|
+
mode="otel",
|
|
189
|
+
otlp_endpoint="http://localhost:4318", # Your OTel collector
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
# Configure the OTel pipeline
|
|
193
|
+
configure_otel(ag)
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Requires the `otel` extra: `pip install execlave-sdk[otel]`
|
|
197
|
+
|
|
198
|
+
## Configuration
|
|
199
|
+
|
|
200
|
+
### Constructor Options
|
|
201
|
+
|
|
202
|
+
| Parameter | Type | Default | Description |
|
|
203
|
+
| ------------------------ | ------ | -------------------------- | ---------------------------- |
|
|
204
|
+
| `api_key` | `str` | `EXECLAVE_API_KEY` env | Your Execlave API key |
|
|
205
|
+
| `base_url` | `str` | `https://api.execlave.com` | Execlave API URL |
|
|
206
|
+
| `environment` | `str` | `"production"` | Environment tag |
|
|
207
|
+
| `async_mode` | `bool` | `True` | Non-blocking trace ingestion |
|
|
208
|
+
| `mode` | `str` | `"native"` | `"native"` or `"otel"` |
|
|
209
|
+
| `otlp_endpoint` | `str` | `None` | OTel collector endpoint |
|
|
210
|
+
| `batch_size` | `int` | `100` | Traces per flush batch |
|
|
211
|
+
| `flush_interval_seconds` | `int` | `10` | Seconds between flushes |
|
|
212
|
+
| `debug` | `bool` | `False` | Enable debug logging |
|
|
213
|
+
| `privacy` | `dict` | `{}` | PII scrubbing config |
|
|
214
|
+
| `enable_control_channel` | `bool` | `True` | Enable status polling |
|
|
215
|
+
| `enable_injection_scan` | `bool` | `True` | Enable injection scanning |
|
|
216
|
+
|
|
217
|
+
### Environment Variables
|
|
218
|
+
|
|
219
|
+
| Variable | Description |
|
|
220
|
+
| ------------------- | ------------------------------------- |
|
|
221
|
+
| `EXECLAVE_API_KEY` | API key (alternative to constructor) |
|
|
222
|
+
| `EXECLAVE_BASE_URL` | Base URL (alternative to constructor) |
|
|
223
|
+
|
|
224
|
+
## Error Handling
|
|
225
|
+
|
|
226
|
+
```python
|
|
227
|
+
from execlave import ExeclaveError, ExeclaveAuthError, AgentPausedError
|
|
228
|
+
|
|
229
|
+
try:
|
|
230
|
+
ag = Execlave(api_key="exe_invalid")
|
|
231
|
+
ag.register_agent(agent_id="test")
|
|
232
|
+
except ExeclaveAuthError:
|
|
233
|
+
print("Invalid API key")
|
|
234
|
+
except AgentPausedError:
|
|
235
|
+
print("Agent is paused")
|
|
236
|
+
except ExeclaveError as e:
|
|
237
|
+
print(f"SDK error: {e}")
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Async Trace Buffer
|
|
241
|
+
|
|
242
|
+
The SDK uses a non-blocking circular buffer (max 10,000 traces) with a background flush thread. Traces are batched and sent to the Execlave API automatically.
|
|
243
|
+
|
|
244
|
+
```python
|
|
245
|
+
# Manual flush (e.g., before shutdown)
|
|
246
|
+
ag.flush()
|
|
247
|
+
|
|
248
|
+
# Graceful shutdown
|
|
249
|
+
ag.shutdown()
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## Development
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
# Clone the repo
|
|
256
|
+
git clone https://github.com/execlave/sdk-python.git
|
|
257
|
+
cd execlave/sdk-python
|
|
258
|
+
|
|
259
|
+
# Install dev dependencies
|
|
260
|
+
pip install -e ".[test]"
|
|
261
|
+
|
|
262
|
+
# Run tests
|
|
263
|
+
pytest # 130 tests
|
|
264
|
+
pytest --cov=execlave # With coverage
|
|
265
|
+
|
|
266
|
+
# Type checking
|
|
267
|
+
mypy execlave/
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
## Legal
|
|
271
|
+
|
|
272
|
+
By using this SDK, you agree to the [Execlave Terms of Service](https://execlave.com/terms).
|
|
273
|
+
|
|
274
|
+
- [Privacy Policy](https://execlave.com/privacy)
|
|
275
|
+
- [Acceptable Use Policy](https://execlave.com/acceptable-use)
|
|
276
|
+
- [Responsible AI](https://execlave.com/responsible-ai)
|
|
277
|
+
- [Security](https://execlave.com/security)
|
|
278
|
+
|
|
279
|
+
## License
|
|
280
|
+
|
|
281
|
+
MIT — see [LICENSE](../LICENSE) for details.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Execlave Python SDK
|
|
3
|
+
|
|
4
|
+
Official SDK for integrating AI agents with the Execlave governance platform.
|
|
5
|
+
Provides tracing, prompt management, and governance capabilities.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .client import Execlave, ExeclaveClient
|
|
9
|
+
from .agent import Agent
|
|
10
|
+
from .trace import Trace
|
|
11
|
+
from .errors import (
|
|
12
|
+
ExeclaveError,
|
|
13
|
+
ExeclaveAuthError,
|
|
14
|
+
AgentPausedError,
|
|
15
|
+
PolicyBlockedError,
|
|
16
|
+
PolicyDeniedError,
|
|
17
|
+
ApprovalTimeoutError,
|
|
18
|
+
EnforcementUnavailableError,
|
|
19
|
+
QuotaExceededError,
|
|
20
|
+
PlanLimitExceededError,
|
|
21
|
+
)
|
|
22
|
+
from .connectors import run_openai_chat, run_langchain
|
|
23
|
+
|
|
24
|
+
__all__ = [
|
|
25
|
+
"Execlave",
|
|
26
|
+
"ExeclaveClient", # backward compat alias
|
|
27
|
+
"Agent",
|
|
28
|
+
"Trace",
|
|
29
|
+
"ExeclaveError",
|
|
30
|
+
"ExeclaveAuthError",
|
|
31
|
+
"AgentPausedError",
|
|
32
|
+
"PolicyBlockedError",
|
|
33
|
+
"PolicyDeniedError",
|
|
34
|
+
"ApprovalTimeoutError",
|
|
35
|
+
"EnforcementUnavailableError",
|
|
36
|
+
"QuotaExceededError",
|
|
37
|
+
"PlanLimitExceededError",
|
|
38
|
+
"run_openai_chat",
|
|
39
|
+
"run_langchain",
|
|
40
|
+
]
|