contextpilot-ai 0.2.0__tar.gz → 0.2.2__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.
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/PKG-INFO +34 -7
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/README.md +33 -6
- contextpilot_ai-0.2.2/benchmarks/benchmark_engine.py +212 -0
- contextpilot_ai-0.2.2/benchmarks/benchmark_readme.py +590 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/contextpilot/cli.py +23 -9
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/contextpilot/compressor.py +16 -9
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/contextpilot/config.py +1 -1
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/contextpilot/mcp_server.py +143 -47
- contextpilot_ai-0.2.2/contextpilot/quality.py +102 -0
- contextpilot_ai-0.2.2/contextpilot/strategies/history.py +81 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/contextpilot/strategies/rag_pruner.py +14 -2
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/pyproject.toml +1 -1
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/tests/test_config.py +2 -2
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/tests/test_live_integration.py +1 -1
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/tests/test_mcp_server.py +10 -12
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/tests/test_strategies.py +1 -1
- contextpilot_ai-0.2.0/contextpilot/quality.py +0 -63
- contextpilot_ai-0.2.0/contextpilot/strategies/history.py +0 -54
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/.github/pull_request_template.md +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/.gitignore +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/CHANGELOG.md +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/CONTRIBUTING.md +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/LICENSE +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/SECURITY.md +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/contextpilot/__init__.py +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/contextpilot/__main__.py +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/contextpilot/_utils.py +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/contextpilot/adapters/__init__.py +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/contextpilot/adapters/anthropic_adapter.py +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/contextpilot/adapters/openai_adapter.py +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/contextpilot/analyzer.py +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/contextpilot/middleware.py +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/contextpilot/migrate.py +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/contextpilot/pipeline.py +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/contextpilot/proxy.py +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/contextpilot/service.py +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/contextpilot/shadow.py +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/contextpilot/strategies/__init__.py +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/contextpilot/strategies/agent_memory.py +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/contextpilot/strategies/dedup.py +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/contextpilot/strategies/structural.py +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/contextpilot/telemetry.py +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/contextpilot/wrapper.py +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/contextpilot.yaml.example +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/docs/claude-code-integration.md +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/examples/smoke_test.py +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/tests/__init__.py +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/tests/mock_server.py +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/tests/test_analyzer.py +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/tests/test_middleware.py +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/tests/test_migrate.py +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/tests/test_pipeline.py +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/tests/test_proxy.py +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/tests/test_quality.py +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/tests/test_service.py +0 -0
- {contextpilot_ai-0.2.0 → contextpilot_ai-0.2.2}/tests/test_wrapper.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: contextpilot-ai
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Python middleware that compresses and optimizes LLM context before each API call
|
|
5
5
|
Project-URL: Homepage, https://contextpilot.org
|
|
6
6
|
Project-URL: Repository, https://github.com/msousa202/ContextPilot
|
|
@@ -61,9 +61,9 @@ Description-Content-Type: text/markdown
|
|
|
61
61
|
[](https://pypi.org/project/contextpilot-ai/)
|
|
62
62
|
[](https://opensource.org/licenses/MIT)
|
|
63
63
|
[](https://www.python.org/downloads/)
|
|
64
|
-
[](tests/)
|
|
65
65
|
|
|
66
|
-
**Cut your LLM API costs
|
|
66
|
+
**Cut your LLM API costs 60–80% with one line of code.**
|
|
67
67
|
|
|
68
68
|
ContextPilot is a Python middleware library that compresses LLM context before each API call — transparently, with automatic quality fallback. It wraps OpenAI and Anthropic SDKs and runs across four surfaces: Python library, local proxy, MCP server, and CLI migration agent.
|
|
69
69
|
|
|
@@ -77,13 +77,40 @@ Every LLM API call passes through a four-stage pipeline:
|
|
|
77
77
|
|
|
78
78
|
1. **Analyze** — scores each message block for staleness, redundancy, relevance, and density
|
|
79
79
|
2. **Compress** — summarizes history, deduplicates system prompts, prunes irrelevant RAG chunks, strips structural noise
|
|
80
|
-
3. **Quality gate** — if predicted quality drops below threshold (default
|
|
80
|
+
3. **Quality gate** — if predicted quality drops below threshold (default 72/100), the original payload is sent instead
|
|
81
81
|
4. **Forward** — the optimized (or original) payload goes to the provider; response comes back unchanged
|
|
82
82
|
|
|
83
83
|
Zero prompt content ever leaves your environment. Telemetry is numerical metadata only.
|
|
84
84
|
|
|
85
85
|
---
|
|
86
86
|
|
|
87
|
+
## Benchmarks
|
|
88
|
+
|
|
89
|
+
Measured on realistic production conversation patterns. Each scenario uses actual repetition patterns developers encounter (accumulated context, repeated RAG chunks, repeated error traces, multi-agent handoffs).
|
|
90
|
+
|
|
91
|
+
| Scenario | Tokens | Reduction | Quality | Latency |
|
|
92
|
+
|----------|--------|-----------|---------|---------|
|
|
93
|
+
| AI coding assistant — 25 turns, growing project context | 5,810 → 1,118 | **80.8%** | 82.8/100 | 10ms |
|
|
94
|
+
| RAG chatbot — 18 turns, 5 retrieved chunks per query | 4,980 → 1,034 | **79.2%** | 83.4/100 | 9ms |
|
|
95
|
+
| Multi-agent code review — 4 agents × 6 rounds | 19,619 → 4,049 | **79.4%** | 83.9/100 | 22ms |
|
|
96
|
+
| Production debugging — 20 turns, repeated tracebacks | 3,814 → 928 | **75.7%** | 82.4/100 | 9ms |
|
|
97
|
+
| LangChain tool agent — 15 turns, 3 tool outputs/turn | 5,368 → 1,278 | **76.2%** | 83.7/100 | 8ms |
|
|
98
|
+
| Document Q&A — 16 turns, full spec prepended each query | 4,561 → 1,110 | **75.7%** | 83.9/100 | 8ms |
|
|
99
|
+
|
|
100
|
+
**Quality gate**: compression is skipped and the original payload sent whenever quality drops below threshold (default 72/100). In all 6 scenarios above, quality held at 82–84/100 — well above the threshold.
|
|
101
|
+
|
|
102
|
+
**Cost at scale** (most impactful scenario — multi-agent on Claude Opus):
|
|
103
|
+
|
|
104
|
+
| Volume | Without ContextPilot | With ContextPilot | Monthly saving |
|
|
105
|
+
|--------|---------------------|-------------------|----------------|
|
|
106
|
+
| 100 calls/day | $29/day | $6/day | **$701/mo** |
|
|
107
|
+
| 1,000 calls/day | $294/day | $61/day | **$7,006/mo** |
|
|
108
|
+
| 10,000 calls/day | $2,943/day | $607/day | **$70,065/mo** |
|
|
109
|
+
|
|
110
|
+
Run `python benchmarks/benchmark_readme.py` to reproduce these numbers locally.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
87
114
|
## Integration surfaces
|
|
88
115
|
|
|
89
116
|
| Surface | Entry point | Best for |
|
|
@@ -260,7 +287,7 @@ Drop a `contextpilot.yaml` in your project root:
|
|
|
260
287
|
```yaml
|
|
261
288
|
compression:
|
|
262
289
|
level: balanced # conservative | balanced | aggressive
|
|
263
|
-
quality_threshold:
|
|
290
|
+
quality_threshold: 72 # fallback to original if score drops below this
|
|
264
291
|
history_window: 6 # keep last N turns verbatim
|
|
265
292
|
rag_relevance_min: 0.15 # drop RAG chunks below this relevance score
|
|
266
293
|
|
|
@@ -325,10 +352,10 @@ python -m contextpilot mcp
|
|
|
325
352
|
|
|
326
353
|
## Contributing
|
|
327
354
|
|
|
328
|
-
See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
355
|
+
See [CONTRIBUTING.md](https://github.com/msousa202/ContextPilot/blob/main/CONTRIBUTING.md).
|
|
329
356
|
|
|
330
357
|
---
|
|
331
358
|
|
|
332
359
|
## License
|
|
333
360
|
|
|
334
|
-
MIT — see [LICENSE](LICENSE).
|
|
361
|
+
MIT — see [LICENSE](https://github.com/msousa202/ContextPilot/blob/main/LICENSE).
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
[](https://pypi.org/project/contextpilot-ai/)
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
5
|
[](https://www.python.org/downloads/)
|
|
6
|
-
[](tests/)
|
|
7
7
|
|
|
8
|
-
**Cut your LLM API costs
|
|
8
|
+
**Cut your LLM API costs 60–80% with one line of code.**
|
|
9
9
|
|
|
10
10
|
ContextPilot is a Python middleware library that compresses LLM context before each API call — transparently, with automatic quality fallback. It wraps OpenAI and Anthropic SDKs and runs across four surfaces: Python library, local proxy, MCP server, and CLI migration agent.
|
|
11
11
|
|
|
@@ -19,13 +19,40 @@ Every LLM API call passes through a four-stage pipeline:
|
|
|
19
19
|
|
|
20
20
|
1. **Analyze** — scores each message block for staleness, redundancy, relevance, and density
|
|
21
21
|
2. **Compress** — summarizes history, deduplicates system prompts, prunes irrelevant RAG chunks, strips structural noise
|
|
22
|
-
3. **Quality gate** — if predicted quality drops below threshold (default
|
|
22
|
+
3. **Quality gate** — if predicted quality drops below threshold (default 72/100), the original payload is sent instead
|
|
23
23
|
4. **Forward** — the optimized (or original) payload goes to the provider; response comes back unchanged
|
|
24
24
|
|
|
25
25
|
Zero prompt content ever leaves your environment. Telemetry is numerical metadata only.
|
|
26
26
|
|
|
27
27
|
---
|
|
28
28
|
|
|
29
|
+
## Benchmarks
|
|
30
|
+
|
|
31
|
+
Measured on realistic production conversation patterns. Each scenario uses actual repetition patterns developers encounter (accumulated context, repeated RAG chunks, repeated error traces, multi-agent handoffs).
|
|
32
|
+
|
|
33
|
+
| Scenario | Tokens | Reduction | Quality | Latency |
|
|
34
|
+
|----------|--------|-----------|---------|---------|
|
|
35
|
+
| AI coding assistant — 25 turns, growing project context | 5,810 → 1,118 | **80.8%** | 82.8/100 | 10ms |
|
|
36
|
+
| RAG chatbot — 18 turns, 5 retrieved chunks per query | 4,980 → 1,034 | **79.2%** | 83.4/100 | 9ms |
|
|
37
|
+
| Multi-agent code review — 4 agents × 6 rounds | 19,619 → 4,049 | **79.4%** | 83.9/100 | 22ms |
|
|
38
|
+
| Production debugging — 20 turns, repeated tracebacks | 3,814 → 928 | **75.7%** | 82.4/100 | 9ms |
|
|
39
|
+
| LangChain tool agent — 15 turns, 3 tool outputs/turn | 5,368 → 1,278 | **76.2%** | 83.7/100 | 8ms |
|
|
40
|
+
| Document Q&A — 16 turns, full spec prepended each query | 4,561 → 1,110 | **75.7%** | 83.9/100 | 8ms |
|
|
41
|
+
|
|
42
|
+
**Quality gate**: compression is skipped and the original payload sent whenever quality drops below threshold (default 72/100). In all 6 scenarios above, quality held at 82–84/100 — well above the threshold.
|
|
43
|
+
|
|
44
|
+
**Cost at scale** (most impactful scenario — multi-agent on Claude Opus):
|
|
45
|
+
|
|
46
|
+
| Volume | Without ContextPilot | With ContextPilot | Monthly saving |
|
|
47
|
+
|--------|---------------------|-------------------|----------------|
|
|
48
|
+
| 100 calls/day | $29/day | $6/day | **$701/mo** |
|
|
49
|
+
| 1,000 calls/day | $294/day | $61/day | **$7,006/mo** |
|
|
50
|
+
| 10,000 calls/day | $2,943/day | $607/day | **$70,065/mo** |
|
|
51
|
+
|
|
52
|
+
Run `python benchmarks/benchmark_readme.py` to reproduce these numbers locally.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
29
56
|
## Integration surfaces
|
|
30
57
|
|
|
31
58
|
| Surface | Entry point | Best for |
|
|
@@ -202,7 +229,7 @@ Drop a `contextpilot.yaml` in your project root:
|
|
|
202
229
|
```yaml
|
|
203
230
|
compression:
|
|
204
231
|
level: balanced # conservative | balanced | aggressive
|
|
205
|
-
quality_threshold:
|
|
232
|
+
quality_threshold: 72 # fallback to original if score drops below this
|
|
206
233
|
history_window: 6 # keep last N turns verbatim
|
|
207
234
|
rag_relevance_min: 0.15 # drop RAG chunks below this relevance score
|
|
208
235
|
|
|
@@ -267,10 +294,10 @@ python -m contextpilot mcp
|
|
|
267
294
|
|
|
268
295
|
## Contributing
|
|
269
296
|
|
|
270
|
-
See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
297
|
+
See [CONTRIBUTING.md](https://github.com/msousa202/ContextPilot/blob/main/CONTRIBUTING.md).
|
|
271
298
|
|
|
272
299
|
---
|
|
273
300
|
|
|
274
301
|
## License
|
|
275
302
|
|
|
276
|
-
MIT — see [LICENSE](LICENSE).
|
|
303
|
+
MIT — see [LICENSE](https://github.com/msousa202/ContextPilot/blob/main/LICENSE).
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
"""5 realistic benchmark scenarios demonstrating real token savings."""
|
|
2
|
+
import sys, io
|
|
3
|
+
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
|
|
4
|
+
|
|
5
|
+
from contextpilot.pipeline import Pipeline
|
|
6
|
+
from contextpilot.config import ContextPilotConfig
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def bench(msgs, system=None, level="balanced", model="gpt-4o", rate=5.00):
|
|
10
|
+
cfg = ContextPilotConfig.load()
|
|
11
|
+
cfg.compression.level = level
|
|
12
|
+
p = Pipeline(cfg)
|
|
13
|
+
_, _, e = p.optimize(msgs, system=system, provider="openai", model=model)
|
|
14
|
+
o, c = e.tokens_input_original, e.tokens_input_compressed
|
|
15
|
+
saved = o - c
|
|
16
|
+
pct = saved / o * 100 if o else 0
|
|
17
|
+
status = "FALLBACK " if e.fallback_triggered else "COMPRESSED "
|
|
18
|
+
print(f" {status} {o:,} -> {c:,} tokens {pct:.1f}% reduction "
|
|
19
|
+
f"quality={e.quality_score:.1f}/100 {e.compression_ms:.0f}ms")
|
|
20
|
+
if not e.fallback_triggered and pct > 0:
|
|
21
|
+
daily_before = o / 1_000_000 * rate * 1000
|
|
22
|
+
daily_after = c / 1_000_000 * rate * 1000
|
|
23
|
+
print(f" At 1k calls/day: ${daily_before:.2f} -> ${daily_after:.2f} "
|
|
24
|
+
f"(save ${daily_before - daily_after:.2f}/day, "
|
|
25
|
+
f"${(daily_before - daily_after) * 30:.0f}/mo)")
|
|
26
|
+
return e
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# --------------------------------------------------------------------------
|
|
30
|
+
# TEST 1: Long repetitive coding session (Claude Code user, same codebase)
|
|
31
|
+
# Realistic: each message re-states the project context
|
|
32
|
+
# --------------------------------------------------------------------------
|
|
33
|
+
print()
|
|
34
|
+
print("TEST 1: Long coding session — 15 rounds, same codebase context per turn")
|
|
35
|
+
print("-" * 70)
|
|
36
|
+
code_ctx = (
|
|
37
|
+
"We are building a Python FastAPI application with PostgreSQL database. "
|
|
38
|
+
"The main models are User, Product, and Order. Authentication uses JWT tokens "
|
|
39
|
+
"stored in Redis. The codebase follows clean architecture with repository pattern. "
|
|
40
|
+
)
|
|
41
|
+
msgs1 = []
|
|
42
|
+
for i in range(15):
|
|
43
|
+
msgs1.append({"role": "user",
|
|
44
|
+
"content": code_ctx + f"Task {i}: implement the endpoint for operation {i}."})
|
|
45
|
+
msgs1.append({"role": "assistant",
|
|
46
|
+
"content": code_ctx + f"Here is the implementation for task {i}. "
|
|
47
|
+
f"def endpoint_{i}(db: Session): return crud.get_item_{i}(db)"})
|
|
48
|
+
msgs1.append({"role": "user",
|
|
49
|
+
"content": "Now write comprehensive integration tests for all endpoints."})
|
|
50
|
+
bench(msgs1)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
# --------------------------------------------------------------------------
|
|
54
|
+
# TEST 2: RAG pipeline — same docs prepended every turn (common pattern)
|
|
55
|
+
# Realistic: RAG pipeline retrieves same chunks repeatedly
|
|
56
|
+
# --------------------------------------------------------------------------
|
|
57
|
+
print()
|
|
58
|
+
print("TEST 2: RAG chatbot — same retrieved docs prepended on every turn (12 rounds)")
|
|
59
|
+
print("-" * 70)
|
|
60
|
+
irrelevant = (
|
|
61
|
+
"The history of ancient Rome spans more than a millennium starting from the Tiber. "
|
|
62
|
+
"Byzantine Empire preserved Roman traditions from 4th to 15th century. "
|
|
63
|
+
"Mediterranean diet reduces cardiovascular risk through olive oil and legumes. "
|
|
64
|
+
"Greek philosophy including Stoicism influenced Roman emperors like Marcus Aurelius. "
|
|
65
|
+
)
|
|
66
|
+
relevant = (
|
|
67
|
+
"FastAPI is a modern Python web framework built on Starlette and Pydantic. "
|
|
68
|
+
"Install with: pip install fastapi uvicorn. Routes use Python decorators. "
|
|
69
|
+
"It auto-generates OpenAPI docs and validates requests via type hints. "
|
|
70
|
+
)
|
|
71
|
+
msgs2 = []
|
|
72
|
+
for i in range(12):
|
|
73
|
+
# Each turn: irrelevant docs + relevant doc + question
|
|
74
|
+
context = irrelevant * 2 + relevant + f" Follow-up question {i}: What about async support?"
|
|
75
|
+
msgs2.append({"role": "user", "content": context})
|
|
76
|
+
msgs2.append({"role": "assistant",
|
|
77
|
+
"content": f"FastAPI supports async natively via Python async/await. "
|
|
78
|
+
f"Answer {i}: use async def for route handlers."})
|
|
79
|
+
msgs2.append({"role": "user", "content": "How do I deploy FastAPI with uvicorn in production?"})
|
|
80
|
+
bench(msgs2)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
# --------------------------------------------------------------------------
|
|
84
|
+
# TEST 3: Verbose system prompt sent on every call (300-word system prompt)
|
|
85
|
+
# Realistic: coding assistant with detailed instructions
|
|
86
|
+
# --------------------------------------------------------------------------
|
|
87
|
+
print()
|
|
88
|
+
print("TEST 3: Verbose system prompt — 300-word prompt, 10 conversation turns")
|
|
89
|
+
print("-" * 70)
|
|
90
|
+
sys_prompt = (
|
|
91
|
+
"You are a senior software engineer and technical lead with 15 years of experience. "
|
|
92
|
+
"You write clean, well-tested, documented Python code following PEP 8 and PEP 257. "
|
|
93
|
+
"You always consider edge cases, error handling, and performance implications. "
|
|
94
|
+
"You never use global variables. You prefer composition over inheritance. "
|
|
95
|
+
"You always add type hints. You write docstrings for all public functions. "
|
|
96
|
+
"You consider security implications in every implementation decision you make. "
|
|
97
|
+
"You follow the SOLID principles and clean architecture patterns in every project. "
|
|
98
|
+
"You always suggest writing unit tests first. You use pytest for all testing needs. "
|
|
99
|
+
"You prefer async code when dealing with any I/O bound operations whatsoever. "
|
|
100
|
+
"You always explain your reasoning thoroughly and clearly before writing any code. "
|
|
101
|
+
"You review your own code for bugs before submitting. You never skip error handling. "
|
|
102
|
+
"You document all configuration options and environment variables in your code. "
|
|
103
|
+
) * 2
|
|
104
|
+
code_block = (
|
|
105
|
+
"from fastapi import FastAPI, Depends, HTTPException, status "
|
|
106
|
+
"from jose import JWTError, jwt "
|
|
107
|
+
"from passlib.context import CryptContext "
|
|
108
|
+
"from datetime import datetime, timedelta "
|
|
109
|
+
"from redis import asyncio as aioredis "
|
|
110
|
+
"from slowapi import Limiter "
|
|
111
|
+
"import structlog "
|
|
112
|
+
"logger = structlog.get_logger() "
|
|
113
|
+
"SECRET_KEY = 'your-secret-key-here' "
|
|
114
|
+
"ALGORITHM = 'HS256' "
|
|
115
|
+
"ACCESS_TOKEN_EXPIRE_MINUTES = 30 "
|
|
116
|
+
"async def get_current_user(token: str = Depends(oauth2_scheme)): "
|
|
117
|
+
" credentials_exception = HTTPException(status_code=401) "
|
|
118
|
+
" try: payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) "
|
|
119
|
+
" except JWTError: raise credentials_exception "
|
|
120
|
+
" return payload "
|
|
121
|
+
)
|
|
122
|
+
turns = [
|
|
123
|
+
("Write a JWT authentication middleware for FastAPI including token creation and validation.",
|
|
124
|
+
"Here is a comprehensive JWT middleware implementation: " + code_block),
|
|
125
|
+
("Add Redis-backed rate limiting to protect all endpoints from abuse.",
|
|
126
|
+
"Updated the middleware with SlowAPI rate limiting backed by Redis: " + code_block),
|
|
127
|
+
("Now add structured request logging with correlation IDs for distributed tracing.",
|
|
128
|
+
"Added structlog-based logging with correlation ID propagation: " + code_block),
|
|
129
|
+
("Write comprehensive pytest tests covering authentication, rate limiting, and logging.",
|
|
130
|
+
"Here are the pytest integration tests with fixtures and mocks: " + code_block),
|
|
131
|
+
("Integrate OpenTelemetry tracing with Jaeger exporter for production observability.",
|
|
132
|
+
"Integrated OpenTelemetry SDK with Jaeger exporter and span propagation: " + code_block),
|
|
133
|
+
("Refactor into separate modules for each cross-cutting concern.",
|
|
134
|
+
"Refactored into auth.py, rate_limit.py, logging.py, tracing.py modules: " + code_block),
|
|
135
|
+
("Add a comprehensive health check endpoint verifying all dependencies.",
|
|
136
|
+
"Added /health endpoint checking database, Redis, Jaeger, and auth service: " + code_block),
|
|
137
|
+
("Document all modules with docstrings and update the OpenAPI descriptions.",
|
|
138
|
+
"Added full docstring coverage and OpenAPI response models to all endpoints: " + code_block),
|
|
139
|
+
("Add Docker and docker-compose support for local development and production.",
|
|
140
|
+
"Added Dockerfile with multi-stage build and docker-compose with all services: " + code_block),
|
|
141
|
+
("Perform a final security review of the complete middleware stack.",
|
|
142
|
+
"Security review complete. All OWASP top 10 addressed. Production ready: " + code_block),
|
|
143
|
+
]
|
|
144
|
+
msgs3 = []
|
|
145
|
+
for q, a in turns:
|
|
146
|
+
msgs3.append({"role": "user", "content": q})
|
|
147
|
+
msgs3.append({"role": "assistant", "content": a})
|
|
148
|
+
msgs3.append({"role": "user", "content": "Summarize all components for the architecture doc."})
|
|
149
|
+
bench(msgs3, system=sys_prompt)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
# --------------------------------------------------------------------------
|
|
153
|
+
# TEST 4: Multi-agent pipeline — 4 agents passing accumulating context (12 turns)
|
|
154
|
+
# Realistic: analysis → fix → test → report pipeline where each agent repeats prior output
|
|
155
|
+
# --------------------------------------------------------------------------
|
|
156
|
+
print()
|
|
157
|
+
print("TEST 4: Multi-agent pipeline — 4-stage pipeline, each agent repeats prior context")
|
|
158
|
+
print("-" * 70)
|
|
159
|
+
base_report = (
|
|
160
|
+
"Analysis complete. Found 47 Python files with 1203 functions total. "
|
|
161
|
+
"Code quality score 8.2 out of 10. Coverage at 67 percent. "
|
|
162
|
+
"Security issues: numpy 1.21 has CVE-2021-41496, requests 2.25 has CVE-2023-32681. "
|
|
163
|
+
"Type hints missing in 23 files. Three circular imports detected in core module. "
|
|
164
|
+
"Recommendation: update dependencies, add mypy strict, increase coverage to 85 percent. "
|
|
165
|
+
)
|
|
166
|
+
msgs4 = []
|
|
167
|
+
for stage in range(4):
|
|
168
|
+
# Each agent echoes the accumulated report + adds its own output
|
|
169
|
+
ctx = base_report * (stage + 1)
|
|
170
|
+
msgs4.append({"role": "user",
|
|
171
|
+
"content": ctx + f"Stage {stage} agent: proceed with your task."})
|
|
172
|
+
msgs4.append({"role": "assistant",
|
|
173
|
+
"content": ctx + f"Stage {stage} completed. Updated report with new findings."})
|
|
174
|
+
# Add 4 more rounds of the same pattern
|
|
175
|
+
for i in range(4):
|
|
176
|
+
msgs4.append({"role": "user",
|
|
177
|
+
"content": base_report * 3 + f"Verification round {i}: confirm all fixes applied."})
|
|
178
|
+
msgs4.append({"role": "assistant",
|
|
179
|
+
"content": base_report * 3 + f"Round {i} verified. All {i+1} checks passed."})
|
|
180
|
+
msgs4.append({"role": "user", "content": "Generate the final executive summary report."})
|
|
181
|
+
bench(msgs4)
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
# --------------------------------------------------------------------------
|
|
185
|
+
# TEST 5: Tool-heavy agentic session — repeated XML tool outputs over many turns
|
|
186
|
+
# Realistic: Claude Code executing bash commands, same output schema each time
|
|
187
|
+
# --------------------------------------------------------------------------
|
|
188
|
+
print()
|
|
189
|
+
print("TEST 5: Agentic tool session — 10 turns of XML tool output + analysis")
|
|
190
|
+
print("-" * 70)
|
|
191
|
+
tool_schema = (
|
|
192
|
+
"<tool_result>\n"
|
|
193
|
+
" <command>run_tests</command>\n"
|
|
194
|
+
" <status>success</status>\n"
|
|
195
|
+
" <empty_field></empty_field>\n"
|
|
196
|
+
" <output>All tests passed. Coverage: 87%. Duration: 12.3s.</output>\n"
|
|
197
|
+
" <metadata></metadata>\n"
|
|
198
|
+
" <empty_section> </empty_section>\n"
|
|
199
|
+
"</tool_result>\n\n---\n---\n---\n\n"
|
|
200
|
+
)
|
|
201
|
+
msgs5 = []
|
|
202
|
+
for i in range(10):
|
|
203
|
+
msgs5.append({"role": "user",
|
|
204
|
+
"content": f"Run test suite iteration {i} and check results.\n" + tool_schema * 3})
|
|
205
|
+
msgs5.append({"role": "assistant",
|
|
206
|
+
"content": f"Iteration {i}: tests passing with 87% coverage. "
|
|
207
|
+
f"No regressions detected. Pipeline healthy."})
|
|
208
|
+
msgs5.append({"role": "user",
|
|
209
|
+
"content": tool_schema * 2 + "Write the final CI/CD status report."})
|
|
210
|
+
bench(msgs5)
|
|
211
|
+
|
|
212
|
+
print()
|