contextspy 0.2.0__tar.gz → 0.3.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.
Files changed (57) hide show
  1. {contextspy-0.2.0/contextspy.egg-info → contextspy-0.3.0}/PKG-INFO +26 -19
  2. {contextspy-0.2.0 → contextspy-0.3.0}/README.md +24 -17
  3. contextspy-0.3.0/contextspy/_web/assets/index-B0fvqx8Q.js +311 -0
  4. contextspy-0.3.0/contextspy/_web/assets/index-Tq-9MUnc.css +1 -0
  5. contextspy-0.2.0/contextspy/_web/assets/index.es-D6MRT83U.js → contextspy-0.3.0/contextspy/_web/assets/index.es-CSuIUirW.js +1 -1
  6. {contextspy-0.2.0 → contextspy-0.3.0}/contextspy/_web/index.html +2 -2
  7. contextspy-0.3.0/contextspy/analysis/adapters/__init__.py +38 -0
  8. contextspy-0.3.0/contextspy/analysis/adapters/anthropic.py +302 -0
  9. contextspy-0.3.0/contextspy/analysis/adapters/base.py +92 -0
  10. contextspy-0.3.0/contextspy/analysis/adapters/ollama.py +84 -0
  11. contextspy-0.3.0/contextspy/analysis/adapters/openai_chat.py +188 -0
  12. contextspy-0.3.0/contextspy/analysis/adapters/openai_responses.py +253 -0
  13. contextspy-0.3.0/contextspy/analysis/blocks.py +129 -0
  14. {contextspy-0.2.0 → contextspy-0.3.0}/contextspy/analysis/classifier.py +74 -76
  15. {contextspy-0.2.0 → contextspy-0.3.0}/contextspy/api/main.py +2 -2
  16. {contextspy-0.2.0 → contextspy-0.3.0}/contextspy/api/routers/requests.py +10 -0
  17. {contextspy-0.2.0 → contextspy-0.3.0}/contextspy/cli.py +254 -3
  18. {contextspy-0.2.0 → contextspy-0.3.0}/contextspy/config.py +25 -0
  19. {contextspy-0.2.0 → contextspy-0.3.0}/contextspy/db/crud.py +134 -16
  20. {contextspy-0.2.0 → contextspy-0.3.0}/contextspy/db/database.py +53 -14
  21. contextspy-0.3.0/contextspy/db/migrations.py +176 -0
  22. {contextspy-0.2.0 → contextspy-0.3.0}/contextspy/db/models.py +104 -2
  23. {contextspy-0.2.0 → contextspy-0.3.0}/contextspy/proxy/addon.py +75 -28
  24. {contextspy-0.2.0 → contextspy-0.3.0/contextspy.egg-info}/PKG-INFO +26 -19
  25. {contextspy-0.2.0 → contextspy-0.3.0}/contextspy.egg-info/SOURCES.txt +11 -4
  26. {contextspy-0.2.0 → contextspy-0.3.0}/pyproject.toml +2 -2
  27. contextspy-0.3.0/tests/test_providers.py +1153 -0
  28. contextspy-0.2.0/contextspy/_web/assets/index-BoLlz7OQ.js +0 -324
  29. contextspy-0.2.0/contextspy/_web/assets/index-CoINF1Xp.css +0 -1
  30. contextspy-0.2.0/contextspy/analysis/providers.py +0 -642
  31. contextspy-0.2.0/tests/test_providers.py +0 -782
  32. {contextspy-0.2.0 → contextspy-0.3.0}/LICENSE +0 -0
  33. {contextspy-0.2.0 → contextspy-0.3.0}/MANIFEST.in +0 -0
  34. {contextspy-0.2.0 → contextspy-0.3.0}/NOTICE +0 -0
  35. {contextspy-0.2.0 → contextspy-0.3.0}/contextspy/__init__.py +0 -0
  36. {contextspy-0.2.0 → contextspy-0.3.0}/contextspy/__main__.py +0 -0
  37. {contextspy-0.2.0 → contextspy-0.3.0}/contextspy/_web/assets/html2canvas.esm-QH1iLAAe.js +0 -0
  38. {contextspy-0.2.0 → contextspy-0.3.0}/contextspy/_web/assets/purify.es-BaNf_EpD.js +0 -0
  39. {contextspy-0.2.0 → contextspy-0.3.0}/contextspy/_web/logo_small_wl.png +0 -0
  40. {contextspy-0.2.0 → contextspy-0.3.0}/contextspy/analysis/__init__.py +0 -0
  41. {contextspy-0.2.0 → contextspy-0.3.0}/contextspy/analysis/tokenizer.py +0 -0
  42. {contextspy-0.2.0 → contextspy-0.3.0}/contextspy/api/__init__.py +0 -0
  43. {contextspy-0.2.0 → contextspy-0.3.0}/contextspy/api/routers/__init__.py +0 -0
  44. {contextspy-0.2.0 → contextspy-0.3.0}/contextspy/api/routers/proxy.py +0 -0
  45. {contextspy-0.2.0 → contextspy-0.3.0}/contextspy/api/routers/sessions.py +0 -0
  46. {contextspy-0.2.0 → contextspy-0.3.0}/contextspy/api/routers/stats.py +0 -0
  47. {contextspy-0.2.0 → contextspy-0.3.0}/contextspy/api/routers/tokenize.py +0 -0
  48. {contextspy-0.2.0 → contextspy-0.3.0}/contextspy/api/websocket.py +0 -0
  49. {contextspy-0.2.0 → contextspy-0.3.0}/contextspy/db/__init__.py +0 -0
  50. {contextspy-0.2.0 → contextspy-0.3.0}/contextspy/proxy/__init__.py +0 -0
  51. {contextspy-0.2.0 → contextspy-0.3.0}/contextspy/proxy/cert.py +0 -0
  52. {contextspy-0.2.0 → contextspy-0.3.0}/contextspy/proxy/runner.py +0 -0
  53. {contextspy-0.2.0 → contextspy-0.3.0}/contextspy.egg-info/dependency_links.txt +0 -0
  54. {contextspy-0.2.0 → contextspy-0.3.0}/contextspy.egg-info/entry_points.txt +0 -0
  55. {contextspy-0.2.0 → contextspy-0.3.0}/contextspy.egg-info/requires.txt +0 -0
  56. {contextspy-0.2.0 → contextspy-0.3.0}/contextspy.egg-info/top_level.txt +0 -0
  57. {contextspy-0.2.0 → contextspy-0.3.0}/setup.cfg +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: contextspy
