ctxoptimizer 0.4.1__py3-none-any.whl
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.
- ctxoptimizer/__init__.py +5 -0
- ctxoptimizer/__main__.py +14 -0
- ctxoptimizer/admin_security.py +130 -0
- ctxoptimizer/analysis/__init__.py +1 -0
- ctxoptimizer/analysis/baseline.py +69 -0
- ctxoptimizer/analysis/break_even.py +49 -0
- ctxoptimizer/analysis/drift.py +151 -0
- ctxoptimizer/analysis/edits.py +148 -0
- ctxoptimizer/analysis/markers.py +34 -0
- ctxoptimizer/analysis/recommend.py +114 -0
- ctxoptimizer/analysis/segments.py +57 -0
- ctxoptimizer/analysis/session.py +62 -0
- ctxoptimizer/analysis/state.py +239 -0
- ctxoptimizer/analysis/tokens.py +62 -0
- ctxoptimizer/analysis/waste.py +322 -0
- ctxoptimizer/cli.py +873 -0
- ctxoptimizer/config.py +512 -0
- ctxoptimizer/dashboard/__init__.py +1 -0
- ctxoptimizer/dashboard/api.py +537 -0
- ctxoptimizer/dashboard/service.py +157 -0
- ctxoptimizer/dashboard/static/.gitkeep +1 -0
- ctxoptimizer/dashboard/templates/.gitkeep +1 -0
- ctxoptimizer/dashboard/templates/doctor.html +46 -0
- ctxoptimizer/dashboard/templates/live.html +91 -0
- ctxoptimizer/dashboard/templates/overview.html +172 -0
- ctxoptimizer/dashboard/templates/pricing.html +115 -0
- ctxoptimizer/dashboard/templates/request.html +111 -0
- ctxoptimizer/dashboard/templates/session.html +67 -0
- ctxoptimizer/dashboard/templates/settings.html +79 -0
- ctxoptimizer/dashboard/templates/table.html +56 -0
- ctxoptimizer/dashboard/templates/transforms.html +118 -0
- ctxoptimizer/dashboard/templates/waste.html +120 -0
- ctxoptimizer/dashboard/views.py +429 -0
- ctxoptimizer/data/cache_limits.json +23 -0
- ctxoptimizer/data/default_config.toml +185 -0
- ctxoptimizer/data/pricing.json +421 -0
- ctxoptimizer/doctor.py +129 -0
- ctxoptimizer/guard.py +139 -0
- ctxoptimizer/ids.py +73 -0
- ctxoptimizer/log.py +73 -0
- ctxoptimizer/mcp.py +124 -0
- ctxoptimizer/models.py +145 -0
- ctxoptimizer/pipeline.py +126 -0
- ctxoptimizer/profiles.py +152 -0
- ctxoptimizer/providers/__init__.py +37 -0
- ctxoptimizer/providers/anthropic.py +105 -0
- ctxoptimizer/providers/base.py +191 -0
- ctxoptimizer/providers/gemini.py +143 -0
- ctxoptimizer/providers/ollama.py +133 -0
- ctxoptimizer/providers/openai_chat.py +135 -0
- ctxoptimizer/providers/openai_responses.py +121 -0
- ctxoptimizer/proxy.py +665 -0
- ctxoptimizer/routing.py +259 -0
- ctxoptimizer/server.py +319 -0
- ctxoptimizer/service.py +150 -0
- ctxoptimizer/telemetry/__init__.py +1 -0
- ctxoptimizer/telemetry/blobs.py +57 -0
- ctxoptimizer/telemetry/expand.py +62 -0
- ctxoptimizer/telemetry/pricing.py +168 -0
- ctxoptimizer/telemetry/redact.py +53 -0
- ctxoptimizer/telemetry/sse.py +145 -0
- ctxoptimizer/telemetry/store.py +829 -0
- ctxoptimizer/telemetry/usage.py +435 -0
- ctxoptimizer/transforms/__init__.py +87 -0
- ctxoptimizer/transforms/ansi.py +21 -0
- ctxoptimizer/transforms/anthropic_cache.py +100 -0
- ctxoptimizer/transforms/backref.py +74 -0
- ctxoptimizer/transforms/base.py +93 -0
- ctxoptimizer/transforms/cache_serve.py +146 -0
- ctxoptimizer/transforms/dedupe_lines.py +69 -0
- ctxoptimizer/transforms/eligibility.py +24 -0
- ctxoptimizer/transforms/openai_hints.py +84 -0
- ctxoptimizer/transforms/progress.py +52 -0
- ctxoptimizer/transforms/stale_result_elision.py +109 -0
- ctxoptimizer/transforms/truncate.py +100 -0
- ctxoptimizer/transforms/volatile.py +177 -0
- ctxoptimizer/transforms/whitespace.py +25 -0
- ctxoptimizer-0.4.1.dist-info/METADATA +196 -0
- ctxoptimizer-0.4.1.dist-info/RECORD +83 -0
- ctxoptimizer-0.4.1.dist-info/WHEEL +4 -0
- ctxoptimizer-0.4.1.dist-info/entry_points.txt +3 -0
- ctxoptimizer-0.4.1.dist-info/licenses/LICENSE +21 -0
- ctxoptimizer-0.4.1.dist-info/licenses/NOTICE +13 -0
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
"""Server-rendered dashboard views (SPEC section 16.2)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from dataclasses import asdict
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
from starlette.requests import Request
|
|
11
|
+
from starlette.responses import Response
|
|
12
|
+
from starlette.templating import Jinja2Templates
|
|
13
|
+
|
|
14
|
+
from ctxoptimizer import __version__
|
|
15
|
+
from ctxoptimizer.analysis.recommend import recommendations
|
|
16
|
+
from ctxoptimizer.config import data_dir
|
|
17
|
+
from ctxoptimizer.dashboard.service import (
|
|
18
|
+
findings_from_rows,
|
|
19
|
+
parse_since,
|
|
20
|
+
pricing_payload,
|
|
21
|
+
)
|
|
22
|
+
from ctxoptimizer.doctor import run_checks
|
|
23
|
+
from ctxoptimizer.telemetry.expand import expand_stats
|
|
24
|
+
|
|
25
|
+
templates = Jinja2Templates(directory=str(Path(__file__).parent / "templates"))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
async def overview(request: Request) -> Response:
|
|
29
|
+
state = request.app.state
|
|
30
|
+
store = getattr(state, "store", None)
|
|
31
|
+
period = request.query_params.get("period", "7d")
|
|
32
|
+
since = parse_since(period) if period != "all" else None
|
|
33
|
+
summary = (
|
|
34
|
+
store.summary(since)
|
|
35
|
+
if store is not None
|
|
36
|
+
else {
|
|
37
|
+
"requests": 0,
|
|
38
|
+
"cost_usd": 0.0,
|
|
39
|
+
"baseline_usd": 0.0,
|
|
40
|
+
"fresh_input": 0,
|
|
41
|
+
"cache_read": 0,
|
|
42
|
+
"output_tokens": 0,
|
|
43
|
+
"tokens_removed": 0,
|
|
44
|
+
}
|
|
45
|
+
)
|
|
46
|
+
rows = store.export_rows(since, 20) if store is not None else []
|
|
47
|
+
projects = store.group_stats("project", 10, since) if store is not None else []
|
|
48
|
+
models = store.group_stats("model", 10, since) if store is not None else []
|
|
49
|
+
points = store.timeseries("cost", "day", since) if store is not None else []
|
|
50
|
+
waste = (
|
|
51
|
+
store.waste_summary(since)
|
|
52
|
+
if store is not None
|
|
53
|
+
else {
|
|
54
|
+
"findings": 0,
|
|
55
|
+
"tokens": 0,
|
|
56
|
+
"cost_usd": 0.0,
|
|
57
|
+
}
|
|
58
|
+
)
|
|
59
|
+
waste_points = store.waste_timeseries("day", since) if store is not None else []
|
|
60
|
+
spend_line = _polyline([float(point.get("value") or 0) for point in points])
|
|
61
|
+
waste_line = _polyline([float(point.get("cost_usd") or 0) for point in waste_points])
|
|
62
|
+
return templates.TemplateResponse(
|
|
63
|
+
request,
|
|
64
|
+
"overview.html",
|
|
65
|
+
{
|
|
66
|
+
"version": __version__,
|
|
67
|
+
"mode": state.config.mode.default,
|
|
68
|
+
"summary": summary,
|
|
69
|
+
"rows": rows,
|
|
70
|
+
"projects": projects,
|
|
71
|
+
"models": models,
|
|
72
|
+
"points": points,
|
|
73
|
+
"period": period,
|
|
74
|
+
"privacy": state.config.telemetry.capture_payloads != "off",
|
|
75
|
+
"capture": state.config.telemetry.capture_payloads,
|
|
76
|
+
"waste": waste,
|
|
77
|
+
"waste_points": waste_points,
|
|
78
|
+
"spend_line": spend_line,
|
|
79
|
+
"waste_line": waste_line,
|
|
80
|
+
},
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
async def waste_view(request: Request) -> Response:
|
|
85
|
+
state = request.app.state
|
|
86
|
+
store = getattr(state, "store", None)
|
|
87
|
+
analysis = getattr(state, "analysis", None)
|
|
88
|
+
findings = analysis.findings() if analysis is not None else []
|
|
89
|
+
rows = store.fetch_waste() if store is not None else []
|
|
90
|
+
if not rows:
|
|
91
|
+
rows = [_finding_dict(finding) for finding in findings]
|
|
92
|
+
if not findings and rows:
|
|
93
|
+
findings = findings_from_rows(rows)
|
|
94
|
+
items = recommendations(
|
|
95
|
+
findings,
|
|
96
|
+
cache_serve_enabled=state.config.transforms.cache_serve.enabled,
|
|
97
|
+
volatile_normalizer_enabled=state.config.transforms.volatile_normalizer.enabled,
|
|
98
|
+
transforms_enabled=True,
|
|
99
|
+
)
|
|
100
|
+
suppressed = store.suppressed_recommendations() if store is not None else set()
|
|
101
|
+
items = [item for item in items if item["id"] not in suppressed]
|
|
102
|
+
return templates.TemplateResponse(
|
|
103
|
+
request,
|
|
104
|
+
"waste.html",
|
|
105
|
+
{
|
|
106
|
+
"version": __version__,
|
|
107
|
+
"mode": state.config.mode.default,
|
|
108
|
+
"findings": rows,
|
|
109
|
+
"recommendations": items,
|
|
110
|
+
"csrf": state.csrf_token,
|
|
111
|
+
},
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
async def sessions_view(request: Request) -> Response:
|
|
116
|
+
store = getattr(request.app.state, "store", None)
|
|
117
|
+
rows = store.fetch_sessions() if store is not None else []
|
|
118
|
+
return _table(
|
|
119
|
+
request,
|
|
120
|
+
"Sessions",
|
|
121
|
+
"Grouped by derived session id.",
|
|
122
|
+
[
|
|
123
|
+
("session_id", "Session"),
|
|
124
|
+
("project", "Project"),
|
|
125
|
+
("client", "Client"),
|
|
126
|
+
("provider", "Provider"),
|
|
127
|
+
("request_count", "Requests"),
|
|
128
|
+
("last_ts", "Last seen"),
|
|
129
|
+
],
|
|
130
|
+
rows,
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
async def session_view(request: Request) -> Response:
|
|
135
|
+
store = getattr(request.app.state, "store", None)
|
|
136
|
+
session_id = request.path_params["session_id"]
|
|
137
|
+
rows = (
|
|
138
|
+
list(reversed(store.fetch_session_requests(session_id, 500))) if store is not None else []
|
|
139
|
+
)
|
|
140
|
+
drift = store.fetch_drift(500) if store is not None else []
|
|
141
|
+
by_request = {item["request_id"]: item for item in drift}
|
|
142
|
+
for row in rows:
|
|
143
|
+
row["drift"] = (by_request.get(row["request_id"]) or {}).get("cause")
|
|
144
|
+
ratios = [
|
|
145
|
+
100
|
|
146
|
+
* (row.get("cache_read") or 0)
|
|
147
|
+
/ max((row.get("cache_read") or 0) + (row.get("fresh_input") or 0), 1)
|
|
148
|
+
for row in rows
|
|
149
|
+
]
|
|
150
|
+
return templates.TemplateResponse(
|
|
151
|
+
request,
|
|
152
|
+
"session.html",
|
|
153
|
+
{
|
|
154
|
+
"version": __version__,
|
|
155
|
+
"mode": request.app.state.config.mode.default,
|
|
156
|
+
"title": f"Session {session_id}",
|
|
157
|
+
"session_id": session_id,
|
|
158
|
+
"rows": rows,
|
|
159
|
+
"ratio_line": _polyline(ratios),
|
|
160
|
+
},
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
async def requests_view(request: Request) -> Response:
|
|
165
|
+
store = getattr(request.app.state, "store", None)
|
|
166
|
+
rows = store.fetch_recent(100) if store is not None else []
|
|
167
|
+
return _table(
|
|
168
|
+
request,
|
|
169
|
+
"Requests",
|
|
170
|
+
"Most recent 100 requests.",
|
|
171
|
+
[
|
|
172
|
+
("request_id", "Request"),
|
|
173
|
+
("ts", "Time"),
|
|
174
|
+
("client", "Client"),
|
|
175
|
+
("provider", "Provider"),
|
|
176
|
+
("model", "Model"),
|
|
177
|
+
("fresh_input", "Fresh"),
|
|
178
|
+
("cache_read", "Cache read"),
|
|
179
|
+
("output_tokens", "Output"),
|
|
180
|
+
("cost_actual_usd", "Cost"),
|
|
181
|
+
("outcome", "Outcome"),
|
|
182
|
+
],
|
|
183
|
+
rows,
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
async def request_view(request: Request) -> Response:
|
|
188
|
+
store = getattr(request.app.state, "store", None)
|
|
189
|
+
request_id = request.path_params["request_id"]
|
|
190
|
+
row = store.fetch_request(request_id) if store is not None else None
|
|
191
|
+
reports = store.fetch_transform_reports(request_id) if store is not None else []
|
|
192
|
+
diff = _diff_blocks(request, request_id)
|
|
193
|
+
status_code = 200 if row is not None else 404
|
|
194
|
+
usage = {}
|
|
195
|
+
timing = {}
|
|
196
|
+
headers: dict[str, Any] = {}
|
|
197
|
+
if row is not None:
|
|
198
|
+
try:
|
|
199
|
+
headers = json.loads(row.get("request_headers_json") or "{}")
|
|
200
|
+
except (TypeError, json.JSONDecodeError):
|
|
201
|
+
headers = {}
|
|
202
|
+
usage = {
|
|
203
|
+
key.removeprefix("cache_write_"): row[key]
|
|
204
|
+
for key in row
|
|
205
|
+
if key.startswith("cache_write_")
|
|
206
|
+
}
|
|
207
|
+
usage.update(
|
|
208
|
+
{
|
|
209
|
+
"source": row.get("usage_source"),
|
|
210
|
+
"fresh_input": row.get("fresh_input"),
|
|
211
|
+
"cache_read": row.get("cache_read"),
|
|
212
|
+
"output": row.get("output_tokens"),
|
|
213
|
+
"reasoning": row.get("reasoning_tokens"),
|
|
214
|
+
"provider_cost_usd": row.get("provider_cost_usd"),
|
|
215
|
+
}
|
|
216
|
+
)
|
|
217
|
+
timing = {
|
|
218
|
+
"ttfb_ms": row.get("ttfb_ms"),
|
|
219
|
+
"total_ms": row.get("total_ms"),
|
|
220
|
+
"proxy_overhead_ms": row.get("proxy_overhead_ms"),
|
|
221
|
+
}
|
|
222
|
+
return templates.TemplateResponse(
|
|
223
|
+
request,
|
|
224
|
+
"request.html",
|
|
225
|
+
{
|
|
226
|
+
"version": __version__,
|
|
227
|
+
"mode": request.app.state.config.mode.default,
|
|
228
|
+
"title": f"Request {request_id}",
|
|
229
|
+
"row": row or {},
|
|
230
|
+
"found": row is not None,
|
|
231
|
+
"reports": reports,
|
|
232
|
+
"diff": diff,
|
|
233
|
+
"usage": usage,
|
|
234
|
+
"timing": timing,
|
|
235
|
+
"headers": headers,
|
|
236
|
+
},
|
|
237
|
+
status_code=status_code,
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def _diff_blocks(request: Request, request_id: str) -> list[dict[str, Any]]:
|
|
242
|
+
store = getattr(request.app.state, "store", None)
|
|
243
|
+
blobs = getattr(request.app.state, "blobs", None)
|
|
244
|
+
if store is None or blobs is None:
|
|
245
|
+
return []
|
|
246
|
+
blocks: list[dict[str, Any]] = []
|
|
247
|
+
for capture in store.fetch_captures(request_id):
|
|
248
|
+
before = blobs.get(capture.get("before_hash") or "")
|
|
249
|
+
after = blobs.get(capture.get("after_hash") or "")
|
|
250
|
+
blocks.append(
|
|
251
|
+
{
|
|
252
|
+
"location": capture.get("location"),
|
|
253
|
+
"before": before.decode("utf-8", "replace") if before else "",
|
|
254
|
+
"after": after.decode("utf-8", "replace") if after else "",
|
|
255
|
+
}
|
|
256
|
+
)
|
|
257
|
+
return blocks
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
async def transforms_view(request: Request) -> Response:
|
|
261
|
+
state = request.app.state
|
|
262
|
+
store = getattr(state, "store", None)
|
|
263
|
+
guard = getattr(state, "guard", None)
|
|
264
|
+
stats = {item["transform_id"]: item for item in (store.transform_stats() if store else [])}
|
|
265
|
+
quarantined = {item["transform_id"] for item in (guard.status() if guard else [])}
|
|
266
|
+
rows = [
|
|
267
|
+
{
|
|
268
|
+
"transform": name,
|
|
269
|
+
"enabled": value.get("enabled", False),
|
|
270
|
+
"quarantined": name in quarantined,
|
|
271
|
+
"runs": stats.get(name, {}).get("runs", 0),
|
|
272
|
+
"tokens_saved": stats.get(name, {}).get("tokens_saved", 0),
|
|
273
|
+
"avg_ms": round(float(stats.get(name, {}).get("avg_ms") or 0.0), 3),
|
|
274
|
+
"errors": stats.get(name, {}).get("errors", 0),
|
|
275
|
+
"no_regress": stats.get(name, {}).get("no_regress", 0),
|
|
276
|
+
"fallbacks": stats.get(name, {}).get("fallbacks", 0),
|
|
277
|
+
}
|
|
278
|
+
for name, value in state.config.transforms.model_dump().items()
|
|
279
|
+
if isinstance(value, dict)
|
|
280
|
+
]
|
|
281
|
+
return templates.TemplateResponse(
|
|
282
|
+
request,
|
|
283
|
+
"transforms.html",
|
|
284
|
+
{
|
|
285
|
+
"version": __version__,
|
|
286
|
+
"mode": state.config.mode.default,
|
|
287
|
+
"rows": rows,
|
|
288
|
+
"guard_events": store.fetch_guard_events() if store else [],
|
|
289
|
+
"expand": expand_stats(),
|
|
290
|
+
"csrf": state.csrf_token,
|
|
291
|
+
},
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
async def pricing_view(request: Request) -> Response:
|
|
296
|
+
config = request.app.state.config
|
|
297
|
+
payload = pricing_payload(config)
|
|
298
|
+
store = getattr(request.app.state, "store", None)
|
|
299
|
+
unpriced = store.unpriced() if store is not None else []
|
|
300
|
+
return templates.TemplateResponse(
|
|
301
|
+
request,
|
|
302
|
+
"pricing.html",
|
|
303
|
+
{
|
|
304
|
+
"version": __version__,
|
|
305
|
+
"mode": config.mode.default,
|
|
306
|
+
"title": f"Pricing ({payload['version']})",
|
|
307
|
+
"models": payload["models"],
|
|
308
|
+
"payload_json": json.dumps({"models": payload["models"]}, indent=2),
|
|
309
|
+
"unpriced": unpriced,
|
|
310
|
+
"csrf": request.app.state.csrf_token,
|
|
311
|
+
},
|
|
312
|
+
)
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
async def settings_view(request: Request) -> Response:
|
|
316
|
+
config = request.app.state.config
|
|
317
|
+
data: dict[str, Any] = {
|
|
318
|
+
"host": config.server.host,
|
|
319
|
+
"port": config.server.port,
|
|
320
|
+
"allow_remote": config.server.allow_remote,
|
|
321
|
+
"mode": config.mode.default,
|
|
322
|
+
"capture_payloads": config.telemetry.capture_payloads,
|
|
323
|
+
"retention_days": config.telemetry.retention_days,
|
|
324
|
+
"db_path": config.telemetry.db_path or str(data_dir() / "ctxoptimizer.db"),
|
|
325
|
+
"pricing_file": config.pricing.file or "(bundled)",
|
|
326
|
+
"upstreams": {
|
|
327
|
+
name: (entry if isinstance(entry, str) else entry.url)
|
|
328
|
+
for name, entry in config.upstreams.items()
|
|
329
|
+
},
|
|
330
|
+
"config_hash": config.config_hash,
|
|
331
|
+
}
|
|
332
|
+
return templates.TemplateResponse(
|
|
333
|
+
request,
|
|
334
|
+
"settings.html",
|
|
335
|
+
{
|
|
336
|
+
"version": __version__,
|
|
337
|
+
"mode": config.mode.default,
|
|
338
|
+
"title": "Settings",
|
|
339
|
+
"data": data,
|
|
340
|
+
"privacy": config.telemetry.capture_payloads != "off",
|
|
341
|
+
"csrf": request.app.state.csrf_token,
|
|
342
|
+
},
|
|
343
|
+
)
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
async def live_view(request: Request) -> Response:
|
|
347
|
+
state = request.app.state
|
|
348
|
+
return templates.TemplateResponse(
|
|
349
|
+
request,
|
|
350
|
+
"live.html",
|
|
351
|
+
{
|
|
352
|
+
"version": __version__,
|
|
353
|
+
"mode": state.config.mode.default,
|
|
354
|
+
"counters": state.counters,
|
|
355
|
+
"last": state.last_request or {},
|
|
356
|
+
"quarantined": (
|
|
357
|
+
state.guard.status() if getattr(state, "guard", None) is not None else []
|
|
358
|
+
),
|
|
359
|
+
},
|
|
360
|
+
)
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
async def doctor_view(request: Request) -> Response:
|
|
364
|
+
state = request.app.state
|
|
365
|
+
checks = run_checks(state.config, offline=True)
|
|
366
|
+
return templates.TemplateResponse(
|
|
367
|
+
request,
|
|
368
|
+
"doctor.html",
|
|
369
|
+
{
|
|
370
|
+
"version": __version__,
|
|
371
|
+
"mode": state.config.mode.default,
|
|
372
|
+
"title": "Doctor",
|
|
373
|
+
"checks": checks,
|
|
374
|
+
},
|
|
375
|
+
)
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
def _polyline(values: list[float], width: int = 600, height: int = 80) -> str:
|
|
379
|
+
if len(values) < 2:
|
|
380
|
+
return ""
|
|
381
|
+
maximum = max(max(values), 1e-9)
|
|
382
|
+
step = width / (len(values) - 1)
|
|
383
|
+
return " ".join(
|
|
384
|
+
f"{index * step:.1f},{height - (value / maximum) * height:.1f}"
|
|
385
|
+
for index, value in enumerate(values)
|
|
386
|
+
)
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
def _finding_dict(finding: Any) -> dict[str, Any]:
|
|
390
|
+
data = asdict(finding)
|
|
391
|
+
data["key_hash"] = finding.key_hash.hex()
|
|
392
|
+
return data
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
def _table(
|
|
396
|
+
request: Request,
|
|
397
|
+
title: str,
|
|
398
|
+
subtitle: str,
|
|
399
|
+
columns: list[tuple[str, str]],
|
|
400
|
+
rows: list[dict[str, Any]],
|
|
401
|
+
) -> Response:
|
|
402
|
+
return templates.TemplateResponse(
|
|
403
|
+
request,
|
|
404
|
+
"table.html",
|
|
405
|
+
{
|
|
406
|
+
"version": __version__,
|
|
407
|
+
"mode": request.app.state.config.mode.default,
|
|
408
|
+
"title": title,
|
|
409
|
+
"subtitle": subtitle,
|
|
410
|
+
"columns": columns,
|
|
411
|
+
"rows": rows,
|
|
412
|
+
"csrf": request.app.state.csrf_token,
|
|
413
|
+
},
|
|
414
|
+
)
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
__all__ = [
|
|
418
|
+
"doctor_view",
|
|
419
|
+
"live_view",
|
|
420
|
+
"overview",
|
|
421
|
+
"pricing_view",
|
|
422
|
+
"request_view",
|
|
423
|
+
"requests_view",
|
|
424
|
+
"session_view",
|
|
425
|
+
"sessions_view",
|
|
426
|
+
"settings_view",
|
|
427
|
+
"transforms_view",
|
|
428
|
+
"waste_view",
|
|
429
|
+
]
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "2026-10-24",
|
|
3
|
+
"source": "https://platform.claude.com/docs/en/build-with-claude/prompt-caching",
|
|
4
|
+
"models": [
|
|
5
|
+
{"match": "claude-fable-5-1*", "min_tokens": 512},
|
|
6
|
+
{"match": "claude-mythos-5-1*", "min_tokens": 512},
|
|
7
|
+
{"match": "claude-opus-5-5*", "min_tokens": 512},
|
|
8
|
+
{"match": "claude-opus-5*", "min_tokens": 512},
|
|
9
|
+
{"match": "claude-sonnet-5-5*", "min_tokens": 512},
|
|
10
|
+
{"match": "claude-sonnet-5*", "min_tokens": 1024},
|
|
11
|
+
{"match": "claude-haiku-5-5*", "min_tokens": 512},
|
|
12
|
+
{"match": "claude-fable-5*", "min_tokens": 512},
|
|
13
|
+
{"match": "claude-mythos-5*", "min_tokens": 512},
|
|
14
|
+
{"match": "claude-opus-4-8*", "min_tokens": 1024},
|
|
15
|
+
{"match": "claude-opus-4-7*", "min_tokens": 2048},
|
|
16
|
+
{"match": "claude-opus-4-6*", "min_tokens": 4096},
|
|
17
|
+
{"match": "claude-opus-4-5*", "min_tokens": 4096},
|
|
18
|
+
{"match": "claude-sonnet-4-6*", "min_tokens": 1024},
|
|
19
|
+
{"match": "claude-sonnet-4-5*", "min_tokens": 1024},
|
|
20
|
+
{"match": "claude-haiku-4-5*", "min_tokens": 4096},
|
|
21
|
+
{"match": "claude-haiku-3-5*", "min_tokens": 2048}
|
|
22
|
+
]
|
|
23
|
+
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# ctxoptimizer configuration (SPEC section 7).
|
|
2
|
+
# Created on first run. Edit and reload with `ctxoptimizer reload` (P5).
|
|
3
|
+
|
|
4
|
+
schema_version = 1
|
|
5
|
+
|
|
6
|
+
[server]
|
|
7
|
+
host = "127.0.0.1"
|
|
8
|
+
port = 8787
|
|
9
|
+
allow_remote = false
|
|
10
|
+
admin_token = ""
|
|
11
|
+
max_body_bytes = 33554432
|
|
12
|
+
log_level = "info"
|
|
13
|
+
|
|
14
|
+
[mode]
|
|
15
|
+
default = "shadow"
|
|
16
|
+
|
|
17
|
+
[upstreams]
|
|
18
|
+
anthropic = "https://api.anthropic.com"
|
|
19
|
+
openai = "https://api.openai.com"
|
|
20
|
+
gemini = "https://generativelanguage.googleapis.com"
|
|
21
|
+
ollama = "http://127.0.0.1:11434"
|
|
22
|
+
# openrouter = { url = "https://openrouter.ai/api", kind = "openai" }
|
|
23
|
+
# deepseek = { url = "https://api.deepseek.com", kind = "openai",
|
|
24
|
+
# usage = "deepseek", cache_policy = "automatic-deepseek" }
|
|
25
|
+
# deepseek-anthropic = { url = "https://api.deepseek.com/anthropic",
|
|
26
|
+
# kind = "anthropic", cache_hints = false }
|
|
27
|
+
# gemini-openai = { url = "https://generativelanguage.googleapis.com/v1beta/openai",
|
|
28
|
+
# kind = "openai", usage = "gemini-openai" }
|
|
29
|
+
# ollama-openai = { url = "http://127.0.0.1:11434/v1", kind = "openai" }
|
|
30
|
+
|
|
31
|
+
[http]
|
|
32
|
+
connect_timeout_s = 10
|
|
33
|
+
write_timeout_s = 60
|
|
34
|
+
pool_timeout_s = 30
|
|
35
|
+
read_timeout_s = 0
|
|
36
|
+
http2 = true
|
|
37
|
+
max_connections = 100
|
|
38
|
+
force_identity_encoding = true
|
|
39
|
+
|
|
40
|
+
[pipeline]
|
|
41
|
+
time_budget_ms = 250
|
|
42
|
+
offload_threshold_bytes = 262144
|
|
43
|
+
min_saving_tokens = 20
|
|
44
|
+
retry_original_on_status = [400, 422]
|
|
45
|
+
|
|
46
|
+
[transforms.ansi_strip]
|
|
47
|
+
enabled = true
|
|
48
|
+
|
|
49
|
+
[transforms.progress_collapse]
|
|
50
|
+
enabled = true
|
|
51
|
+
|
|
52
|
+
[transforms.line_dedupe]
|
|
53
|
+
enabled = true
|
|
54
|
+
min_repeat = 3
|
|
55
|
+
|
|
56
|
+
[transforms.whitespace_trim]
|
|
57
|
+
enabled = true
|
|
58
|
+
max_blank_run = 2
|
|
59
|
+
|
|
60
|
+
[transforms.smart_truncate]
|
|
61
|
+
enabled = true
|
|
62
|
+
trigger_bytes = 16384
|
|
63
|
+
target_bytes = 10240
|
|
64
|
+
head_lines = 40
|
|
65
|
+
tail_lines = 60
|
|
66
|
+
context_lines = 3
|
|
67
|
+
max_line_chars = 2000
|
|
68
|
+
max_signal_lines = 150
|
|
69
|
+
|
|
70
|
+
[transforms.duplicate_backref]
|
|
71
|
+
enabled = true
|
|
72
|
+
min_bytes = 2048
|
|
73
|
+
include_never_touch = true
|
|
74
|
+
|
|
75
|
+
[transforms.stale_result_elision]
|
|
76
|
+
enabled = false
|
|
77
|
+
keep_recent_turns = 12
|
|
78
|
+
batch_turns = 8
|
|
79
|
+
min_bytes = 4096
|
|
80
|
+
|
|
81
|
+
[transforms.anthropic_cache]
|
|
82
|
+
enabled = true
|
|
83
|
+
ttl = "5m"
|
|
84
|
+
respect_existing = true
|
|
85
|
+
max_breakpoints = 4
|
|
86
|
+
|
|
87
|
+
[transforms.openai_hints]
|
|
88
|
+
enabled = false
|
|
89
|
+
send_prompt_cache_key = true
|
|
90
|
+
inject_stream_usage = false
|
|
91
|
+
|
|
92
|
+
[transforms.cache_serve]
|
|
93
|
+
enabled = false
|
|
94
|
+
include_never_touch = true
|
|
95
|
+
min_bytes = 2048
|
|
96
|
+
max_stubs_per_request = 6
|
|
97
|
+
batch_turns = 8
|
|
98
|
+
keep_recent_turns = 12
|
|
99
|
+
max_state_sessions = 256
|
|
100
|
+
max_entries_per_session = 512
|
|
101
|
+
|
|
102
|
+
[transforms.volatile_normalizer]
|
|
103
|
+
enabled = false
|
|
104
|
+
|
|
105
|
+
[tools]
|
|
106
|
+
compactable = [
|
|
107
|
+
"*bash*",
|
|
108
|
+
"*shell*",
|
|
109
|
+
"*terminal*",
|
|
110
|
+
"*exec*",
|
|
111
|
+
"*run*",
|
|
112
|
+
"*command*",
|
|
113
|
+
"*test*",
|
|
114
|
+
"*build*",
|
|
115
|
+
"*npm*",
|
|
116
|
+
"*pytest*",
|
|
117
|
+
"*cargo*",
|
|
118
|
+
]
|
|
119
|
+
never_touch = [
|
|
120
|
+
"*read*",
|
|
121
|
+
"*view*",
|
|
122
|
+
"*cat*",
|
|
123
|
+
"*edit*",
|
|
124
|
+
"*write*",
|
|
125
|
+
"*patch*",
|
|
126
|
+
"*apply*",
|
|
127
|
+
"*notebook*",
|
|
128
|
+
]
|
|
129
|
+
|
|
130
|
+
[telemetry]
|
|
131
|
+
db_path = ""
|
|
132
|
+
capture_payloads = "changed_blocks"
|
|
133
|
+
retention_days = 14
|
|
134
|
+
redact_secrets = true
|
|
135
|
+
writer_queue_max = 10000
|
|
136
|
+
max_blob_bytes = 524288000
|
|
137
|
+
|
|
138
|
+
[waste]
|
|
139
|
+
enabled = true
|
|
140
|
+
dedupe_window_min = 30
|
|
141
|
+
capture_assistant_hashes = true
|
|
142
|
+
|
|
143
|
+
[waste.redundant_reread]
|
|
144
|
+
enabled = true
|
|
145
|
+
min_bytes = 512
|
|
146
|
+
|
|
147
|
+
[waste.identical_output]
|
|
148
|
+
enabled = true
|
|
149
|
+
min_bytes = 1024
|
|
150
|
+
|
|
151
|
+
[waste.unbatched_fanout]
|
|
152
|
+
enabled = true
|
|
153
|
+
min_calls = 4
|
|
154
|
+
|
|
155
|
+
[waste.runaway_session]
|
|
156
|
+
enabled = true
|
|
157
|
+
idle_gap_s = 900
|
|
158
|
+
min_turns = 6
|
|
159
|
+
|
|
160
|
+
[waste.recurring_drift]
|
|
161
|
+
enabled = true
|
|
162
|
+
min_occurrences = 2
|
|
163
|
+
|
|
164
|
+
[waste.churn_detector]
|
|
165
|
+
enabled = false
|
|
166
|
+
|
|
167
|
+
[waste.schema_bloat]
|
|
168
|
+
enabled = true
|
|
169
|
+
min_session_requests = 10
|
|
170
|
+
|
|
171
|
+
[guard]
|
|
172
|
+
enabled = true
|
|
173
|
+
fallback_window = 50
|
|
174
|
+
fallback_limit = 3
|
|
175
|
+
our_fault_drift_limit = 1
|
|
176
|
+
min_savings_to_stay = 0.01
|
|
177
|
+
notify = "dashboard"
|
|
178
|
+
auto_reenable = 0
|
|
179
|
+
expand_error_rate = 0.20
|
|
180
|
+
|
|
181
|
+
[pricing]
|
|
182
|
+
file = ""
|
|
183
|
+
|
|
184
|
+
[dashboard]
|
|
185
|
+
enabled = true
|