coding-agent-tools 0.1.2__tar.gz → 0.1.4__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.
- {coding_agent_tools-0.1.2 → coding_agent_tools-0.1.4}/PKG-INFO +1 -1
- {coding_agent_tools-0.1.2 → coding_agent_tools-0.1.4}/coding_agent_tools/__init__.py +1 -1
- {coding_agent_tools-0.1.2 → coding_agent_tools-0.1.4}/coding_agent_tools/agent_usage.py +61 -11
- {coding_agent_tools-0.1.2 → coding_agent_tools-0.1.4}/pyproject.toml +1 -1
- {coding_agent_tools-0.1.2 → coding_agent_tools-0.1.4}/.gitignore +0 -0
- {coding_agent_tools-0.1.2 → coding_agent_tools-0.1.4}/README.md +0 -0
- {coding_agent_tools-0.1.2 → coding_agent_tools-0.1.4}/coding_agent_tools/claude_sessions.py +0 -0
- {coding_agent_tools-0.1.2 → coding_agent_tools-0.1.4}/coding_agent_tools/codex_sessions.py +0 -0
- {coding_agent_tools-0.1.2 → coding_agent_tools-0.1.4}/coding_agent_tools/find_session.py +0 -0
- {coding_agent_tools-0.1.2 → coding_agent_tools-0.1.4}/coding_agent_tools/opencode_sessions.py +0 -0
|
@@ -53,7 +53,7 @@ class ModelBucket:
|
|
|
53
53
|
|
|
54
54
|
class PricingResolver:
|
|
55
55
|
def __init__(self) -> None:
|
|
56
|
-
self._prices = self._fetch_litellm_prices()
|
|
56
|
+
self._prices, self._fetch_error = self._fetch_litellm_prices()
|
|
57
57
|
self._lookup_cache: dict[tuple[str, str], Optional[dict]] = {}
|
|
58
58
|
self._model_aliases = {
|
|
59
59
|
# Codex aliases
|
|
@@ -65,6 +65,23 @@ class PricingResolver:
|
|
|
65
65
|
"antigravity-claude-opus-4-6-thinking": "claude-opus-4-1",
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
def pricing_banner(self) -> str:
|
|
69
|
+
if self._prices:
|
|
70
|
+
return (
|
|
71
|
+
"💡 Pricing source: LiteLLM live registry "
|
|
72
|
+
f"({len(self._prices):,} model entries). "
|
|
73
|
+
"Unknown models fall back to observed/source-reported cost."
|
|
74
|
+
)
|
|
75
|
+
if self._fetch_error:
|
|
76
|
+
return (
|
|
77
|
+
"⚠ Pricing source: LiteLLM unavailable "
|
|
78
|
+
f"({self._fetch_error}). Using observed/source-reported cost only."
|
|
79
|
+
)
|
|
80
|
+
return (
|
|
81
|
+
"⚠ Pricing source: LiteLLM unavailable. "
|
|
82
|
+
"Using observed/source-reported cost only."
|
|
83
|
+
)
|
|
84
|
+
|
|
68
85
|
def estimate_cost(
|
|
69
86
|
self,
|
|
70
87
|
model: str,
|
|
@@ -176,13 +193,15 @@ class PricingResolver:
|
|
|
176
193
|
}
|
|
177
194
|
|
|
178
195
|
@staticmethod
|
|
179
|
-
def _fetch_litellm_prices() -> dict:
|
|
196
|
+
def _fetch_litellm_prices() -> tuple[dict, Optional[str]]:
|
|
180
197
|
try:
|
|
181
198
|
with urllib.request.urlopen(LITELLM_URL, timeout=15) as response:
|
|
182
199
|
data = json.loads(response.read())
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
200
|
+
if isinstance(data, dict):
|
|
201
|
+
return data, None
|
|
202
|
+
return {}, "unexpected pricing payload"
|
|
203
|
+
except Exception as exc:
|
|
204
|
+
return {}, str(exc)
|
|
186
205
|
|
|
187
206
|
|
|
188
207
|
def to_period(ts: datetime, mode: str) -> str:
|
|
@@ -339,6 +358,7 @@ def print_table(
|
|
|
339
358
|
"cache_r": fmt_int(item.cache_read),
|
|
340
359
|
"total": fmt_int(item.total),
|
|
341
360
|
"cost": fmt_cost(item.cost),
|
|
361
|
+
"faded": True,
|
|
342
362
|
}
|
|
343
363
|
)
|
|
344
364
|
entries.append({"type": "sep"})
|
|
@@ -386,9 +406,10 @@ def print_table(
|
|
|
386
406
|
tw = max(len("Tokens"), max(len(e["total"]) for e in all_data))
|
|
387
407
|
cow = max(len("(USD)"), max(len(e["cost"]) for e in all_data))
|
|
388
408
|
|
|
389
|
-
use_color =
|
|
409
|
+
use_color = not os.getenv("NO_COLOR")
|
|
390
410
|
dim = "\033[90m" if use_color else ""
|
|
391
411
|
cyan = "\033[36m" if use_color else ""
|
|
412
|
+
faint = "\033[2m" if use_color else ""
|
|
392
413
|
reset = "\033[39m" if use_color else ""
|
|
393
414
|
|
|
394
415
|
def hl(l: str, m: str, r: str) -> str:
|
|
@@ -438,6 +459,7 @@ def print_table(
|
|
|
438
459
|
elif e["type"] == "date_cont":
|
|
439
460
|
print(rl(e["date"], "", "", "", "", "", "", ""))
|
|
440
461
|
elif e["type"] == "data":
|
|
462
|
+
row_tone = faint if e.get("faded") else ""
|
|
441
463
|
print(
|
|
442
464
|
rl(
|
|
443
465
|
e["date"],
|
|
@@ -448,6 +470,7 @@ def print_table(
|
|
|
448
470
|
e["cache_r"],
|
|
449
471
|
e["total"],
|
|
450
472
|
e["cost"],
|
|
473
|
+
row_tone,
|
|
451
474
|
)
|
|
452
475
|
)
|
|
453
476
|
|
|
@@ -1005,27 +1028,54 @@ Examples:
|
|
|
1005
1028
|
def main() -> None:
|
|
1006
1029
|
mode, breakdown, source_filter = parse_args(sys.argv[1:])
|
|
1007
1030
|
pricing = PricingResolver()
|
|
1031
|
+
mode_title = mode.capitalize()
|
|
1032
|
+
|
|
1033
|
+
print(pricing.pricing_banner())
|
|
1008
1034
|
|
|
1009
1035
|
if should_show("claude", source_filter):
|
|
1010
1036
|
usage, totals = collect_claude(mode, pricing)
|
|
1011
|
-
print_table(
|
|
1037
|
+
print_table(
|
|
1038
|
+
f"📊 Claude Code Token Usage Report - {mode_title} (From JSONL Sessions)",
|
|
1039
|
+
usage,
|
|
1040
|
+
totals,
|
|
1041
|
+
mode,
|
|
1042
|
+
breakdown,
|
|
1043
|
+
)
|
|
1012
1044
|
|
|
1013
1045
|
if should_show("codex", source_filter):
|
|
1014
1046
|
usage, totals = collect_codex(mode, pricing)
|
|
1015
|
-
print_table(
|
|
1047
|
+
print_table(
|
|
1048
|
+
f"📊 Codex Token Usage Report - {mode_title} (From JSONL Sessions)",
|
|
1049
|
+
usage,
|
|
1050
|
+
totals,
|
|
1051
|
+
mode,
|
|
1052
|
+
breakdown,
|
|
1053
|
+
)
|
|
1016
1054
|
|
|
1017
1055
|
if should_show("openclaw", source_filter):
|
|
1018
1056
|
usage, totals = collect_openclaw(mode, pricing)
|
|
1019
|
-
print_table(
|
|
1057
|
+
print_table(
|
|
1058
|
+
f"📊 OpenClaw Token Usage Report - {mode_title} (From JSONL Sessions)",
|
|
1059
|
+
usage,
|
|
1060
|
+
totals,
|
|
1061
|
+
mode,
|
|
1062
|
+
breakdown,
|
|
1063
|
+
)
|
|
1020
1064
|
|
|
1021
1065
|
if should_show("opencode", source_filter):
|
|
1022
1066
|
usage, totals = collect_opencode(mode, pricing)
|
|
1023
|
-
print_table(
|
|
1067
|
+
print_table(
|
|
1068
|
+
f"📊 OpenCode Token Usage Report - {mode_title} (From SQLite DB)",
|
|
1069
|
+
usage,
|
|
1070
|
+
totals,
|
|
1071
|
+
mode,
|
|
1072
|
+
breakdown,
|
|
1073
|
+
)
|
|
1024
1074
|
|
|
1025
1075
|
if should_show("openwhispr", source_filter):
|
|
1026
1076
|
usage, totals = collect_openwhispr(mode)
|
|
1027
1077
|
print_table(
|
|
1028
|
-
"OpenWhispr Usage",
|
|
1078
|
+
f"📊 OpenWhispr Token Usage Report - {mode_title} (From SQLite DB)",
|
|
1029
1079
|
usage,
|
|
1030
1080
|
totals,
|
|
1031
1081
|
mode,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{coding_agent_tools-0.1.2 → coding_agent_tools-0.1.4}/coding_agent_tools/opencode_sessions.py
RENAMED
|
File without changes
|