3
- Version: 0.2.0
4
- Summary: LLM proxy that analyses token usage in context windows
3
+ Version: 0.3.0
4
+ Summary: Context profiler for LLMs and AI agents - used to inspect context conents and reduce token costs
5
5
  Author-email: Rimantas Zukaitis <rimasz@gmail.com>
6
6
  License:
7
7
  Apache License
@@ -259,14 +259,14 @@ Dynamic: license-file
259
259
  </p>
260
260
 
261
261
  ContextSpy is a context window profiler for large language models and common agentic AI coding tools.
262
- It is used to intercept requests to LLM API, analyze and visualize prompt composition, and track context
263
- changes between multiple requests in same session. Modern AI coding agents (GitHub Copilot, Claude Code, Opencode, etc.) pack a lot into each LLM request: system prompts, tool definitions and results, file contents, conversation history. It's often unclear why a session is slow, expensive, or hitting
262
+ It is used to intercept requests to an LLM API, analyze and visualize prompt composition, and track context
263
+ changes between multiple requests in the same session. Modern AI coding agents (GitHub Copilot, Claude Code, opencode, etc.) pack a lot into each LLM request: system prompts, tool definitions and results, file contents, conversation history. It's often unclear why a session is slow, expensive, or hitting
264
264
  the context limit. ContextSpy makes the invisible visible - you see a live breakdown of
265
265
  every token category for every request, across sessions, over time.
266
266
 
267
267
  <p align="center"><strong>Example dashboard view</strong><br><img src="docs/_static/dashboard.png" alt="Dashboard view"></p>
268
268
 
269
- Think of your favorite CPU or memory profiler, just applied to contents of the context of AI agent. While you can optimize pefromance just by reviewing code, having a profiler to capture and visualise shapshot data helps alot. Same with LLM context optmisation.
269
+ Think of your favorite CPU or memory profiler, just applied to the contents of the context of an AI agent. While you can optimize performance just by reviewing code, having a profiler to capture and visualise snapshot data helps a lot. Same with LLM context optimisation.
270
270
 
271
271
  ## Quick start
272
272
 
@@ -283,32 +283,32 @@ sudo contextspy install-cert
283
283
  contextspy start
284
284
 
285
285
  # In a new terminal: launch your coding agent through the proxy
286
- # contextspy run sets required environment variables, so LLM requests are routed though the proxy
287
- contextspy run claude <path to your project>
288
- # contextspy run opencode <path to your project>
286
+ # contextspy run sets required environment variables, so LLM requests are routed through the proxy
287
+ contextspy run opencode <path to your project>
289
288
  # contextspy run code <path to your project>
