epi-recorder 2.2.0__py3-none-any.whl → 2.3.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.
@@ -0,0 +1,269 @@
1
+ Metadata-Version: 2.4
2
+ Name: epi-recorder
3
+ Version: 2.3.0
4
+ Summary: Verifiable execution evidence for AI systems. Portable, cryptographically signed artifacts.
5
+ Author-email: EPI Labs <mohdibrahim@epilabs.org>
6
+ Maintainer-email: Mohd Ibrahim Afridi <mohdibrahim@epilabs.org>
7
+ License: MIT
8
+ Project-URL: Homepage, https://epilabs.org
9
+ Project-URL: Documentation, https://epilabs.org/docs
10
+ Project-URL: Repository, https://github.com/mohdibrahimaiml/epi-recorder
11
+ Project-URL: Issues, https://github.com/mohdibrahimaiml/epi-recorder/issues
12
+ Project-URL: Discussions, https://github.com/mohdibrahimaiml/epi-recorder/discussions
13
+ Keywords: evidence,forensics,audit,compliance,cryptography,ai,llm,verification,artifact,execution-trace,reproducibility,tamper-evident
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Intended Audience :: Legal Industry
17
+ Classifier: Intended Audience :: Science/Research
18
+ Classifier: License :: OSI Approved :: MIT License
19
+ Classifier: Operating System :: OS Independent
20
+ Classifier: Programming Language :: Python :: 3
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
24
+ Classifier: Topic :: Security :: Cryptography
25
+ Classifier: Topic :: System :: Logging
26
+ Classifier: Typing :: Typed
27
+ Classifier: Framework :: Pydantic
28
+ Classifier: Framework :: Pydantic :: 2
29
+ Requires-Python: >=3.11
30
+ Description-Content-Type: text/markdown
31
+ License-File: LICENSE
32
+ Requires-Dist: pydantic>=2.0.0
33
+ Requires-Dist: cryptography>=41.0.0
34
+ Requires-Dist: cbor2>=5.6.0
35
+ Requires-Dist: typer[all]>=0.12.0
36
+ Requires-Dist: rich>=13.0.0
37
+ Requires-Dist: google-generativeai>=0.4.0
38
+ Provides-Extra: dev
39
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
40
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
41
+ Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
42
+ Requires-Dist: black>=24.0.0; extra == "dev"
43
+ Requires-Dist: ruff>=0.3.0; extra == "dev"
44
+ Dynamic: license-file
45
+
46
+ <p align="center">
47
+ <img src="https://raw.githubusercontent.com/mohdibrahimaiml/epi-recorder/main/docs/assets/logo.png" alt="EPI Logo" width="180"/>
48
+ <br>
49
+ <h1 align="center">EPI</h1>
50
+ <p align="center"><strong>Verifiable Execution Evidence for AI Systems / AI Agents</strong></p>
51
+ <p align="center">
52
+ <em>A portable, cryptographically sealed artifact format for AI execution records.</em>
53
+ </p>
54
+ </p>
55
+
56
+ <p align="center">
57
+ <a href="https://pypi.org/project/epi-recorder/"><img src="https://img.shields.io/pypi/v/epi-recorder?style=for-the-badge&color=00d4ff&label=PyPI" alt="PyPI"/></a>
58
+ <a href="https://github.com/mohdibrahimaiml/epi-recorder"><img src="https://img.shields.io/badge/python-3.11%2B-blue?style=for-the-badge&logo=python&logoColor=white" alt="Python"/></a>
59
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green?style=for-the-badge" alt="License"/></a>
60
+ </p>
61
+
62
+ ---
63
+
64
+ ## What is EPI?
65
+
66
+ EPI (Evidence Package for AI) is a **file format** for capturing and verifying AI execution evidence.
67
+
68
+ An `.epi` file is to AI execution what PDF is to documents:
69
+ - **Self-contained** — prompts, responses, environment, viewer — all in one file
70
+ - **Universally viewable** — opens in any browser, no software required
71
+ - **Tamper-evident** — Ed25519 signatures prove the record wasn't altered
72
+
73
+ EPI is designed for **adversarial review**: audits, incident response, compliance, litigation.
74
+
75
+ ---
76
+
77
+ ## Design Guarantees
78
+
79
+ EPI artifacts provide the following guarantees:
80
+
81
+ | Guarantee | Implementation |
82
+ |:----------|:---------------|
83
+ | **Explicitness** | Evidence capture is intentional and reviewable in source code |
84
+ | **Portability** | Single file, no external dependencies, works offline |
85
+ | **Offline Verifiability** | Signature verification requires no network or cloud services |
86
+ | **Adversarial Review** | Format assumes the reviewer does not trust the producer |
87
+
88
+ These are not features. They are **constraints** that define what EPI is.
89
+
90
+ ---
91
+
92
+ ## Quick Start
93
+
94
+ ```bash
95
+ pip install epi-recorder
96
+ ```
97
+
98
+ ### Capture Evidence (Explicit API)
99
+
100
+ ```python
101
+ from epi_recorder import record
102
+
103
+ with record("evidence.epi") as epi:
104
+ response = client.chat.completions.create(model="gpt-4", messages=[...])
105
+ epi.log_llm_call(response) # Explicit capture
106
+ ```
107
+
108
+ ### Capture Evidence (Wrapper Client)
109
+
110
+ ```python
111
+ from epi_recorder import record, wrap_openai
112
+ from openai import OpenAI
113
+
114
+ client = wrap_openai(OpenAI())
115
+
116
+ with record("evidence.epi"):
117
+ response = client.chat.completions.create(...) # Captured via wrapper
118
+ ```
119
+
120
+ ### Verify Evidence
121
+
122
+ ```bash
123
+ epi verify evidence.epi
124
+ ```
125
+
126
+ ---
127
+
128
+ ## The `.epi` Artifact Format
129
+
130
+ An `.epi` file is a ZIP archive with a defined structure. See [docs/EPI-SPEC.md](docs/EPI-SPEC.md) for the full specification.
131
+
132
+ ```
133
+ evidence.epi
134
+ ├── mimetype # "application/epi+zip"
135
+ ├── manifest.json # Metadata + Ed25519 signature
136
+ ├── steps.jsonl # Execution steps (NDJSON)
137
+ ├── env.json # Runtime environment snapshot
138
+ └── viewer/
139
+ └── index.html # Self-contained offline viewer
140
+ ```
141
+
142
+ The embedded viewer allows any recipient to:
143
+ - View the complete execution timeline
144
+ - Verify cryptographic integrity
145
+ - Inspect individual steps
146
+
147
+ No software installation required.
148
+
149
+ ---
150
+
151
+ ## CLI Reference
152
+
153
+ ### Primary Commands
154
+
155
+ | Command | Purpose |
156
+ |:--------|:--------|
157
+ | `epi run <script.py>` | Capture execution evidence to `.epi` |
158
+ | `epi verify <file.epi>` | Verify artifact integrity and signature |
159
+ | `epi view <file.epi>` | Open artifact in browser viewer |
160
+ | `epi keys list` | Manage signing keys |
161
+
162
+ ### Secondary Tools
163
+
164
+ These tools consume evidence artifacts for analysis:
165
+
166
+ | Command | Purpose |
167
+ |:--------|:--------|
168
+ | `epi debug <file.epi>` | Heuristic analysis (loops, errors, inefficiencies) |
169
+ | `epi chat <file.epi>` | Natural language querying via LLM |
170
+
171
+ > **Note:** `debug` and `chat` are convenience tools built on top of the evidence format.
172
+ > They are not part of the core specification.
173
+
174
+ ---
175
+
176
+ ## Cryptographic Properties
177
+
178
+ | Property | Implementation |
179
+ |:---------|:---------------|
180
+ | **Signatures** | Ed25519 (RFC 8032) |
181
+ | **Hashing** | SHA-256 content addressing |
182
+ | **Key Storage** | Local keyring, user-controlled |
183
+ | **Verification** | Client-side, zero external dependencies |
184
+
185
+ Signatures are **optional but recommended**. Unsigned artifacts are still valid but cannot prove origin.
186
+
187
+ ---
188
+
189
+ ## When to Use EPI
190
+
191
+ ### Appropriate Use Cases
192
+
193
+ - Post-incident forensics
194
+ - Compliance documentation
195
+ - Audit trails for autonomous systems
196
+ - Reproducibility evidence for research
197
+ - Litigation-grade execution records
198
+
199
+ ### Not Designed For
200
+
201
+ - Real-time monitoring dashboards
202
+ - High-frequency telemetry
203
+ - System health metrics
204
+ - Application performance monitoring
205
+
206
+ EPI produces **artifacts**, not **streams**.
207
+
208
+ ---
209
+
210
+ ## Supported Providers
211
+
212
+ | Provider | Capture Method |
213
+ |:---------|:---------------|
214
+ | OpenAI | Wrapper client or explicit API |
215
+ | Anthropic | Explicit API |
216
+ | Google Gemini | Explicit API |
217
+ | Any HTTP-based LLM | Explicit API via `log_llm_call()` |
218
+
219
+ EPI does not depend on provider-specific integrations. The explicit API works with any response format.
220
+
221
+ ---
222
+
223
+ ## v2.3.0 — Design Correction
224
+
225
+ This release corrects EPI's evidence capture model.
226
+
227
+ | Before (v2.2.x) | After (v2.3.0) |
228
+ |:----------------|:---------------|
229
+ | Implicit monkey-patching | Explicit capture |
230
+ | Fragile to SDK changes | Stable across versions |
231
+ | Hidden instrumentation | Reviewable in source |
232
+
233
+ **Rationale:** Evidence systems must be intentional. Implicit capture was convenient but violated the explicitness guarantee.
234
+
235
+ **Migration:** Replace implicit capture with `epi.log_llm_call(response)` or `wrap_openai()`.
236
+
237
+ **Legacy mode:** `record(legacy_patching=True)` is deprecated and will be removed in v3.0.
238
+
239
+ ---
240
+
241
+ ## Release History
242
+
243
+ | Version | Date | Summary |
244
+ |:--------|:-----|:--------|
245
+ | **2.3.0** | 2026-02-06 | Explicit capture, wrapper clients, design correction |
246
+ | **2.2.0** | 2026-01-30 | SQLite storage, async support, context isolation |
247
+ | **2.1.3** | 2026-01-24 | Gemini capture, evidence querying |
248
+ | **2.1.0** | 2025-12-15 | Initial release |
249
+
250
+ See [CHANGELOG.md](./CHANGELOG.md) for full details.
251
+
252
+ ---
253
+
254
+ ## Contributing
255
+
256
+ ```bash
257
+ git clone https://github.com/mohdibrahimaiml/epi-recorder.git
258
+ cd epi-recorder
259
+ pip install -e ".[dev]"
260
+ pytest
261
+ ```
262
+
263
+ See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
264
+
265
+ ---
266
+
267
+ ## License
268
+
269
+ MIT License. See [LICENSE](./LICENSE).
@@ -14,25 +14,28 @@ epi_cli/view.py,sha256=EP9takENuZnRllBsxDze9Mm32TGsyxsQaUhlNmUNA_w,4027
14
14
  epi_core/__init__.py,sha256=8CTVjxZDI6oy-MMqWTILY9h8rgSZXS8kVzgySympGJU,309
