proveai-agentpulse 0.2.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.
- proveai_agentpulse-0.2.0/LICENSE +21 -0
- proveai_agentpulse-0.2.0/PKG-INFO +361 -0
- proveai_agentpulse-0.2.0/README.md +318 -0
- proveai_agentpulse-0.2.0/pyproject.toml +41 -0
- proveai_agentpulse-0.2.0/setup.cfg +4 -0
- proveai_agentpulse-0.2.0/src/agentpulse/__init__.py +16 -0
- proveai_agentpulse-0.2.0/src/agentpulse/__main__.py +3 -0
- proveai_agentpulse-0.2.0/src/agentpulse/analysis/__init__.py +0 -0
- proveai_agentpulse-0.2.0/src/agentpulse/analysis/changes.py +353 -0
- proveai_agentpulse-0.2.0/src/agentpulse/analysis/dag.py +282 -0
- proveai_agentpulse-0.2.0/src/agentpulse/analysis/diagnose.py +101 -0
- proveai_agentpulse-0.2.0/src/agentpulse/analysis/drift_chains.py +157 -0
- proveai_agentpulse-0.2.0/src/agentpulse/analysis/drift_config.py +96 -0
- proveai_agentpulse-0.2.0/src/agentpulse/analysis/drift_detect.py +393 -0
- proveai_agentpulse-0.2.0/src/agentpulse/analysis/layer1_raw.py +108 -0
- proveai_agentpulse-0.2.0/src/agentpulse/analysis/metric_series.py +347 -0
- proveai_agentpulse-0.2.0/src/agentpulse/analysis/run_anomaly.py +426 -0
- proveai_agentpulse-0.2.0/src/agentpulse/analysis/run_insights.py +328 -0
- proveai_agentpulse-0.2.0/src/agentpulse/analysis/run_metrics.py +410 -0
- proveai_agentpulse-0.2.0/src/agentpulse/analysis/trends.py +319 -0
- proveai_agentpulse-0.2.0/src/agentpulse/analysis/version_drift.py +413 -0
- proveai_agentpulse-0.2.0/src/agentpulse/cli.py +59 -0
- proveai_agentpulse-0.2.0/src/agentpulse/config/drift_rules.yaml +377 -0
- proveai_agentpulse-0.2.0/src/agentpulse/config/prompts_v1.yaml +12 -0
- proveai_agentpulse-0.2.0/src/agentpulse/drift_cli.py +218 -0
- proveai_agentpulse-0.2.0/src/agentpulse/mcp_server.py +424 -0
- proveai_agentpulse-0.2.0/src/agentpulse/paths.py +55 -0
- proveai_agentpulse-0.2.0/src/agentpulse/report.py +211 -0
- proveai_agentpulse-0.2.0/src/agentpulse/reporter/__init__.py +0 -0
- proveai_agentpulse-0.2.0/src/agentpulse/reporter/dashboard.py +3475 -0
- proveai_agentpulse-0.2.0/src/agentpulse/reporter/static/agentpulse.png +0 -0
- proveai_agentpulse-0.2.0/src/agentpulse/reporter/static/agentpulse1.png +0 -0
- proveai_agentpulse-0.2.0/src/agentpulse/reporter/static/proveai_logo.png +0 -0
- proveai_agentpulse-0.2.0/src/agentpulse/reporter/static/run_history.png +0 -0
- proveai_agentpulse-0.2.0/src/agentpulse/reporter/static/trend_view.png +0 -0
- proveai_agentpulse-0.2.0/src/agentpulse/reporter/templates/base.html +352 -0
- proveai_agentpulse-0.2.0/src/agentpulse/reporter/templates/changelog.html +192 -0
- proveai_agentpulse-0.2.0/src/agentpulse/reporter/templates/drift2.html +508 -0
- proveai_agentpulse-0.2.0/src/agentpulse/reporter/templates/explore.html +508 -0
- proveai_agentpulse-0.2.0/src/agentpulse/reporter/templates/home.html +119 -0
- proveai_agentpulse-0.2.0/src/agentpulse/reporter/templates/index.html +172 -0
- proveai_agentpulse-0.2.0/src/agentpulse/reporter/templates/overview.html +154 -0
- proveai_agentpulse-0.2.0/src/agentpulse/reporter/templates/run.html +704 -0
- proveai_agentpulse-0.2.0/src/agentpulse/reporter/templates/timeline.html +133 -0
- proveai_agentpulse-0.2.0/src/agentpulse/reporter/templates/trends.html +840 -0
- proveai_agentpulse-0.2.0/src/agentpulse/reporter/terminal.py +106 -0
- proveai_agentpulse-0.2.0/src/agentpulse/runner.py +58 -0
- proveai_agentpulse-0.2.0/src/agentpulse/sdk/__init__.py +3 -0
- proveai_agentpulse-0.2.0/src/agentpulse/sdk/instrument.py +67 -0
- proveai_agentpulse-0.2.0/src/agentpulse/sdk/patches/__init__.py +0 -0
- proveai_agentpulse-0.2.0/src/agentpulse/sdk/patches/anthropic.py +103 -0
- proveai_agentpulse-0.2.0/src/agentpulse/sdk/patches/autogen.py +137 -0
- proveai_agentpulse-0.2.0/src/agentpulse/sdk/patches/langchain.py +632 -0
- proveai_agentpulse-0.2.0/src/agentpulse/sdk/patches/openai.py +378 -0
- proveai_agentpulse-0.2.0/src/agentpulse/sdk/session.py +536 -0
- proveai_agentpulse-0.2.0/src/agentpulse/storage/__init__.py +0 -0
- proveai_agentpulse-0.2.0/src/agentpulse/storage/sqlite_store.py +627 -0
- proveai_agentpulse-0.2.0/src/proveai_agentpulse.egg-info/PKG-INFO +361 -0
- proveai_agentpulse-0.2.0/src/proveai_agentpulse.egg-info/SOURCES.txt +65 -0
- proveai_agentpulse-0.2.0/src/proveai_agentpulse.egg-info/dependency_links.txt +1 -0
- proveai_agentpulse-0.2.0/src/proveai_agentpulse.egg-info/entry_points.txt +2 -0
- proveai_agentpulse-0.2.0/src/proveai_agentpulse.egg-info/requires.txt +16 -0
- proveai_agentpulse-0.2.0/src/proveai_agentpulse.egg-info/top_level.txt +1 -0
- proveai_agentpulse-0.2.0/tests/test_drift_chains.py +52 -0
- proveai_agentpulse-0.2.0/tests/test_drift_detect.py +60 -0
- proveai_agentpulse-0.2.0/tests/test_investigate.py +52 -0
- proveai_agentpulse-0.2.0/tests/test_series_snapshot.py +58 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Prove AI
|
|
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.
|
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: proveai-agentpulse
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Observability and drift detection for multi-agent systems (AutoGen, LangChain/LangGraph)
|
|
5
|
+
License: MIT License
|
|
6
|
+
|
|
7
|
+
Copyright (c) 2026 Prove AI
|
|
8
|
+
|
|
9
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
10
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
11
|
+
in the Software without restriction, including without limitation the rights
|
|
12
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
13
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
14
|
+
furnished to do so, subject to the following conditions:
|
|
15
|
+
|
|
16
|
+
The above copyright notice and this permission notice shall be included in all
|
|
17
|
+
copies or substantial portions of the Software.
|
|
18
|
+
|
|
19
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
20
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
21
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
22
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
23
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
24
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
25
|
+
SOFTWARE.
|
|
26
|
+
|
|
27
|
+
Requires-Python: >=3.10
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
License-File: LICENSE
|
|
30
|
+
Requires-Dist: flask>=3.0
|
|
31
|
+
Requires-Dist: pyyaml>=6.0
|
|
32
|
+
Requires-Dist: rich>=13.0
|
|
33
|
+
Provides-Extra: ai
|
|
34
|
+
Requires-Dist: anthropic>=0.40; extra == "ai"
|
|
35
|
+
Provides-Extra: mcp
|
|
36
|
+
Requires-Dist: mcp>=1.0; extra == "mcp"
|
|
37
|
+
Provides-Extra: otel
|
|
38
|
+
Requires-Dist: opentelemetry-sdk>=1.24; extra == "otel"
|
|
39
|
+
Requires-Dist: opentelemetry-api>=1.24; extra == "otel"
|
|
40
|
+
Provides-Extra: all
|
|
41
|
+
Requires-Dist: proveai-agentpulse[ai,mcp,otel]; extra == "all"
|
|
42
|
+
Dynamic: license-file
|
|
43
|
+
|
|
44
|
+
# AgentPulse
|
|
45
|
+
|
|
46
|
+
[](https://github.com/prove-ai/agentpulse/actions/workflows/tests.yml)
|
|
47
|
+
[](LICENSE)
|
|
48
|
+
|
|
49
|
+
> Traces tell you what happened. They don't tell you where to start investigating.
|
|
50
|
+
|
|
51
|
+
AgentPulse is an **open-source reference implementation** of drift investigation for multi-agent systems. It turns raw agent traces (tokens, cost, latency, tool calls, handoffs, DAG structure) into run, agent, handoff, route, and drift views. When an outcome degrades, it traces the drift upstream through the handoff graph to the component where it originated and presents the whole causal path.
|
|
52
|
+
|
|
53
|
+
**Who it's for.** Teams building in-house observability for multi-agent systems, and anyone exploring how agent failures should be investigated. Use the ideas, the schema, or the whole thing.
|
|
54
|
+
|
|
55
|
+
**What it's not.** A production observability platform. If you need managed tracing at scale today, use Langfuse, LangSmith, or similar tools. AgentPulse explores the layer above traces: the investigation.
|
|
56
|
+
|
|
57
|
+
If you try it, I would like to hear what worked and what did not. See [Feedback](#feedback).
|
|
58
|
+
|
|
59
|
+

|
|
60
|
+
|
|
61
|
+
*The core view: writer drifted after a prompt and model change at run 18, and critic's success dropped as a consequence. The fix belongs in writer, not critic.*
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Architecture
|
|
66
|
+
|
|
67
|
+
One drift engine, three surfaces. The dashboard, the CLI, and the MCP server call the same engine functions, so they always agree on what "drift" means. Data flows left to right:
|
|
68
|
+
|
|
69
|
+
```mermaid
|
|
70
|
+
flowchart LR
|
|
71
|
+
A["your multi-agent app<br/>+ instrument()"] --> B["sdk/<br/>intercepts LLM calls,<br/>tool calls, handoffs"]
|
|
72
|
+
B --> C[("storage/<br/>SQLite, one file<br/>per project")]
|
|
73
|
+
C --> D["analysis/<br/>metrics, anomalies,<br/>drift, causal chains"]
|
|
74
|
+
D --> E["Dashboard (Flask)"]
|
|
75
|
+
D --> F["CLI (today-drift)"]
|
|
76
|
+
D --> G["MCP server"]
|
|
77
|
+
G --> H["Claude Code /<br/>Claude Desktop"]
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
In words:
|
|
81
|
+
|
|
82
|
+
1. You launch your app through `agentpulse run` — no code changes. It patches the OpenAI and Anthropic SDKs inside your process and hooks AutoGen and LangChain when they are present. With those frameworks, every LLM call, tool call, and handoff is captured automatically; custom orchestrators are not officially supported (see [Framework support](#framework-support)).
|
|
83
|
+
2. Captured events are written through `storage/` into a plain SQLite file per project, `~/.agentpulse/db/<project>.db`. No server, no agent daemon.
|
|
84
|
+
3. The `analysis/` engine reads those runs and computes metrics, anomaly reports, drift findings, and causal chains.
|
|
85
|
+
4. Three surfaces present the same findings: the Flask dashboard, the `today-drift` CLI, and the MCP server that Claude Code or Claude Desktop connects to.
|
|
86
|
+
|
|
87
|
+
| Surface | What it's for |
|
|
88
|
+
|---|---|
|
|
89
|
+
| **Dashboard** (Flask) | Run explorer, timelines, DAGs, trends, and the Drift Investigation view |
|
|
90
|
+
| **CLI** (`today-drift`) | Drift findings as readable cards in your terminal, useful as a daily standup check |
|
|
91
|
+
| **MCP server** | The same findings inside Claude Code / Claude Desktop, so a coding agent can run the investigation |
|
|
92
|
+
|
|
93
|
+
Works with the OpenAI and Anthropic SDKs. How much is captured automatically depends on your framework; see [Framework support](#framework-support).
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Ideas you can reuse
|
|
98
|
+
|
|
99
|
+
Even if you never run AgentPulse, these design decisions carry over to any in-house build:
|
|
100
|
+
|
|
101
|
+
1. **Detect agent, handoff, and route drift separately.** An agent getting slower, a handoff payload shrinking, and the execution path changing are different failure classes with different signals. Collapsing them into one "anomaly score" hides where to look. (`analysis/drift_detect.py`, `analysis/version_drift.py`)
|
|
102
|
+
|
|
103
|
+
2. **Severity needs corroboration, not just magnitude.** A Tier-0 (outcome) breach only escalates to critical when co-timed strong supporting signals and a plausible change event line up. A lone moving metric stays a low-confidence candidate. (`analysis/drift_detect.py`, thresholds in `config/drift_rules.yaml`)
|
|
104
|
+
|
|
105
|
+
3. **Trace the symptom to its upstream origination.** Walk the handoff graph upstream from the breached outcome and stop at the component whose input is stable but whose output drifted. That is where the fix belongs. The downstream agent that "failed" often did not change at all. (`analysis/drift_chains.py`)
|
|
106
|
+
|
|
107
|
+
4. **A change can only explain a drift if it could have caused it.** Config, prompt, and model changes are attributed only when they happened at or before the drift start, on the same or an upstream component. (`_nearby_change` in `analysis/drift_detect.py`)
|
|
108
|
+
|
|
109
|
+
5. **Give the investigation to a coding agent, not just a dashboard.** The MCP server exposes findings as structured, root-cause-led cards, so Claude can triage drift, compare releases, and propose next checks conversationally. (`src/agentpulse/mcp_server.py`, `.claude/skills/`)
|
|
110
|
+
|
|
111
|
+
6. **Pin your metric engine with a snapshot test.** Every chart value for the sample data is pinned by a fixture. A refactor that silently changes a metric fails CI loudly. (`tests/test_series_snapshot.py`)
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Getting started
|
|
116
|
+
|
|
117
|
+
### Step 1: install
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
pip install proveai-agentpulse
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
To try the dashboard with the bundled sample project first (a 4-agent content pipeline with 120 runs across 4 prompt versions and one real drift), clone the repo and point AgentPulse at its data:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
git clone https://github.com/prove-ai/agentpulse.git
|
|
127
|
+
AGENTPULSE_HOME=./agentpulse agentpulse dashboard
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Open <http://localhost:5001> — the Drift Investigation view above is the first thing you can reproduce.
|
|
131
|
+
|
|
132
|
+
### Step 2: capture your own system
|
|
133
|
+
|
|
134
|
+
No code changes — launch your app through `agentpulse run` instead of `python`:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
agentpulse run python main.py
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
If your system runs on a supported framework (see the table below), that is the whole integration. Every LLM call, agent turn, tool call, and handoff is captured into `~/.agentpulse/db/runs.db`. Then run `agentpulse dashboard` and your project appears in the sidebar picker. Your data stays on your machine — it's plain SQLite in your home directory.
|
|
141
|
+
|
|
142
|
+
To monitor several systems side by side, give each its own database:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
AGENTPULSE_DB=my-system agentpulse run python main.py
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
If you can't change how your app is launched (a notebook, a process manager), add two lines at the top of your entry point instead — this is exactly what `agentpulse run` does for you:
|
|
149
|
+
|
|
150
|
+
```python
|
|
151
|
+
import agentpulse
|
|
152
|
+
agentpulse.instrument()
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Framework support
|
|
156
|
+
|
|
157
|
+
`agentpulse run` is the whole story only when your framework tells AgentPulse where agent boundaries are:
|
|
158
|
+
|
|
159
|
+
| Your stack | Integration effort | What you get |
|
|
160
|
+
|---|---|---|
|
|
161
|
+
| AutoGen (`SelectorGroupChat`) | `agentpulse run`, nothing else | Full capture: turns, tokens, tools, handoffs, termination |
|
|
162
|
+
| LangChain, LangGraph, and frameworks built on LangChain callbacks (e.g. CrewAI) | `agentpulse run`, nothing else | Full capture: each chain/node reports its name through the callback system; tokens come from the SDK patches |
|
|
163
|
+
| Plain OpenAI/Anthropic SDK with your own orchestration (e.g. `asyncio.gather`) | Not officially supported | — |
|
|
164
|
+
|
|
165
|
+
The reason for the difference: AutoGen and LangChain expose agent boundaries through their event and callback systems, so AgentPulse can attribute every call to the right agent automatically. A hand-rolled orchestrator has no such signal, so automatic capture is not possible and custom pipelines are not officially supported. (If you really need one, the session primitives in [`src/agentpulse/sdk/session.py`](src/agentpulse/sdk/session.py) are what the adapters in [`src/agentpulse/sdk/patches/`](src/agentpulse/sdk/patches) drive — but you're off the supported path.)
|
|
166
|
+
|
|
167
|
+
### What gets captured
|
|
168
|
+
|
|
169
|
+
| Layer | What |
|
|
170
|
+
|---|---|
|
|
171
|
+
| Per-call | start/end timestamps, input/output tokens, model, latency |
|
|
172
|
+
| Per-agent turn | aggregated tokens, duration, tool calls, status, parent agent |
|
|
173
|
+
| Per-run | total cost, wall-clock, termination reason, prompt version |
|
|
174
|
+
| DAG | parent → child edges (when your orchestrator exposes them), parallel branches, join waits |
|
|
175
|
+
|
|
176
|
+
No API keys are needed to capture data or browse the dashboard; it only reads SQLite. An `ANTHROPIC_API_KEY` is needed only for the optional AI "suggest next checks" feature (see [Configuration](#configuration)).
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## The dashboard
|
|
181
|
+
|
|
182
|
+
### Drift Investigation (`/drift2`)
|
|
183
|
+
The core view, shown at the top of this README: findings ranked by severity, the causal path, what changed, why it matters, potentially related changes, and suggested next checks.
|
|
184
|
+
|
|
185
|
+
### Run explorer (`/`)
|
|
186
|
+
Every captured run with status, route, and cost. Click through to the per-run detail page with an execution timeline (gantt), the interactive agent-chain DAG, anomalies vs the baseline, and parallel-group efficiency.
|
|
187
|
+
|
|
188
|
+

|
|
189
|
+
|
|
190
|
+
### Metrics Explorer (`/explore`)
|
|
191
|
+
Chart any metric for any agent, handoff, or the whole system across runs, with the same baseline bands and version markers as Drift Investigation, plus custom metrics and thresholds.
|
|
192
|
+
|
|
193
|
+

|
|
194
|
+
|
|
195
|
+
There is also a trend view (`/trends`) with agent health cards and a handoff health leaderboard, and an event timeline (`/timeline`) of prompt, model, and tool changes.
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## CLI: `agentpulse drift`
|
|
200
|
+
|
|
201
|
+
The drift findings as terminal cards, with no server and no Claude involved:
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
agentpulse drift # all projects, active drifts
|
|
205
|
+
agentpulse drift --project demo # one project
|
|
206
|
+
agentpulse drift --range 7d # narrower look-back window (default 30d)
|
|
207
|
+
agentpulse drift --min-severity drift # hide low-signal watches
|
|
208
|
+
agentpulse drift --next demo:chain0 # next investigation checks for one finding
|
|
209
|
+
agentpulse drift --compare --project demo # version comparison (baseline vs newest)
|
|
210
|
+
agentpulse drift --compare --project demo --all # step through every version pair
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Sample output:
|
|
214
|
+
|
|
215
|
+
```
|
|
216
|
+
AgentPulse — 1 drift finding · as of 2026-07-16 17:09 · range 30d · demo
|
|
217
|
+
|
|
218
|
+
● writer · Agent behaviour · demo
|
|
219
|
+
Severity: Drift Confidence: High
|
|
220
|
+
Path: writer → … → critic
|
|
221
|
+
Why: A change in writer propagated downstream to critic, whose outcome
|
|
222
|
+
(success) worsened. The fix belongs in writer, not critic.
|
|
223
|
+
Trigger: writer prompt changed near run 110
|
|
224
|
+
Metrics changed (3):
|
|
225
|
+
• writer latency_s +51.2%
|
|
226
|
+
• writer cost_usd +1446.9%
|
|
227
|
+
• critic success -9.3 pp
|
|
228
|
+
active 23d, since Jun 23 · id demo:chain0
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Findings carry an `id` (like `demo:chain0`). Pass it to `--next` to get the recommended follow-up checks for that finding.
|
|
232
|
+
|
|
233
|
+
There is also `agentpulse report`, a per-run metrics report for a single project (`agentpulse report --all --db demo`).
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## MCP server: let Claude run the investigation
|
|
238
|
+
|
|
239
|
+
`agentpulse mcp` (install with `pip install "proveai-agentpulse[mcp]"`) exposes the drift engine to Claude Code and Claude Desktop as three tools:
|
|
240
|
+
|
|
241
|
+
| Tool | What it returns |
|
|
242
|
+
|---|---|
|
|
243
|
+
| `get_todays_finding` | The drift findings active right now, as root-cause-led investigation cards (which component drifted, why, how long it's been active) |
|
|
244
|
+
| `get_version_comparison` | Baseline-vs-newest (or any pair, or every consecutive pair) version comparison, leading with the change that broke an outcome |
|
|
245
|
+
| `get_next_check_steps` | Recommended next investigation steps for a finding. AI-generated when an `ANTHROPIC_API_KEY` is configured, deterministic checks otherwise |
|
|
246
|
+
|
|
247
|
+
### Claude Code
|
|
248
|
+
|
|
249
|
+
The repo ships with a project-scoped [`.mcp.json`](.mcp.json), so if you followed Getting started (venv at `.venv/`), just open Claude Code inside the repo and approve the server when prompted:
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
cd agentpulse
|
|
253
|
+
claude
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
Then ask things like *"what drifted today?"*, *"compare versions of the demo project"*, or *"what should I check next for demo:chain0?"*.
|
|
257
|
+
|
|
258
|
+
To register it from another directory instead:
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
claude mcp add agentpulse -- agentpulse mcp
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
The repo also bundles three Claude Code **skills** under [`.claude/skills/`](.claude/skills) that build on these tools: `drift-triage` (daily standup-style triage), `drift-root-cause-report` (a written root-cause report), and `release-regression-check` (did the last release break anything?).
|
|
265
|
+
|
|
266
|
+
### Claude Desktop
|
|
267
|
+
|
|
268
|
+
Add to `claude_desktop_config.json`. Use absolute paths, because Desktop spawns servers without a working directory:
|
|
269
|
+
|
|
270
|
+
```json
|
|
271
|
+
{
|
|
272
|
+
"mcpServers": {
|
|
273
|
+
"agentpulse": {
|
|
274
|
+
"command": "/path/to/your/venv/bin/agentpulse",
|
|
275
|
+
"args": ["mcp"]
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## Configuration
|
|
284
|
+
|
|
285
|
+
All AgentPulse data lives under one home directory, `~/.agentpulse` by default (override with `AGENTPULSE_HOME`):
|
|
286
|
+
|
|
287
|
+
```
|
|
288
|
+
~/.agentpulse/
|
|
289
|
+
├── db/ one SQLite file per project
|
|
290
|
+
├── config/ optional overrides, e.g. drift_rules.yaml
|
|
291
|
+
└── .env optional KEY=VALUE env file
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
Set `ANTHROPIC_API_KEY` in `~/.agentpulse/.env` (or your shell environment) to enable the AI "suggest next checks" feature (dashboard button, CLI `--next`, MCP `get_next_check_steps`). Everything else works without it; the MCP tool falls back to deterministic checks.
|
|
295
|
+
|
|
296
|
+
Drift detection thresholds and handoff rules ship inside the package ([`src/agentpulse/config/drift_rules.yaml`](src/agentpulse/config/drift_rules.yaml)); to tune them, copy that file to `~/.agentpulse/config/drift_rules.yaml` and edit — it takes precedence, and the dashboard reloads it on every request, no restart needed.
|
|
297
|
+
|
|
298
|
+
Per-run labels are set with environment variables when launching: `AGENTPULSE_DB` (project database name), `AGENTPULSE_TASK_TYPE` (groups like-with-like in drift reports), and `AGENTPULSE_PROMPT_VERSION` (bump when you change prompts). All are optional.
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
## What I want to learn
|
|
303
|
+
|
|
304
|
+
This project is an experiment in how agent failures should be investigated. If you build or operate multi-agent systems, I want to know:
|
|
305
|
+
|
|
306
|
+
- What telemetry do you actually collect for multi-agent systems, and what does AgentPulse's schema miss?
|
|
307
|
+
- Does the agent / handoff / route drift split match how you triage failures?
|
|
308
|
+
- Where is the drift detector wrong? Thresholds live in [`src/agentpulse/config/drift_rules.yaml`](src/agentpulse/config/drift_rules.yaml). If it over-fires or under-fires on your data, that is useful feedback.
|
|
309
|
+
- Should agent observability stay a dashboard, or become structured context for a coding agent that performs the investigation? The MCP server is a bet on the second answer.
|
|
310
|
+
|
|
311
|
+
## Feedback
|
|
312
|
+
|
|
313
|
+
**Feedback is welcome.** Please open a [GitHub issue](https://github.com/prove-ai/agentpulse/issues) for questions, ideas, or bug reports. Telemetry schemas, stories about agent failures that were hard to localize, and design disagreements are all useful.
|
|
314
|
+
|
|
315
|
+
For private feedback, contact me at [leyla@proveai.com](mailto:leyla@proveai.com).
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
## Project layout
|
|
320
|
+
|
|
321
|
+
```
|
|
322
|
+
agentpulse/
|
|
323
|
+
├── pyproject.toml Package definition (`pip install .`, `agentpulse` CLI)
|
|
324
|
+
├── src/agentpulse/
|
|
325
|
+
│ ├── sdk/ Patches for OpenAI/Anthropic + the instrument() entry point
|
|
326
|
+
│ ├── storage/ SQLite store (multi-DB aware via ContextVar)
|
|
327
|
+
│ ├── analysis/ Metric engine: raw → derived → anomalies → trends → drift → DAG
|
|
328
|
+
│ ├── reporter/ Flask dashboard + Jinja templates
|
|
329
|
+
│ ├── config/ Default drift rules + prompt manifests (shipped in the package)
|
|
330
|
+
│ ├── runner.py `agentpulse run` — zero-code-change launcher
|
|
331
|
+
│ ├── cli.py The `agentpulse` command (run/report/dashboard/drift/mcp)
|
|
332
|
+
│ ├── drift_cli.py Drift findings as terminal cards
|
|
333
|
+
│ ├── report.py Per-run metrics report
|
|
334
|
+
│ └── mcp_server.py MCP server (3 tools over the same engine)
|
|
335
|
+
├── scripts/ Demo generators & import helpers
|
|
336
|
+
├── tests/ pytest suite (incl. a metric snapshot guard)
|
|
337
|
+
├── .claude/skills/ Claude Code skills built on the MCP tools
|
|
338
|
+
└── db/ demo.db sample data
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
## Development
|
|
342
|
+
|
|
343
|
+
```bash
|
|
344
|
+
git clone https://github.com/prove-ai/agentpulse.git
|
|
345
|
+
cd agentpulse
|
|
346
|
+
python3 -m venv .venv && source .venv/bin/activate
|
|
347
|
+
pip install -e ".[all]" pytest
|
|
348
|
+
python -m pytest tests/ # run the test suite
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for the snapshot-test workflow and guidelines.
|
|
352
|
+
|
|
353
|
+
## Requirements
|
|
354
|
+
|
|
355
|
+
- Python 3.10+
|
|
356
|
+
- Optional extras: `proveai-agentpulse[mcp]` (MCP server), `proveai-agentpulse[ai]` (AI next-check suggestions), `proveai-agentpulse[otel]` (OTel export), `proveai-agentpulse[all]`
|
|
357
|
+
- The multi-agent system you observe needs `openai` and/or `anthropic` installed in **its** environment. AgentPulse patches whichever it finds; neither is a hard dependency of AgentPulse itself.
|
|
358
|
+
|
|
359
|
+
## License
|
|
360
|
+
|
|
361
|
+
[MIT](LICENSE)
|