289
+ # contextspy run claude # run in the drectory of your project
290
290
  ```
291
291
  Open http://127.0.0.1:5173 in your browser for the ContextSpy dashboard.
292
292
 
293
293
  If something doesn't work, see the [troubleshooting section](docs/install.md#troubleshooting) in the install guide.
294
294
 
295
- Alternatively, refer to [configure your agent](docs/cloud-mode.md) on how to route LLM traffic through proxy at `http://127.0.0.1:8888`
295
+ Alternatively, refer to [configure your agent](docs/cloud-mode.md) on how to route LLM traffic through the proxy at `http://127.0.0.1:8888`
296
296
 
297
297
  ## Context profiling? Why should I care?
298
298
 
299
- **Token costs are rising.** With AI agents embracing more and more complex workflows and usecases, token consumption and subsequent
299
+ **Token costs are rising.** With AI agents embracing more and more complex workflows and use cases, token consumption and subsequent
300
300
  cloud API bills are growing larger and larger. This is also applicable for AI coding agents and tools,
301
301
  where providers are gradually switching from subsidized subscription mode and are either reducing token
302
- limits or switching to token usage based billing (e.g. GitHub Copilot)
302
+ limits or switching to token usage based billing (e.g. GitHub Copilot).
303
303
 
304
304
  **Input tokens are major part**. When discussing AI model pricing, most people bring up token generation cost - that's where the numbers look
305
305
  most dramatic ($25 per million tokens for Opus 4.8 output vs $0.40 for gpt-5-nano). But in agentic
306
- workloads, input tokens outnumber output by 20-50x, or even more. So the most of your API bill is influenced
306
+ workloads, input tokens outnumber output by 20-50x, or even more. So most of your API bill is influenced
307
307
  by input context, not the output the model generates.
308
308
 
309
- **AI coding agents = lots of input**. The expensive part is quick accumulation of context - with every turn it fills up with additional tokens - system prompt, skills, tool definitions, tool results, file contents, conversation history.
310
- You start with 5000 - 10000 tokens in fresh session, but by turn 25 it might be 30 to 50 thousand, spend some more time it might be hitting context window limit and compacting. Every API call to the model sends the full context
311
- as part of prompt - and here is where the token consumption and costs skyrocket quickly.
309
+ **AI coding agents = lots of input**. The expensive part is the quick accumulation of context - with every turn it fills up with additional tokens - system prompt, skills, tool definitions, tool results, file contents, conversation history.
310
+ You start with 5000 - 10000 tokens in a fresh session, but by turn 25 it might be 30 to 50 thousand, spend some more time and it might be hitting the context window limit and compacting. Every API call to the model sends the full context
311
+ as part of the prompt - and here is where the token consumption and costs skyrocket quickly.
312
312
 
313
313
  ## Why large context is bad
314
314
 
@@ -317,14 +317,14 @@ We all have been told that the more information we will give to the model, the m
317
317
  There are three ways you pay for extra (and sometimes unnecessary) information in your context:
318
318
 
319
319
  1. **API Costs** - even with near perfect cache hits, input token costs outweigh output, often by order of magnitude or more.
