agentlens-proxy 0.1.1__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.
- agentlens_proxy-0.1.1/.gitignore +17 -0
- agentlens_proxy-0.1.1/PKG-INFO +220 -0
- agentlens_proxy-0.1.1/README.md +198 -0
- agentlens_proxy-0.1.1/pyproject.toml +53 -0
- agentlens_proxy-0.1.1/src/agentlens/__init__.py +3 -0
- agentlens_proxy-0.1.1/src/agentlens/__main__.py +5 -0
- agentlens_proxy-0.1.1/src/agentlens/cli.py +217 -0
- agentlens_proxy-0.1.1/src/agentlens/export/__init__.py +0 -0
- agentlens_proxy-0.1.1/src/agentlens/models/__init__.py +43 -0
- agentlens_proxy-0.1.1/src/agentlens/models/base.py +160 -0
- agentlens_proxy-0.1.1/src/agentlens/models/enums.py +34 -0
- agentlens_proxy-0.1.1/src/agentlens/models/raw.py +33 -0
- agentlens_proxy-0.1.1/src/agentlens/parsers/__init__.py +25 -0
- agentlens_proxy-0.1.1/src/agentlens/providers/__init__.py +126 -0
- agentlens_proxy-0.1.1/src/agentlens/providers/_base.py +94 -0
- agentlens_proxy-0.1.1/src/agentlens/providers/anthropic/__init__.py +5 -0
- agentlens_proxy-0.1.1/src/agentlens/providers/anthropic/plugin.py +400 -0
- agentlens_proxy-0.1.1/src/agentlens/providers/anthropic/pricing.py +18 -0
- agentlens_proxy-0.1.1/src/agentlens/providers/openai/__init__.py +6 -0
- agentlens_proxy-0.1.1/src/agentlens/providers/openai/completions.py +351 -0
- agentlens_proxy-0.1.1/src/agentlens/providers/openai/plugin.py +450 -0
- agentlens_proxy-0.1.1/src/agentlens/providers/openai/pricing.py +27 -0
- agentlens_proxy-0.1.1/src/agentlens/proxy/__init__.py +9 -0
- agentlens_proxy-0.1.1/src/agentlens/proxy/addon.py +260 -0
- agentlens_proxy-0.1.1/src/agentlens/proxy/runner.py +31 -0
- agentlens_proxy-0.1.1/src/agentlens/server/__init__.py +19 -0
- agentlens_proxy-0.1.1/src/agentlens/server/app.py +118 -0
- agentlens_proxy-0.1.1/src/agentlens/server/dependencies.py +33 -0
- agentlens_proxy-0.1.1/src/agentlens/server/event_bus.py +31 -0
- agentlens_proxy-0.1.1/src/agentlens/server/routes/__init__.py +15 -0
- agentlens_proxy-0.1.1/src/agentlens/server/routes/events.py +37 -0
- agentlens_proxy-0.1.1/src/agentlens/server/routes/export.py +339 -0
- agentlens_proxy-0.1.1/src/agentlens/server/routes/providers.py +16 -0
- agentlens_proxy-0.1.1/src/agentlens/server/routes/requests.py +128 -0
- agentlens_proxy-0.1.1/src/agentlens/server/routes/sessions.py +61 -0
- agentlens_proxy-0.1.1/src/agentlens/storage/__init__.py +12 -0
- agentlens_proxy-0.1.1/src/agentlens/storage/database.py +107 -0
- agentlens_proxy-0.1.1/src/agentlens/storage/repositories.py +431 -0
- agentlens_proxy-0.1.1/web/dist/assets/index-DALNaD5X.css +1 -0
- agentlens_proxy-0.1.1/web/dist/assets/index-GmjNl-go.js +128 -0
- agentlens_proxy-0.1.1/web/dist/index.html +14 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agentlens-proxy
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Profile AI agents by intercepting LLM API traffic through a local MITM proxy
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
Requires-Python: >=3.11
|
|
7
|
+
Requires-Dist: aiosqlite>=0.20.0
|
|
8
|
+
Requires-Dist: fastapi>=0.115.0
|
|
9
|
+
Requires-Dist: mitmproxy>=11.0
|
|
10
|
+
Requires-Dist: pydantic>=2.0
|
|
11
|
+
Requires-Dist: rich>=13.0
|
|
12
|
+
Requires-Dist: sqlalchemy[asyncio]>=2.0
|
|
13
|
+
Requires-Dist: typer>=0.15.0
|
|
14
|
+
Requires-Dist: uvicorn[standard]>=0.32.0
|
|
15
|
+
Requires-Dist: websockets>=14.0
|
|
16
|
+
Provides-Extra: dev
|
|
17
|
+
Requires-Dist: httpx>=0.28.0; extra == 'dev'
|
|
18
|
+
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
|
|
19
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
20
|
+
Requires-Dist: ruff>=0.8.0; extra == 'dev'
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
|
|
23
|
+
# AgentLens
|
|
24
|
+
|
|
25
|
+
Profile AI agents by intercepting LLM API traffic through a local MITM proxy. Understand how agents work: prompts, tools, MCP, token usage, costs, and timing — all in a real-time web UI.
|
|
26
|
+
|
|
27
|
+
## Prerequisites
|
|
28
|
+
|
|
29
|
+
- Python >= 3.11
|
|
30
|
+
- [uv](https://docs.astral.sh/uv/)
|
|
31
|
+
- Node.js >= 18
|
|
32
|
+
|
|
33
|
+
## Install
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
git clone https://github.com/agenticloops/agentlens.git
|
|
37
|
+
cd agentlens
|
|
38
|
+
|
|
39
|
+
make install
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Run
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# Start the proxy (port 8080) and web UI (port 8081)
|
|
46
|
+
agentlens start
|
|
47
|
+
|
|
48
|
+
# Or equivalently
|
|
49
|
+
uv run agentlens start
|
|
50
|
+
make dev
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
This opens the web UI at `http://127.0.0.1:8081` and starts the MITM proxy on port `8080`.
|
|
54
|
+
|
|
55
|
+
### CLI Options
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
agentlens start [OPTIONS]
|
|
59
|
+
|
|
60
|
+
Options:
|
|
61
|
+
--proxy-port INT Port for the MITM proxy [default: 8080]
|
|
62
|
+
--web-port INT Port for the web UI [default: 8081]
|
|
63
|
+
--host TEXT Host to bind to [default: 127.0.0.1]
|
|
64
|
+
--session-name TEXT Name for this profiling session [default: auto-generated]
|
|
65
|
+
--db-path TEXT Path to SQLite database [default: ~/.agentlens/data.db]
|
|
66
|
+
--open/--no-open Open web UI in browser [default: --open]
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Certificate Setup
|
|
70
|
+
|
|
71
|
+
On first run, mitmproxy generates a CA certificate at `~/.mitmproxy/`. You need to either trust this certificate or disable SSL verification for your agent to work through the proxy.
|
|
72
|
+
|
|
73
|
+
### Trust the certificate system-wide (macOS)
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
sudo security add-trusted-cert -d -r trustRoot \
|
|
77
|
+
-k /Library/Keychains/System.keychain \
|
|
78
|
+
~/.mitmproxy/mitmproxy-ca-cert.pem
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Trust the certificate system-wide (Linux)
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# Debian/Ubuntu
|
|
85
|
+
sudo cp ~/.mitmproxy/mitmproxy-ca-cert.pem /usr/local/share/ca-certificates/mitmproxy.crt
|
|
86
|
+
sudo update-ca-certificates
|
|
87
|
+
|
|
88
|
+
# RHEL/Fedora
|
|
89
|
+
sudo cp ~/.mitmproxy/mitmproxy-ca-cert.pem /etc/pki/ca-trust/source/anchors/mitmproxy.pem
|
|
90
|
+
sudo update-ca-trust
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Per-tool certificate environment variables
|
|
94
|
+
|
|
95
|
+
Instead of trusting system-wide, you can point individual tools to the cert:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# Python (requests / urllib3)
|
|
99
|
+
export REQUESTS_CA_BUNDLE=~/.mitmproxy/mitmproxy-ca-cert.pem
|
|
100
|
+
|
|
101
|
+
# Python (httpx)
|
|
102
|
+
export SSL_CERT_FILE=~/.mitmproxy/mitmproxy-ca-cert.pem
|
|
103
|
+
|
|
104
|
+
# Node.js
|
|
105
|
+
export NODE_EXTRA_CA_CERTS=~/.mitmproxy/mitmproxy-ca-cert.pem
|
|
106
|
+
|
|
107
|
+
# curl
|
|
108
|
+
curl --cacert ~/.mitmproxy/mitmproxy-ca-cert.pem ...
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Skip verification entirely (not recommended for production)
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
# Node.js
|
|
115
|
+
export NODE_TLS_REJECT_UNAUTHORIZED=0
|
|
116
|
+
|
|
117
|
+
# Python
|
|
118
|
+
export PYTHONHTTPSVERIFY=0
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Usage
|
|
122
|
+
|
|
123
|
+
Start the profiler in one terminal, then launch your agent in another with proxy environment variables set. The profiler captures all LLM API traffic transparently — no code changes needed.
|
|
124
|
+
|
|
125
|
+
### Claude Code
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
# Terminal 1
|
|
129
|
+
agentlens start --session-name "claude-code-debug-session"
|
|
130
|
+
|
|
131
|
+
# Terminal 2
|
|
132
|
+
HTTP_PROXY=http://127.0.0.1:8080 \
|
|
133
|
+
HTTPS_PROXY=http://127.0.0.1:8080 \
|
|
134
|
+
NODE_EXTRA_CA_CERTS=~/.mitmproxy/mitmproxy-ca-cert.pem \
|
|
135
|
+
claude
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Or skip cert verification:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
HTTP_PROXY=http://127.0.0.1:8080 \
|
|
142
|
+
HTTPS_PROXY=http://127.0.0.1:8080 \
|
|
143
|
+
NODE_TLS_REJECT_UNAUTHORIZED=0 \
|
|
144
|
+
claude
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Codex CLI
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
HTTP_PROXY=http://127.0.0.1:8080 \
|
|
151
|
+
HTTPS_PROXY=http://127.0.0.1:8080 \
|
|
152
|
+
NODE_EXTRA_CA_CERTS=~/.mitmproxy/mitmproxy-ca-cert.pem \
|
|
153
|
+
codex
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### OpenAI Python SDK
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
HTTP_PROXY=http://127.0.0.1:8080 \
|
|
160
|
+
HTTPS_PROXY=http://127.0.0.1:8080 \
|
|
161
|
+
REQUESTS_CA_BUNDLE=~/.mitmproxy/mitmproxy-ca-cert.pem \
|
|
162
|
+
python my_agent.py
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Anthropic Python SDK
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
HTTP_PROXY=http://127.0.0.1:8080 \
|
|
169
|
+
HTTPS_PROXY=http://127.0.0.1:8080 \
|
|
170
|
+
SSL_CERT_FILE=~/.mitmproxy/mitmproxy-ca-cert.pem \
|
|
171
|
+
python my_claude_agent.py
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### LangChain / LlamaIndex / Any Python Agent
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
HTTP_PROXY=http://127.0.0.1:8080 \
|
|
178
|
+
HTTPS_PROXY=http://127.0.0.1:8080 \
|
|
179
|
+
REQUESTS_CA_BUNDLE=~/.mitmproxy/mitmproxy-ca-cert.pem \
|
|
180
|
+
SSL_CERT_FILE=~/.mitmproxy/mitmproxy-ca-cert.pem \
|
|
181
|
+
python my_langchain_agent.py
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Node.js Agents (Vercel AI SDK, etc.)
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
HTTP_PROXY=http://127.0.0.1:8080 \
|
|
188
|
+
HTTPS_PROXY=http://127.0.0.1:8080 \
|
|
189
|
+
NODE_EXTRA_CA_CERTS=~/.mitmproxy/mitmproxy-ca-cert.pem \
|
|
190
|
+
node my_agent.js
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### curl (Quick Test)
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
curl https://api.anthropic.com/v1/messages \
|
|
197
|
+
-x http://127.0.0.1:8080 \
|
|
198
|
+
--cacert ~/.mitmproxy/mitmproxy-ca-cert.pem \
|
|
199
|
+
-H "x-api-key: $ANTHROPIC_API_KEY" \
|
|
200
|
+
-H "anthropic-version: 2023-06-01" \
|
|
201
|
+
-H "content-type: application/json" \
|
|
202
|
+
-d '{
|
|
203
|
+
"model": "claude-haiku-4",
|
|
204
|
+
"max_tokens": 128,
|
|
205
|
+
"messages": [{"role": "user", "content": "Hello!"}]
|
|
206
|
+
}'
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### What Gets Captured
|
|
210
|
+
|
|
211
|
+
| Provider | Hosts | Paths |
|
|
212
|
+
|----------|-------|-------|
|
|
213
|
+
| OpenAI | `api.openai.com` | `/v1/chat/completions`, `/v1/responses` |
|
|
214
|
+
| Anthropic | `api.anthropic.com` | `/v1/messages` |
|
|
215
|
+
|
|
216
|
+
All other HTTP traffic passes through the proxy transparently without being captured or stored.
|
|
217
|
+
|
|
218
|
+
## License
|
|
219
|
+
|
|
220
|
+
MIT
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# AgentLens
|
|
2
|
+
|
|
3
|
+
Profile AI agents by intercepting LLM API traffic through a local MITM proxy. Understand how agents work: prompts, tools, MCP, token usage, costs, and timing — all in a real-time web UI.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- Python >= 3.11
|
|
8
|
+
- [uv](https://docs.astral.sh/uv/)
|
|
9
|
+
- Node.js >= 18
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
git clone https://github.com/agenticloops/agentlens.git
|
|
15
|
+
cd agentlens
|
|
16
|
+
|
|
17
|
+
make install
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Run
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# Start the proxy (port 8080) and web UI (port 8081)
|
|
24
|
+
agentlens start
|
|
25
|
+
|
|
26
|
+
# Or equivalently
|
|
27
|
+
uv run agentlens start
|
|
28
|
+
make dev
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
This opens the web UI at `http://127.0.0.1:8081` and starts the MITM proxy on port `8080`.
|
|
32
|
+
|
|
33
|
+
### CLI Options
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
agentlens start [OPTIONS]
|
|
37
|
+
|
|
38
|
+
Options:
|
|
39
|
+
--proxy-port INT Port for the MITM proxy [default: 8080]
|
|
40
|
+
--web-port INT Port for the web UI [default: 8081]
|
|
41
|
+
--host TEXT Host to bind to [default: 127.0.0.1]
|
|
42
|
+
--session-name TEXT Name for this profiling session [default: auto-generated]
|
|
43
|
+
--db-path TEXT Path to SQLite database [default: ~/.agentlens/data.db]
|
|
44
|
+
--open/--no-open Open web UI in browser [default: --open]
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Certificate Setup
|
|
48
|
+
|
|
49
|
+
On first run, mitmproxy generates a CA certificate at `~/.mitmproxy/`. You need to either trust this certificate or disable SSL verification for your agent to work through the proxy.
|
|
50
|
+
|
|
51
|
+
### Trust the certificate system-wide (macOS)
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
sudo security add-trusted-cert -d -r trustRoot \
|
|
55
|
+
-k /Library/Keychains/System.keychain \
|
|
56
|
+
~/.mitmproxy/mitmproxy-ca-cert.pem
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Trust the certificate system-wide (Linux)
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# Debian/Ubuntu
|
|
63
|
+
sudo cp ~/.mitmproxy/mitmproxy-ca-cert.pem /usr/local/share/ca-certificates/mitmproxy.crt
|
|
64
|
+
sudo update-ca-certificates
|
|
65
|
+
|
|
66
|
+
# RHEL/Fedora
|
|
67
|
+
sudo cp ~/.mitmproxy/mitmproxy-ca-cert.pem /etc/pki/ca-trust/source/anchors/mitmproxy.pem
|
|
68
|
+
sudo update-ca-trust
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Per-tool certificate environment variables
|
|
72
|
+
|
|
73
|
+
Instead of trusting system-wide, you can point individual tools to the cert:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# Python (requests / urllib3)
|
|
77
|
+
export REQUESTS_CA_BUNDLE=~/.mitmproxy/mitmproxy-ca-cert.pem
|
|
78
|
+
|
|
79
|
+
# Python (httpx)
|
|
80
|
+
export SSL_CERT_FILE=~/.mitmproxy/mitmproxy-ca-cert.pem
|
|
81
|
+
|
|
82
|
+
# Node.js
|
|
83
|
+
export NODE_EXTRA_CA_CERTS=~/.mitmproxy/mitmproxy-ca-cert.pem
|
|
84
|
+
|
|
85
|
+
# curl
|
|
86
|
+
curl --cacert ~/.mitmproxy/mitmproxy-ca-cert.pem ...
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Skip verification entirely (not recommended for production)
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
# Node.js
|
|
93
|
+
export NODE_TLS_REJECT_UNAUTHORIZED=0
|
|
94
|
+
|
|
95
|
+
# Python
|
|
96
|
+
export PYTHONHTTPSVERIFY=0
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Usage
|
|
100
|
+
|
|
101
|
+
Start the profiler in one terminal, then launch your agent in another with proxy environment variables set. The profiler captures all LLM API traffic transparently — no code changes needed.
|
|
102
|
+
|
|
103
|
+
### Claude Code
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
# Terminal 1
|
|
107
|
+
agentlens start --session-name "claude-code-debug-session"
|
|
108
|
+
|
|
109
|
+
# Terminal 2
|
|
110
|
+
HTTP_PROXY=http://127.0.0.1:8080 \
|
|
111
|
+
HTTPS_PROXY=http://127.0.0.1:8080 \
|
|
112
|
+
NODE_EXTRA_CA_CERTS=~/.mitmproxy/mitmproxy-ca-cert.pem \
|
|
113
|
+
claude
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Or skip cert verification:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
HTTP_PROXY=http://127.0.0.1:8080 \
|
|
120
|
+
HTTPS_PROXY=http://127.0.0.1:8080 \
|
|
121
|
+
NODE_TLS_REJECT_UNAUTHORIZED=0 \
|
|
122
|
+
claude
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Codex CLI
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
HTTP_PROXY=http://127.0.0.1:8080 \
|
|
129
|
+
HTTPS_PROXY=http://127.0.0.1:8080 \
|
|
130
|
+
NODE_EXTRA_CA_CERTS=~/.mitmproxy/mitmproxy-ca-cert.pem \
|
|
131
|
+
codex
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### OpenAI Python SDK
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
HTTP_PROXY=http://127.0.0.1:8080 \
|
|
138
|
+
HTTPS_PROXY=http://127.0.0.1:8080 \
|
|
139
|
+
REQUESTS_CA_BUNDLE=~/.mitmproxy/mitmproxy-ca-cert.pem \
|
|
140
|
+
python my_agent.py
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Anthropic Python SDK
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
HTTP_PROXY=http://127.0.0.1:8080 \
|
|
147
|
+
HTTPS_PROXY=http://127.0.0.1:8080 \
|
|
148
|
+
SSL_CERT_FILE=~/.mitmproxy/mitmproxy-ca-cert.pem \
|
|
149
|
+
python my_claude_agent.py
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### LangChain / LlamaIndex / Any Python Agent
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
HTTP_PROXY=http://127.0.0.1:8080 \
|
|
156
|
+
HTTPS_PROXY=http://127.0.0.1:8080 \
|
|
157
|
+
REQUESTS_CA_BUNDLE=~/.mitmproxy/mitmproxy-ca-cert.pem \
|
|
158
|
+
SSL_CERT_FILE=~/.mitmproxy/mitmproxy-ca-cert.pem \
|
|
159
|
+
python my_langchain_agent.py
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Node.js Agents (Vercel AI SDK, etc.)
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
HTTP_PROXY=http://127.0.0.1:8080 \
|
|
166
|
+
HTTPS_PROXY=http://127.0.0.1:8080 \
|
|
167
|
+
NODE_EXTRA_CA_CERTS=~/.mitmproxy/mitmproxy-ca-cert.pem \
|
|
168
|
+
node my_agent.js
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### curl (Quick Test)
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
curl https://api.anthropic.com/v1/messages \
|
|
175
|
+
-x http://127.0.0.1:8080 \
|
|
176
|
+
--cacert ~/.mitmproxy/mitmproxy-ca-cert.pem \
|
|
177
|
+
-H "x-api-key: $ANTHROPIC_API_KEY" \
|
|
178
|
+
-H "anthropic-version: 2023-06-01" \
|
|
179
|
+
-H "content-type: application/json" \
|
|
180
|
+
-d '{
|
|
181
|
+
"model": "claude-haiku-4",
|
|
182
|
+
"max_tokens": 128,
|
|
183
|
+
"messages": [{"role": "user", "content": "Hello!"}]
|
|
184
|
+
}'
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### What Gets Captured
|
|
188
|
+
|
|
189
|
+
| Provider | Hosts | Paths |
|
|
190
|
+
|----------|-------|-------|
|
|
191
|
+
| OpenAI | `api.openai.com` | `/v1/chat/completions`, `/v1/responses` |
|
|
192
|
+
| Anthropic | `api.anthropic.com` | `/v1/messages` |
|
|
193
|
+
|
|
194
|
+
All other HTTP traffic passes through the proxy transparently without being captured or stored.
|
|
195
|
+
|
|
196
|
+
## License
|
|
197
|
+
|
|
198
|
+
MIT
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "agentlens-proxy"
|
|
7
|
+
version = "0.1.1"
|
|
8
|
+
description = "Profile AI agents by intercepting LLM API traffic through a local MITM proxy"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
dependencies = [
|
|
13
|
+
"mitmproxy>=11.0",
|
|
14
|
+
"pydantic>=2.0",
|
|
15
|
+
"fastapi>=0.115.0",
|
|
16
|
+
"uvicorn[standard]>=0.32.0",
|
|
17
|
+
"aiosqlite>=0.20.0",
|
|
18
|
+
"sqlalchemy[asyncio]>=2.0",
|
|
19
|
+
"typer>=0.15.0",
|
|
20
|
+
"rich>=13.0",
|
|
21
|
+
"websockets>=14.0",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
[project.optional-dependencies]
|
|
25
|
+
dev = [
|
|
26
|
+
"pytest>=8.0",
|
|
27
|
+
"pytest-asyncio>=0.24.0",
|
|
28
|
+
"httpx>=0.28.0",
|
|
29
|
+
"ruff>=0.8.0",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[project.scripts]
|
|
33
|
+
agentlens = "agentlens.cli:app"
|
|
34
|
+
|
|
35
|
+
[tool.hatch.build.targets.wheel]
|
|
36
|
+
packages = ["src/agentlens"]
|
|
37
|
+
|
|
38
|
+
[tool.hatch.build.targets.wheel.force-include]
|
|
39
|
+
"web/dist" = "agentlens/static"
|
|
40
|
+
|
|
41
|
+
[tool.hatch.build.targets.sdist]
|
|
42
|
+
include = ["src/agentlens", "web/dist", "pyproject.toml", "README.md"]
|
|
43
|
+
|
|
44
|
+
[tool.hatch.build.targets.sdist.force-include]
|
|
45
|
+
"web/dist" = "web/dist"
|
|
46
|
+
|
|
47
|
+
[tool.pytest.ini_options]
|
|
48
|
+
testpaths = ["tests"]
|
|
49
|
+
asyncio_mode = "auto"
|
|
50
|
+
|
|
51
|
+
[tool.ruff]
|
|
52
|
+
target-version = "py311"
|
|
53
|
+
line-length = 120
|