15
15
  epi_core/container.py,sha256=Eop4CN3TgCoxRyEWorbjvVBnFaxS4zkccdDwgXQ4eIk,13344
16
16
  epi_core/redactor.py,sha256=GAq6R9gkuAHyzgE9sxBXpbQvL_v_myEktxTWFNFnrbY,9892
17
- epi_core/schemas.py,sha256=xpl6xdsIquj_j_a6h2yQ23mB92e91wuiSpKo_BHkY2c,4733
17
+ epi_core/schemas.py,sha256=iVz6yqVnXEe_mG5wh6Y4ojGHyop_kB5igpKXRkK7fT8,4734
18
18
  epi_core/serialize.py,sha256=KB7Z7dfDFh6qq0tlrwjWADOBUV4z32q29Dt2yiniGGg,5691
19
19
  epi_core/storage.py,sha256=XEVbdr5xf00LDDJMqCdrZDFvVS-BZ1e1CWzDaJqG0jE,5374
20
20
  epi_core/trust.py,sha256=_RgYABg0vVH3yBDeXJD7jEyq7WMm5Sli0DHFLmu7lkQ,7970
21
- epi_recorder/__init__.py,sha256=IFimK8E4Mpfx6QLuL5K6SiI1JFyr7iu8Nwh2bG-axIM,402
22
- epi_recorder/api.py,sha256=oFHmdoAyBKi-0b8C9qvZB3q04iA0XlNMVO-Yk3kZ2Ng,22648
21
+ epi_recorder/__init__.py,sha256=tCq2jrJHLxOfO4FPJL3W7F9dRIiOmbNbOZ52cUnqa90,565
22
+ epi_recorder/api.py,sha256=HK10VkaOLxdi-QSw4Jb_NfW-_p0FtXqWQqTJT-rOvlQ,29820
23
23
  epi_recorder/async_api.py,sha256=a2WQL8MnJ8uwnLD6unDZxASe5JbywP1V-8gcFyySFM8,4949