320
- 2. **Compute and latency** - larger contexts take considerably longer to process - especially in local hosted models
320
+ 2. **Compute and latency** - larger contexts take considerably longer to process - especially in locally hosted models
321
321
  3. **Context rot** - with larger contexts, LLMs start to lose precision rapidly, with [100k being the limit](https://www.trychroma.com/research/context-rot) where rapid degradation starts. So you are paying for more expensive model, but getting performance of cheaper one - or even worse.
322
322
 
323
323
  ContextSpy makes these costs visible so you can act on them.
324
324
 
325
325
  ## How does it work
326
326
 
327
- ContextSpy starts a HTTPS proxy (or reverse proxy for locally hosted models) which intercepts every request to LLMs, analyzes it and stores to local SQLite db. A webserver is also started on localhost, and serves dashboard to visualise all captured data.
327
+ ContextSpy starts an HTTPS proxy (or reverse proxy for locally hosted models) which intercepts every request to LLMs, analyzes it and stores to local SQLite db. A webserver is also started on localhost, and serves dashboard to visualise all captured data.
328
328
 
329
329
  ## Some screenshots
330
330
 
@@ -343,7 +343,11 @@ The proxy and dashboard server are bound to localhost, and not exposed to extern
343
343
 
344
344
  The intended use case is to run ContextSpy as a profiler tool on dedicated profiling and optimisation sessions, rather than keeping it permanently as a monitoring tool.
345
345
 
346
- The contents of requests are purged from the database after 7 days, and only statistics are retained.
346
+ The contents of requests (raw bodies and block contents) are purged from the database after 7 days
347
+ by default — configurable via `[retention]` in `~/.contextspy/config.toml`. Aggregated token counts
348
+ and classifications are retained indefinitely. Purging only runs at server startup, not on a
349
+ background timer, so a `contextspy` process left running for many days in a row won't purge again
350
+ until it's restarted.
347
351
 
348
352
  The contents of database can be cleared manually by running `contextspy reset-db`.
349
353
  In practice, it is recommended to do it from time to time.
@@ -360,7 +364,10 @@ brew update
360
364
  brew upgrade contextspy
361
365
  ```
362
366
 
363
- At this stage, the database schema is subject to change, so it is advisable to purge db before upgrading.
367
+ At this stage, the database schema is subject to change. Structural changes (new tables/columns)
368
+ are applied automatically on next startup. If a data migration is needed (e.g. backfilling new
369
+ derived data for existing requests), `contextspy start` will print a warning — run
370
+ `contextspy db-upgrade` to backfill, or `contextspy reset-db` to start fresh.
364
371
 
365
372
  ## Tech stack
366
373
 
@@ -21,14 +21,14 @@
21
21
  </p>
22
22
 
23
23
  ContextSpy is a context window profiler for large language models and common agentic AI coding tools.
24
- It is used to intercept requests to LLM API, analyze and visualize prompt composition, and track context
25
- changes between multiple requests in same session. Modern AI coding agents (GitHub Copilot, Claude Code, Opencode, etc.) pack a lot into each LLM request: system prompts, tool definitions and results, file contents, conversation history. It's often unclear why a session is slow, expensive, or hitting
24
+ It is used to intercept requests to an LLM API, analyze and visualize prompt composition, and track context
25
+ changes between multiple requests in the same session. Modern AI coding agents (GitHub Copilot, Claude Code, opencode, etc.) pack a lot into each LLM request: system prompts, tool definitions and results, file contents, conversation history. It's often unclear why a session is slow, expensive, or hitting
26
26
  the context limit. ContextSpy makes the invisible visible - you see a live breakdown of
27
27
  every token category for every request, across sessions, over time.
28
28
 
29
29
  <p align="center"><strong>Example dashboard view</strong><br><img src="docs/_static/dashboard.png" alt="Dashboard view"></p>
30
30
 
31
- Think of your favorite CPU or memory profiler, just applied to contents of the context of AI agent. While you can optimize pefromance just by reviewing code, having a profiler to capture and visualise shapshot data helps alot. Same with LLM context optmisation.
31
+ Think of your favorite CPU or memory profiler, just applied to the contents of the context of an AI agent. While you can optimize performance just by reviewing code, having a profiler to capture and visualise snapshot data helps a lot. Same with LLM context optimisation.
32
32
 
33
33
  ## Quick start
34
34
 
@@ -45,32 +45,32 @@ sudo contextspy install-cert
45
45
  contextspy start
46
46
 
47
47
  # In a new terminal: launch your coding agent through the proxy
48
- # contextspy run sets required environment variables, so LLM requests are routed though the proxy
49
- contextspy run claude <path to your project>
50
- # contextspy run opencode <path to your project>
48
+ # contextspy run sets required environment variables, so LLM requests are routed through the proxy
49
+ contextspy run opencode <path to your project>
51
50
  # contextspy run code <path to your project>
51
+ # contextspy run claude # run in the drectory of your project
52
52
  ```
53
53
  Open http://127.0.0.1:5173 in your browser for the ContextSpy dashboard.
54
54
 
55
55
  If something doesn't work, see the [troubleshooting section](docs/install.md#troubleshooting) in the install guide.
56
56
 
57
- Alternatively, refer to [configure your agent](docs/cloud-mode.md) on how to route LLM traffic through proxy at `http://127.0.0.1:8888`
57
+ Alternatively, refer to [configure your agent](docs/cloud-mode.md) on how to route LLM traffic through the proxy at `http://127.0.0.1:8888`
58
58
 
59
59
  ## Context profiling? Why should I care?
60
60
 
61
- **Token costs are rising.** With AI agents embracing more and more complex workflows and usecases, token consumption and subsequent
61
+ **Token costs are rising.** With AI agents embracing more and more complex workflows and use cases, token consumption and subsequent
62
62
  cloud API bills are growing larger and larger. This is also applicable for AI coding agents and tools,
63
63
  where providers are gradually switching from subsidized subscription mode and are either reducing token
64
- limits or switching to token usage based billing (e.g. GitHub Copilot)
64
+ limits or switching to token usage based billing (e.g. GitHub Copilot).
65
65
 
66
66
  **Input tokens are major part**. When discussing AI model pricing, most people bring up token generation cost - that's where the numbers look
67
67
  most dramatic ($25 per million tokens for Opus 4.8 output vs $0.40 for gpt-5-nano). But in agentic
68
- workloads, input tokens outnumber output by 20-50x, or even more. So the most of your API bill is influenced
68
+ workloads, input tokens outnumber output by 20-50x, or even more. So most of your API bill is influenced
69
69
  by input context, not the output the model generates.
70
70
 
71
- **AI coding agents = lots of input**. The expensive part is quick accumulation of context - with every turn it fills up with additional tokens - system prompt, skills, tool definitions, tool results, file contents, conversation history.
72
- You start with 5000 - 10000 tokens in fresh session, but by turn 25 it might be 30 to 50 thousand, spend some more time it might be hitting context window limit and compacting. Every API call to the model sends the full context
73
- as part of prompt - and here is where the token consumption and costs skyrocket quickly.
71
+ **AI coding agents = lots of input**. The expensive part is the quick accumulation of context - with every turn it fills up with additional tokens - system prompt, skills, tool definitions, tool results, file contents, conversation history.
72
+ You start with 5000 - 10000 tokens in a fresh session, but by turn 25 it might be 30 to 50 thousand, spend some more time and it might be hitting the context window limit and compacting. Every API call to the model sends the full context
73
+ as part of the prompt - and here is where the token consumption and costs skyrocket quickly.
74
74
 
75
75
  ## Why large context is bad
76
76
 
@@ -79,14 +79,14 @@ We all have been told that the more information we will give to the model, the m
79
79
  There are three ways you pay for extra (and sometimes unnecessary) information in your context:
80
80
 
81
81
  1. **API Costs** - even with near perfect cache hits, input token costs outweigh output, often by order of magnitude or more.
82
- 2. **Compute and latency** - larger contexts take considerably longer to process - especially in local hosted models
82
+ 2. **Compute and latency** - larger contexts take considerably longer to process - especially in locally hosted models
83
83
  3. **Context rot** - with larger contexts, LLMs start to lose precision rapidly, with [100k being the limit](https://www.trychroma.com/research/context-rot) where rapid degradation starts. So you are paying for more expensive model, but getting performance of cheaper one - or even worse.
84
84
 
85
85
  ContextSpy makes these costs visible so you can act on them.
86
86
 
87
87
  ## How does it work
88
88
 
89
- ContextSpy starts a HTTPS proxy (or reverse proxy for locally hosted models) which intercepts every request to LLMs, analyzes it and stores to local SQLite db. A webserver is also started on localhost, and serves dashboard to visualise all captured data.
89
+ ContextSpy starts an HTTPS proxy (or reverse proxy for locally hosted models) which intercepts every request to LLMs, analyzes it and stores to local SQLite db. A webserver is also started on localhost, and serves dashboard to visualise all captured data.
90
90
 
91
91
  ## Some screenshots
92
92
 
@@ -105,7 +105,11 @@ The proxy and dashboard server are bound to localhost, and not exposed to extern
105
105
 
106
106
  The intended use case is to run ContextSpy as a profiler tool on dedicated profiling and optimisation sessions, rather than keeping it permanently as a monitoring tool.
107
107
 
108
- The contents of requests are purged from the database after 7 days, and only statistics are retained.
108
+ The contents of requests (raw bodies and block contents) are purged from the database after 7 days
109
+ by default — configurable via `[retention]` in `~/.contextspy/config.toml`. Aggregated token counts
110
+ and classifications are retained indefinitely. Purging only runs at server startup, not on a
111
+ background timer, so a `contextspy` process left running for many days in a row won't purge again
112
+ until it's restarted.
109
113
 
110
114
  The contents of database can be cleared manually by running `contextspy reset-db`.
111
115
  In practice, it is recommended to do it from time to time.
@@ -122,7 +126,10 @@ brew update
122
126
  brew upgrade contextspy
123
127
  ```
124
128
 
125
- At this stage, the database schema is subject to change, so it is advisable to purge db before upgrading.
129
+ At this stage, the database schema is subject to change. Structural changes (new tables/columns)
130
+ are applied automatically on next startup. If a data migration is needed (e.g. backfilling new
131
+ derived data for existing requests), `contextspy start` will print a warning — run
132
+ `contextspy db-upgrade` to backfill, or `contextspy reset-db` to start fresh.
126
133
 
127
134
  ## Tech stack
128
135