|
6 | 6 |
|
7 | 7 | The evidence layer for context engineering. Profile before you prune. |
8 | 8 |
|
9 | | -`context-profiler` turns raw provider requests, observability exports, and agent trajectories into evidence about how context grows, repeats, and concentrates — so you know **what** to compact and **where** it's safe to cut. |
| 9 | +`context-profiler` analyzes how context grows, repeats, and concentrates across agent turns — so you know **what** to compact and **where** it's safe to cut. |
10 | 10 |
|
11 | 11 | <p align="center"> |
12 | | - <img src="assets/readme/hero.png" alt="context-profiler: Icicle view showing token distribution across a 31-turn SWE-agent session" width="100%"> |
| 12 | + <img src="assets/readme/demo.gif" alt="context-profiler CLI demo" width="720"> |
13 | 13 | </p> |
14 | 14 |
|
15 | | -## Why |
16 | | - |
17 | | -Compression tools (LLMLingua, `/compact`, Mem0) execute blindly. They don't tell you what's redundant, what's safe to remove, or what downstream references will break. `context-profiler` fills the missing step: |
| 15 | +## Two interfaces, one workflow |
18 | 16 |
|
19 | 17 | ``` |
20 | | -trace → profile → human review → prune/compact decision |
| 18 | +trace → diagnose (agent) → report (human) → prune/compact decision |
| 19 | +``` |
| 20 | + |
| 21 | +- **`diagnose --json`** — stable issue codes and evidence for agents to act on automatically |
| 22 | +- **`analyze --html`** — interactive report for humans to review before cutting |
| 23 | + |
| 24 | +## Install |
| 25 | + |
| 26 | +```bash |
| 27 | +pipx install context-profiler |
| 28 | +# or: uv tool install context-profiler |
21 | 29 | ``` |
22 | 30 |
|
23 | | -Built for both humans and agents: |
24 | | -- **HTML reports** — interactive timeline, icicle, persistence heatmap, tools, diff, findings |
25 | | -- **JSON contracts** — stable issue codes and evidence for automated agent workflows |
26 | | -- **Trace-source agnostic** — same analysis across OpenAI, Anthropic, Langfuse, and public trajectory datasets |
| 31 | +## Quick Start |
| 32 | + |
| 33 | +```bash |
| 34 | +# Generate an interactive HTML report |
| 35 | +context-profiler analyze examples/swe_agent/session.jsonl --format openai --html report.html |
| 36 | + |
| 37 | +# Get machine-readable diagnosis for agent consumption |
| 38 | +context-profiler diagnose trace.json --format auto --json |
| 39 | +``` |
27 | 40 |
|
28 | 41 | ## Report Views |
29 | 42 |
|
30 | 43 | <table> |
31 | 44 | <tr> |
32 | 45 | <td width="50%"> |
33 | | - <img src="assets/readme/semantic.png" alt="Icicle view with semantic color and diff mode" width="100%"> |
34 | | - <br> |
35 | | - <strong>Icicle</strong> |
36 | | - <br> |
37 | | - Token distribution per request. Semantic color by role, diff mode for additions/removals. |
| 46 | + <img src="assets/readme/semantic.png" alt="Icicle view" width="100%"> |
| 47 | + <br><strong>Icicle</strong> — token distribution per request, diff mode for additions/removals |
38 | 48 | </td> |
39 | 49 | <td width="50%"> |
40 | | - <img src="assets/readme/persistence.png" alt="Persistence heatmap showing content blocks across requests" width="100%"> |
41 | | - <br> |
42 | | - <strong>Persistence</strong> |
43 | | - <br> |
44 | | - Which content blocks survive across turns. Blue = token cost. Red = compact candidate. |
| 50 | + <img src="assets/readme/persistence.png" alt="Persistence heatmap" width="100%"> |
| 51 | + <br><strong>Persistence</strong> — what survives across turns. Red = compact candidate |
45 | 52 | </td> |
46 | 53 | </tr> |
47 | 54 | <tr> |
48 | 55 | <td width="50%"> |
49 | | - <img src="assets/readme/tools.png" alt="Tools view with token table and invocation detail" width="100%"> |
50 | | - <br> |
51 | | - <strong>Tools</strong> |
52 | | - <br> |
53 | | - Which tools dominate the context budget and their invocation details. |
| 56 | + <img src="assets/readme/tools.png" alt="Tools view" width="100%"> |
| 57 | + <br><strong>Tools</strong> — which tools dominate the context budget |
54 | 58 | </td> |
55 | 59 | <td width="50%"> |
56 | | - <img src="assets/readme/findings.png" alt="Findings drawer with grouped diagnosis issues" width="100%"> |
57 | | - <br> |
58 | | - <strong>Findings</strong> |
59 | | - <br> |
60 | | - Issue codes with severity, evidence, and actionable recommendations. |
| 60 | + <img src="assets/readme/findings.png" alt="Findings drawer" width="100%"> |
| 61 | + <br><strong>Findings</strong> — issue codes with evidence and recommendations |
61 | 62 | </td> |
62 | 63 | </tr> |
63 | 64 | </table> |
64 | 65 |
|
65 | | -## Findings Across Public Datasets |
66 | | - |
67 | | -Profiled on real multi-turn agent trajectories from public benchmarks: |
68 | | - |
69 | | -| Dataset | Domain | Turns | Total Tokens | Redundancy | Top Issue | Carryover | |
70 | | -|---------|--------|-------|-------------|------------|-----------|-----------| |
71 | | -| [SWE-agent](https://huggingface.co/datasets/nebius/SWE-agent-trajectories) | Coding agent | 31 | 27.1K | 26.9% | `REPEATED_CONTENT_BLOCK` | 231K across 20 blocks | |
72 | | -| [lmcache](https://huggingface.co/datasets/sammshen/lmcache-agentic-traces) | KV-cache traces | 35 | 36.5K | 1.4% | `REPEATED_CONTENT_BLOCK` | 403K across 20 blocks | |
73 | | -| [OpenHands](https://huggingface.co/datasets/nvidia/SWE-Zero-openhands-trajectories) | Tool-heavy agent | 34 | 23.9K | 0.2% | `REPEATED_CONTENT_BLOCK` | 383K across 20 blocks | |
74 | | - |
75 | | -All examples are included in [`examples/`](examples/) with conversion scripts and pre-converted session files. |
76 | | - |
77 | | -## Install |
78 | | - |
79 | | -For agent/CLI use, prefer an isolated executable install: |
80 | | - |
81 | | -```bash |
82 | | -pipx install context-profiler |
83 | | -# or |
84 | | -uv tool install context-profiler |
85 | | -context-profiler --version |
86 | | -which -a context-profiler # ensure a stale executable is not shadowing pipx/uv |
87 | | -``` |
88 | | - |
89 | | -Or install from source: |
90 | | - |
91 | | -```bash |
92 | | -git clone https://github.com/Turdot/context-profiler.git |
93 | | -cd context-profiler |
94 | | -uv tool install -e . |
95 | | -# for local development in this repo: |
96 | | -PYTHONPATH=src uv run context-profiler --version |
97 | | -``` |
98 | | - |
99 | | -## Quick Start |
100 | | - |
101 | | -Analyze a multi-turn agent session (SWE-agent trajectory included): |
102 | | - |
103 | | -```bash |
104 | | -context-profiler analyze examples/swe_agent/session.jsonl --format openai --html report.html |
105 | | -``` |
106 | | - |
107 | | -Analyze a raw provider request: |
108 | | - |
109 | | -```bash |
110 | | -context-profiler analyze request.json --format auto |
111 | | -context-profiler diagnose request.json --format auto --json |
112 | | -``` |
113 | | - |
114 | | -Analyze a Langfuse export: |
| 66 | +## Agent Harness |
115 | 67 |
|
116 | | -```bash |
117 | | -context-profiler validate trace.json --format langfuse --json |
118 | | -context-profiler diagnose trace.json --format langfuse --json |
119 | | -context-profiler analyze trace.json --format langfuse --html report.html |
120 | | -``` |
121 | | - |
122 | | -Fetch a Langfuse trace through the public API, then analyze it: |
123 | | - |
124 | | -```bash |
125 | | -TRACE_ID="<trace-id>" |
126 | | -HOST="${LANGFUSE_HOST%/}" |
127 | | -OUT="/tmp/langfuse-trace-${TRACE_ID}" |
128 | | -mkdir -p "$OUT" |
129 | | - |
130 | | -curl -fsS \ |
131 | | - -u "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" \ |
132 | | - "$HOST/api/public/traces/$TRACE_ID" \ |
133 | | - -o "$OUT/trace.json" |
134 | | - |
135 | | -curl -fsS \ |
136 | | - -u "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" \ |
137 | | - "$HOST/api/public/observations?traceId=$TRACE_ID&limit=100&page=1" \ |
138 | | - -o "$OUT/observations-page-1.json" |
139 | | - |
140 | | -context-profiler diagnose "$OUT/trace.json" --format langfuse --json |
141 | | -``` |
142 | | - |
143 | | -Analyze a public academic agent trajectory: |
| 68 | +Agents use the CLI to discover formats, validate input, and get structured diagnosis: |
144 | 69 |
|
145 | 70 | ```bash |
146 | | -context-profiler diagnose examples/agent-trace/sample.json --format agent-trace --json |
147 | | -context-profiler analyze examples/agent-trace/sample.json --format agent-trace --html report.html |
| 71 | +context-profiler formats list --json # discover supported formats |
| 72 | +context-profiler validate trace.json --json # check before analyzing |
| 73 | +context-profiler diagnose trace.json --json # structured issues + evidence |
148 | 74 | ``` |
149 | 75 |
|
150 | | -Generate an interactive report: |
151 | | - |
152 | | -```bash |
153 | | -context-profiler analyze session.jsonl --html report.html |
154 | | -``` |
155 | | - |
156 | | -## CLI Output |
157 | | - |
158 | | -The terminal report gives a quick read on context budget, repeated content, and tool hotspots before you open the HTML report. |
159 | | - |
160 | | -```text |
161 | | -╭──────────────────────────────────────────────────────────────────────────────╮ |
162 | | -│ context-profiler | mode: snapshot | source: │ |
163 | | -│ tests/fixtures/repeated_tool_calls.json │ |
164 | | -╰──────────────────────────────────────────────────────────────────────────────╯ |
165 | | -
|
166 | | -⚠ Warnings |
167 | | - • Content duplication: 476 redundant tokens (60.2% of total) |
168 | | -
|
169 | | -Token Distribution |
170 | | - Category Tokens % of Total |
171 | | - Total Input 791 100% |
172 | | - System Prompt 13 1.6% |
173 | | - Tool Definitions 83 10.5% |
174 | | - Messages (assistant) 609 77.0% |
175 | | - Messages (tool) 70 8.8% |
176 | | - Messages (user) 16 2.0% |
177 | | -
|
178 | | - Top Tools by Token Usage |
179 | | - generate_canvas_component 595 75.2% |
180 | | -``` |
181 | | - |
182 | | -## Agent-Friendly CLI Harness |
183 | | - |
184 | | -`context-profiler` is strict about supported formats but helpful when input does not match. Agents can discover contracts and adapt unsupported traces without asking users to reshape data manually. |
185 | | - |
186 | | -```bash |
187 | | -# Discover supported formats |
188 | | -context-profiler formats list --json |
189 | | -context-profiler formats describe cursor-jsonl --json |
190 | | - |
191 | | -# Discover canonical contracts |
192 | | -context-profiler schema trace --json |
193 | | -context-profiler schema diagnosis --json |
194 | | - |
195 | | -# Validate and normalize |
196 | | -context-profiler validate trace.json --format auto --json |
197 | | -context-profiler normalize trace.json --from auto --json |
198 | | - |
199 | | -# Diagnose for agent consumption; '-' reads JSON/JSONL from stdin |
200 | | -context-profiler diagnose trace.json --format auto --json |
201 | | -``` |
202 | | - |
203 | | -If validation fails, the JSON response includes `errors[].agent_action` and `next_steps` so the agent can convert the trace into `ContextTrace`. |
204 | | - |
205 | | -## Agent Skill Distribution |
206 | | - |
207 | | -This repository ships an `analyze-agent-context` skill for Cursor, Claude Code, and other Agent Skills / Open Plugins compatible tools. |
208 | | - |
209 | | -The skill does not make `context-profiler` fetch traces itself. It teaches agents to fetch Langfuse trace ids with the Langfuse public API via `curl`, then route the fetched JSON into `context-profiler` for diagnosis whenever the user asks to analyze a trace, loop, transcript, agent run, context growth, stale context, or tool bloat. It intentionally avoids `langfuse-cli` for trace fetching because the CLI may omit fields needed for complete analysis. |
210 | | - |
211 | | -Canonical skill: |
212 | | - |
213 | | -```text |
214 | | -skills/analyze-agent-context/SKILL.md |
215 | | -``` |
216 | | - |
217 | | -Plugin manifests: |
218 | | - |
219 | | -```text |
220 | | -.plugin/plugin.json |
221 | | -.claude-plugin/marketplace.json |
222 | | -``` |
223 | | - |
224 | | -## Supported Inputs |
225 | | - |
226 | | -Use `context-profiler formats list --json` for the current machine-readable registry. |
227 | | - |
228 | | -| Kind | Formats | Confidence | |
229 | | -|------|---------|------------| |
230 | | -| Provider request | OpenAI, Anthropic | exact | |
231 | | -| Observability trace | Langfuse, planned OTel/OpenInference | high | |
232 | | -| Agent transcript | Cursor JSONL, Claude Code JSONL | partial | |
233 | | -| Benchmark trajectory | planned agent-trace, agent_trajectories, SWE-agent | dataset-dependent | |
234 | | - |
235 | | -For `agent-transcript`, analysis is intentionally marked `partial`: hidden system prompts, rules, tool definitions, MCP schemas, and provider compaction may not be present. |
236 | | - |
237 | | -## Example Diagnosis |
| 76 | +Example diagnosis output: |
238 | 77 |
|
239 | 78 | ```json |
240 | 79 | { |
241 | 80 | "issues": [ |
242 | 81 | { |
243 | | - "code": "TOOL_USE_DOMINATES_CONTEXT", |
| 82 | + "code": "TOOL_INPUT_BLOAT", |
244 | 83 | "severity": "critical", |
245 | | - "message": "Tool inputs dominate the visible context." |
246 | | - }, |
247 | | - { |
248 | | - "code": "TOP_TOOL_CONTEXT_HOTSPOT", |
249 | | - "message": "ApplyPatch is the largest visible tool context hotspot." |
250 | | - } |
251 | | - ], |
252 | | - "diff_hints": [ |
253 | | - { |
254 | | - "type": "large_addition", |
255 | | - "request_index": 76, |
256 | | - "evidence": { |
257 | | - "added_tokens": 7473, |
258 | | - "top_added_tool": "ApplyPatch" |
259 | | - } |
| 84 | + "message": "Tool inputs (not results) consume a large share of context.", |
| 85 | + "evidence": { "tool_input_tokens": 595, "ratio": 0.752 }, |
| 86 | + "recommendation": "Consider using artifact references or shorter identifiers." |
260 | 87 | } |
261 | 88 | ] |
262 | 89 | } |
263 | 90 | ``` |
264 | 91 |
|
265 | | -Academic trajectory sample: |
| 92 | +Issue codes: `TOOL_INPUT_BLOAT`, `TOOL_RESULT_DOMINATES`, `TOP_TOOL_CONTEXT_HOTSPOT`, `REPEATED_CONTENT_BLOCK`, `REPEATED_TOOL_INPUT`, `STATIC_CONTEXT_BLOAT` |
266 | 93 |
|
267 | | -```text |
268 | | -context-profiler analyze examples/agent-trace/sample.json --format agent-trace --html report.html |
| 94 | +This repo also ships an [`analyze-agent-context`](skills/analyze-agent-context/SKILL.md) skill for Cursor, Claude Code, and Open Plugins compatible tools. |
269 | 95 |
|
270 | | -Total Input: 11.7K |
271 | | -Messages (assistant): 10.7K |
272 | | -Tool: python_interpreter 2.9K |
273 | | -Warnings: Content duplication 2.3K redundant tokens |
274 | | -``` |
275 | | - |
276 | | -## Examples |
277 | | - |
278 | | -See [`examples/README.md`](examples/README.md) for runnable fixtures and conversion patterns. |
| 96 | +## Supported Inputs |
279 | 97 |
|
280 | | -Recommended demo order: |
| 98 | +| Kind | Formats | Confidence | |
| 99 | +|------|---------|------------| |
| 100 | +| Provider request | OpenAI, Anthropic | exact | |
| 101 | +| Observability trace | Langfuse | high | |
| 102 | +| Agent transcript | Cursor JSONL, Claude Code JSONL | partial | |
| 103 | +| Benchmark trajectory | agent-trace, SWE-agent | dataset-dependent | |
281 | 104 |
|
282 | | -1. Raw OpenAI/Anthropic request. |
283 | | -2. Cursor or Claude Code transcript. |
284 | | -3. Langfuse trace export. |
285 | | -4. Multi-turn academic trajectories such as `pagarsky/agent-trace`, `cx-cmu/agent_trajectories`, or SWE-agent traces. |
| 105 | +## Findings on Public Datasets |
286 | 106 |
|
287 | | -## Research Context |
| 107 | +| Dataset | Turns | Redundancy | Top Issue | Carryover | |
| 108 | +|---------|-------|------------|-----------|-----------| |
| 109 | +| [SWE-agent](https://huggingface.co/datasets/nebius/SWE-agent-trajectories) | 31 | 26.9% | `REPEATED_CONTENT_BLOCK` | 231K across 20 blocks | |
| 110 | +| [lmcache](https://huggingface.co/datasets/sammshen/lmcache-agentic-traces) | 35 | 1.4% | `REPEATED_CONTENT_BLOCK` | 403K across 20 blocks | |
| 111 | +| [OpenHands](https://huggingface.co/datasets/nvidia/SWE-Zero-openhands-trajectories) | 34 | 0.2% | `REPEATED_CONTENT_BLOCK` | 383K across 20 blocks | |
288 | 112 |
|
289 | | -`context-profiler` is motivated by recent work showing that long-horizon agents are constrained not only by model quality, but also by how their working context is retained, compressed, and reused across turns. |
| 113 | +All examples included in [`examples/`](examples/) with conversion scripts. |
290 | 114 |
|
291 | | -Related work: |
| 115 | +## Development |
292 | 116 |
|
293 | | -- **ByteDance Seed — _Scaling Long-Horizon LLM Agent via Context-Folding_** |
294 | | - Studies context management for long-horizon agents through folding and summarizing intermediate sub-trajectories. This motivates `context-profiler`'s focus on turn-to-turn context diffs, retained observations, and compression/pruning evidence. |
295 | | -- **SWE-agent — _Agent-Computer Interfaces Enable Automated Software Engineering_** |
296 | | - Shows the importance of the agent-computer interface for software-engineering agents, motivating analysis of tool calls, terminal output, and artifact churn. |
297 | | -- **WebArena — _A Realistic Web Environment for Building Autonomous Agents_** |
298 | | - Demonstrates the value of realistic multi-step agent trajectories, motivating support for loop/transcript analysis rather than only single prompt snapshots. |
| 117 | +```bash |
| 118 | +git clone https://github.com/yanpgwang/context-profiler.git |
| 119 | +cd context-profiler |
| 120 | +PYTHONPATH=src uv run --with pytest pytest tests/ -v |
| 121 | +``` |
299 | 122 |
|
300 | 123 | ## Docs |
301 | 124 |
|
302 | 125 | - [CLI harness design](docs/design/cli-harness.md) |
303 | 126 | - [Roadmap](docs/roadmap.md) |
304 | | - |
305 | | -## What It Does Not Do |
306 | | - |
307 | | -- It does not fetch traces from Langfuse, Hugging Face, Cursor, or Claude Code. |
308 | | -- It does not replay agent loops. |
309 | | -- It does not execute tools. |
310 | | -- It does not replace observability platforms. |
311 | | -- It does not pretend agent transcripts are exact raw provider requests. |
312 | | - |
313 | | -## Development |
314 | | - |
315 | | -```bash |
316 | | -PYTHONPATH=src uv run --with pytest pytest tests/test_smoke.py -v |
317 | | -``` |
| 127 | +- [Examples](examples/README.md) |
318 | 128 |
|
319 | 129 | ## Acknowledgements |
320 | 130 |
|
321 | | -This project is inspired by and learned from: |
322 | | - |
323 | | -- [context-lens](https://github.com/larsderidder/context-lens) — local proxy for capturing and visualizing LLM API calls |
324 | | -- [ContextFlame](https://github.com/jcgs2503/contextflame) — flamegraph-based token profiling for Claude Code |
325 | | -- [speedscope](https://www.speedscope.app/) — the icicle / flamegraph UI design is inspired by speedscope's interactive visualization |
| 131 | +Inspired by [context-lens](https://github.com/larsderidder/context-lens), [ContextFlame](https://github.com/jcgs2503/contextflame), and [speedscope](https://www.speedscope.app/). |
326 | 132 |
|
327 | 133 | ## License |
328 | 134 |
|
|
0 commit comments