24
24
  epi_recorder/bootstrap.py,sha256=vk6mKnaHcnanm8SB7dYGPDJ8E2iSBSX3OTQ3zyO-6b0,1851
25
25
  epi_recorder/environment.py,sha256=09KuIb7GOxiSHu9OsacaxaHXFJy5e7ewbS3Jz4fX2Zk,6604
26
- epi_recorder/patcher.py,sha256=L773RR3vKj9rw6WVxY6c9zZfrSZMHLR03ZYxcqfbmKw,19475
26
+ epi_recorder/patcher.py,sha256=U_1MRMhLtcdrYxDdD3Lt6MZ4nolkSiYIa93Vn1Go4yI,20981
27
27
  epi_recorder/test_import.py,sha256=_wrlfu0BLtT21AINf1_NugJTvM-RVNKJOyzokMezjO0,462
28
28
  epi_recorder/test_script.py,sha256=ot2vRtgvUdeqk6Oj_cz0TZyQN9fUFVHy2E82jdzZUOs,95
29
- epi_recorder-2.2.0.dist-info/licenses/LICENSE,sha256=uuhz9Y8AjcWd5wF_pZA2cdymDjnESrrLKWDjE_hz7dQ,10347
30
- epi_viewer_static/app.js,sha256=d9m9BYvhtej8xCZQ_4t-0wLHirkhWmDcIbMyJgsqDDs,16173
29
+ epi_recorder/wrappers/__init__.py,sha256=uG0jSBjM_wYo2_lmEiHzDtJbSgF0XlguaNye-dzVjPY,409
30
+ epi_recorder/wrappers/base.py,sha256=uZNNMJSgkf50J_Z-VYO9HOPk-1A1J00BivvKET4opIk,2641
31
+ epi_recorder/wrappers/openai.py,sha256=Mc5LxUSBQtaFyCh7MG0kwe8Wt0VM17weOCRh0N3vjuY,5977
32
+ epi_recorder-2.3.0.dist-info/licenses/LICENSE,sha256=C9g69QrsraEzIORyleKkUeim8h49747brp68ZUf9_ms,1089
33
+ epi_viewer_static/app.js,sha256=2CkRO3iq4J0QTpFgpfAvzGQDrrAIXGp61cJfIC225Cc,20362
31
34
  epi_viewer_static/crypto.js,sha256=2bdANR9tLCPRE9joOih4kKVtptpfRXxERNps4IEhjAQ,19082
32
35
  epi_viewer_static/index.html,sha256=sPNXnDTnk0ArVLofdKB3hhd8q-NL1AUmjucytXoythk,3302
33
36
  epi_viewer_static/viewer_lite.css,sha256=EGsbTiaSZcnep5GMXm6eKxsfr9oIg_IjEDDI94KI4vc,4695
34
- epi_recorder-2.2.0.dist-info/METADATA,sha256=f_Ojf_H0ASyd0-5LWTrJsfgjJdx8Wnx38Af_ZoJ6_EA,6283
35
- epi_recorder-2.2.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
36
- epi_recorder-2.2.0.dist-info/entry_points.txt,sha256=MfMwqVRx_yMGbuPpiyjz2f8fQp8TUbHmRC1H_bupoyM,41
37
- epi_recorder-2.2.0.dist-info/top_level.txt,sha256=osrjwlhDfJZSucB-G1u-rF6o0L1OCx2d892gSWr8Iik,77
38
- epi_recorder-2.2.0.dist-info/RECORD,,
37
+ epi_recorder-2.3.0.dist-info/METADATA,sha256=9ZGZtvoz7vNiy6e35cB9AQUqRWpNNDQGHPqEZ_bfl1Q,8761
38
+ epi_recorder-2.3.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
39
+ epi_recorder-2.3.0.dist-info/entry_points.txt,sha256=MfMwqVRx_yMGbuPpiyjz2f8fQp8TUbHmRC1H_bupoyM,41
40
+ epi_recorder-2.3.0.dist-info/top_level.txt,sha256=osrjwlhDfJZSucB-G1u-rF6o0L1OCx2d892gSWr8Iik,77
41
+ epi_recorder-2.3.0.dist-info/RECORD,,
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024-2026 EPI Labs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
epi_viewer_static/app.js CHANGED
@@ -230,6 +230,14 @@ function renderStep(step) {
230
230
  contentDiv.innerHTML = renderLLMRequest(content);
231
231
  } else if (kind === 'llm.response') {
232
232
  contentDiv.innerHTML = renderLLMResponse(content);
233
+ } else if (kind === 'llm.error') {
234
+ contentDiv.innerHTML = renderLLMError(content);
235
+ } else if (kind === 'http.request') {
236
+ contentDiv.innerHTML = renderHTTPRequest(content);
237
+ } else if (kind === 'http.response') {
238
+ contentDiv.innerHTML = renderHTTPResponse(content);
239
+ } else if (kind === 'http.error') {
240
+ contentDiv.innerHTML = renderHTTPError(content);
233
241
  } else if (kind === 'security.redaction') {
234
242
  contentDiv.innerHTML = renderRedaction(content);
235
243
  } else {
@@ -328,6 +336,74 @@ function renderRedaction(content) {
328
336
  `;
329
337
  }
330
338
 
339
+ // Render LLM error
340
+ function renderLLMError(content) {
341
+ return `
342
+ <div class="bg-red-50 border border-red-200 rounded-lg p-3 text-sm">
343
+ <div class="flex items-center text-red-800">
344
+ <svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 20 20">
345
+ <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd"/>
346
+ </svg>
347
+ <span class="font-medium">LLM Error</span>
348
+ </div>
349
+ <div class="mt-2 text-red-700 font-mono text-xs">
350
+ ${escapeHTML(content.error || content.message || JSON.stringify(content))}
351
+ </div>
352
+ ${content.provider ? `<div class="mt-1 text-xs text-red-600">${content.provider} • ${content.model || 'unknown'}</div>` : ''}
353
+ </div>
354
+ `;
355
+ }
356
+
357
+ // Render HTTP request
358
+ function renderHTTPRequest(content) {
359
+ return `
360
+ <div class="bg-indigo-50 border border-indigo-200 rounded-lg p-3 text-sm">
361
+ <div class="flex items-center text-indigo-800 mb-2">
362
+ <span class="font-medium px-2 py-0.5 bg-indigo-200 rounded text-xs">${content.method || 'GET'}</span>
363
+ <span class="ml-2 font-mono text-xs break-all">${escapeHTML(content.url || '')}</span>
364
+ </div>
365
+ ${content.headers ? `<div class="text-xs text-indigo-600">Headers: ${Object.keys(content.headers).length}</div>` : ''}
366
+ ${content.body ? `<pre class="mt-2 text-xs bg-indigo-100 p-2 rounded overflow-auto max-h-32">${escapeHTML(typeof content.body === 'string' ? content.body : JSON.stringify(content.body, null, 2))}</pre>` : ''}
367
+ </div>
368
+ `;
369
+ }
370
+
371
+ // Render HTTP response
372
+ function renderHTTPResponse(content) {
373
+ const statusColor = (content.status_code >= 200 && content.status_code < 300) ? 'green' :
374
+ (content.status_code >= 400) ? 'red' : 'yellow';
375
+ return `
376
+ <div class="bg-${statusColor}-50 border border-${statusColor}-200 rounded-lg p-3 text-sm">
377
+ <div class="flex items-center text-${statusColor}-800 mb-2">
378
+ <span class="font-medium px-2 py-0.5 bg-${statusColor}-200 rounded text-xs">${content.status_code || '???'}</span>
379
+ <span class="ml-2 text-xs">${content.url || ''}</span>
380
+ ${content.latency_seconds ? `<span class="ml-auto text-xs">⚡ ${content.latency_seconds}s</span>` : ''}
381
+ </div>
382
+ ${content.body ? `<pre class="mt-2 text-xs bg-gray-100 p-2 rounded overflow-auto max-h-32">${escapeHTML(typeof content.body === 'string' ? content.body.slice(0, 500) : JSON.stringify(content.body, null, 2).slice(0, 500))}${(content.body.length > 500) ? '...' : ''}</pre>` : ''}
383
+ </div>
384
+ `;
385
+ }
386
+
387
+ // Render HTTP error
388
+ function renderHTTPError(content) {
389
+ return `
390
+ <div class="bg-red-50 border border-red-200 rounded-lg p-3 text-sm">
391
+ <div class="flex items-center text-red-800">
392
+ <svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 20 20">
393
+ <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd"/>
394
+ </svg>
395
+ <span class="font-medium">HTTP Error</span>
396
+ </div>
397
+ <div class="mt-2 text-red-700">
398
+ <span class="font-mono text-xs">${escapeHTML(content.url || '')}</span>
399
+ </div>
400
+ <div class="mt-1 text-red-600 text-xs">
401
+ ${escapeHTML(content.error || content.message || JSON.stringify(content))}
402
+ </div>
403
+ </div>
404
+ `;
405
+ }
406
+
331
407
  // Escape HTML to prevent XSS
332
408
  function escapeHTML(str) {
333
409
  const div = document.createElement('div');
@@ -404,5 +480,4 @@ if (document.readyState === 'loading') {
404
480
  } else {
405
481
  init();
406
482
  }
407
-
408
-
483
+
@@ -1,162 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: epi-recorder
3
- Version: 2.2.0
4
- Summary: The Flight Recorder for AI Agents. Debug LangChain & CrewAI with execution tracing.
5
- Author-email: EPI Labs <mohdibrahim@epilabs.org>
6
- Maintainer-email: Mohd Ibrahim Afridi <mohdibrahim@epilabs.org>
7
- License: Apache-2.0
8
- Project-URL: Homepage, https://epilabs.org
9
- Project-URL: Documentation, https://epilabs.org/docs
10
- Project-URL: Repository, https://github.com/mohdibrahimaiml/epi-recorder
11
- Project-URL: Issues, https://github.com/mohdibrahimaiml/epi-recorder/issues
12
- Project-URL: Discussions, https://github.com/mohdibrahimaiml/epi-recorder/discussions
13
- Keywords: ai,debugging,agents,langchain,crewai,devtools,observability,llm,openai,gemini,tracing,flight-recorder
14
- Classifier: Development Status :: 4 - Beta
15
- Classifier: Intended Audience :: Developers
16
- Classifier: License :: OSI Approved :: Apache Software License
17
- Classifier: Operating System :: OS Independent
18
- Classifier: Programming Language :: Python :: 3
19
- Classifier: Programming Language :: Python :: 3.11
20
- Classifier: Programming Language :: Python :: 3.12
21
- Classifier: Topic :: Software Development :: Debuggers
22
- Classifier: Topic :: Software Development :: Testing
23
- Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
24
- Classifier: Topic :: System :: Logging
25
- Classifier: Typing :: Typed
26
- Classifier: Framework :: Pydantic
27
- Classifier: Framework :: Pydantic :: 2
28
- Requires-Python: >=3.11
29
- Description-Content-Type: text/markdown
30
- License-File: LICENSE
31
- Requires-Dist: pydantic>=2.0.0
32
- Requires-Dist: cryptography>=41.0.0
33
- Requires-Dist: cbor2>=5.6.0
34
- Requires-Dist: typer[all]>=0.12.0
35
- Requires-Dist: rich>=13.0.0
36
- Requires-Dist: google-generativeai>=0.4.0
37
- Provides-Extra: dev
38
- Requires-Dist: pytest>=8.0.0; extra == "dev"
39
- Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
40
- Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
41
- Requires-Dist: black>=24.0.0; extra == "dev"
42
- Requires-Dist: ruff>=0.3.0; extra == "dev"
43
- Dynamic: license-file
44
-
45
- <p align="center">
46
- <img src="docs/assets/logo.png" alt="EPI Logo" width="200"/>
47
- <br>
48
- <h1 align="center">EPI Recorder</h1>
49
- </p>
50
-
51
- [![Release](https://img.shields.io/github/v/release/mohdibrahimaiml/epi-recorder?label=release&style=flat-square&color=00d4ff)](https://github.com/mohdibrahimaiml/epi-recorder/releases)
52
- [![Python](https://img.shields.io/badge/python-3.11%2B-blue?style=flat-square&logo=python&logoColor=white)](https://pypi.org/project/epi-recorder/)
53
- [![License](https://img.shields.io/badge/license-Apache--2.0-green?style=flat-square)](LICENSE)
54
- [![Downloads](https://img.shields.io/pypi/dm/epi-recorder?style=flat-square&color=10b981)](https://pypi.org/project/epi-recorder/)
55
- [![Users](https://img.shields.io/badge/users-4.5K%2B-orange?style=flat-square&color=f59e0b)](#)
56
-
57
- **The Flight Recorder for AI Agents**
58
-
59
- Debug production failures in LangChain, CrewAI, and custom agents with one command.
60
- Captures complete execution context—prompts, responses, tool calls—and cryptographically seals them for audit trails.
61
-
62
- &#128214; [Documentation](https://epilabs.org) • &#128640; [Quick Start](#quick-start) • &#128272; [Security](#security-compliance)
63
-
64
- > "EPI Recorder provides the missing observability layer we needed for our autonomous agents. The flight recorder approach is a game changer."
65
- > — Lead AI Engineer, Early Adopter
66
-
67
- ---
68
-
69
- ## Traction
70
- - **4,000+** developers using EPI for daily debugging
71
- - **12,000+** agent executions recorded
72
- - **99.9%** atomic capture rate (zero data loss on crashes)
73
-
74
- ---
75
-
76
- ## Why EPI?
77
-
78
- Your AI agent failed in production. It hallucinated. It looped infinitely. It cost you $50 in API calls.
79
-
80
- **You can't reproduce it.** LLMs are non-deterministic. Your logs don't show the full prompt context. You're taking screenshots and pasting JSON into Slack.
81
-
82
- **EPI is the black box.** One command captures everything. Debug locally. Prove what happened.
83
-
84
- ---
85
-
86
- ## Quick Start
87
-
88
- ```bash
89
- pip install epi-recorder
90
-
91
- # Record your agent (zero config)
92
- epi run agent.py
93
-
94
- # Debug the failure (opens browser viewer)
95
- epi view recording.epi
96
-
97
- # Verify integrity (cryptographic proof)
98
- epi verify recording.epi
99
- ```
100
-
101
-
102
-
103
- ---
104
-
105
- ## Features
106
-
107
- - **⚡ Zero Config**: `epi run` intercepts OpenAI, LangChain, CrewAI automatically—no code changes.
108
- - **🔍 AI Debugging**: Built-in heuristics detect infinite loops, hallucinations, and cost inefficiencies.
109
- - **🛡️ Crash Safe**: Atomic SQLite storage survives OOM and power failures (99.9% capture rate).
110
- - **🔐 Tamper Proof**: Ed25519 signatures prove logs weren't edited (for compliance/audits).
111
- - **🌐 Framework Agnostic**: Works with any Python agent (LangChain, CrewAI, AutoGPT, or 100 lines of raw code).
112
-
113
- ---
114
-
115
- ## How It Works
116
-
117
- EPI acts as a **Parasitic Observer**—injecting instrumentation at the Python runtime level via `sitecustomize.py`.
118
-
119
- 1. **Intercept**: Captures LLM calls at the HTTP layer (`requests.Session`) and library level.
120
- 2. **Store**: Atomic SQLite WAL ensures zero data loss on crashes.
121
- 3. **Analyze**: `epi debug` uses local heuristics + AI to find root causes.
122
- 4. **Seal**: Canonical JSON (RFC 8785) + Ed25519 signatures create forensically-valid evidence.
123
-
124
- ```mermaid
125
- graph LR
126
- Script[User Script] -->|Intercept| Patcher[EPI Patcher]
127
- Patcher -->|Write| WAL[(Atomic SQLite)]
128
- WAL -->|Package| File[.epi File]
129
- File -->|Sign| Key[Ed25519 Key]
130
- ```
131
-
132
- ---
133
-
134
- ## Security & Compliance
135
-
136
- While EPI is built for daily debugging, it provides the cryptographic infrastructure required for regulated environments:
137
-
138
- - **Signatures**: Ed25519 with client-side verification (zero-knowledge).
139
- - **Standards**: Supports EU AI Act Article 6 logging requirements.
140
- - **Privacy**: Automatic PII redaction, air-gapped operation (no cloud required).
141
-
142
- *[Enterprise support available](mailto:enterprise@epilabs.org) for SOC2/ISO27001 environments.*
143
-
144
- ---
145
-
146
- ## Contributing
147
-
148
- We welcome contributions! Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for details.
149
-
150
- ```bash
151
- git clone https://github.com/mohdibrahimaiml/epi-recorder.git
152
- cd epi-recorder
153
- pip install -e ".[dev]"
154
- pytest
155
- ```
156
-
157
- ## License
158
-
159
- Apache-2.0 License. See [LICENSE](./LICENSE) for details.
160
-
161
-
162
-