eurysx 0.1.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.
- eurysx-0.1.0/CHANGELOG.md +140 -0
- eurysx-0.1.0/LICENSE +21 -0
- eurysx-0.1.0/MANIFEST.in +3 -0
- eurysx-0.1.0/PKG-INFO +263 -0
- eurysx-0.1.0/README.md +252 -0
- eurysx-0.1.0/config/preferences.jsonc.sample +26 -0
- eurysx-0.1.0/config/pricing.jsonc.sample +25 -0
- eurysx-0.1.0/pyproject.toml +23 -0
- eurysx-0.1.0/setup.cfg +4 -0
- eurysx-0.1.0/src/eurysx/__init__.py +3 -0
- eurysx-0.1.0/src/eurysx/analysis.py +302 -0
- eurysx-0.1.0/src/eurysx/cli.py +470 -0
- eurysx-0.1.0/src/eurysx/collectors/__init__.py +45 -0
- eurysx-0.1.0/src/eurysx/collectors/claude_code.py +115 -0
- eurysx-0.1.0/src/eurysx/collectors/codex.py +152 -0
- eurysx-0.1.0/src/eurysx/collectors/opencode.py +135 -0
- eurysx-0.1.0/src/eurysx/collectors/paths.py +34 -0
- eurysx-0.1.0/src/eurysx/collectors/pi.py +113 -0
- eurysx-0.1.0/src/eurysx/collectors/sources.py +33 -0
- eurysx-0.1.0/src/eurysx/models.py +141 -0
- eurysx-0.1.0/src/eurysx/paths.py +26 -0
- eurysx-0.1.0/src/eurysx/pricing.py +517 -0
- eurysx-0.1.0/src/eurysx/render.py +466 -0
- eurysx-0.1.0/src/eurysx/store.py +247 -0
- eurysx-0.1.0/src/eurysx.egg-info/PKG-INFO +263 -0
- eurysx-0.1.0/src/eurysx.egg-info/SOURCES.txt +28 -0
- eurysx-0.1.0/src/eurysx.egg-info/dependency_links.txt +1 -0
- eurysx-0.1.0/src/eurysx.egg-info/entry_points.txt +2 -0
- eurysx-0.1.0/src/eurysx.egg-info/top_level.txt +1 -0
- eurysx-0.1.0/tests/test_eurysx.py +1919 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.1.0] - Local observability, diagnostics, pacing, and stable exports
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- Parse Claude Code date-only timestamps correctly; aggregate rates use observed dates and omit false daily spikes.
|
|
8
|
+
- Attribute Pi sessions from session headers, retaining the legacy per-event fallback.
|
|
9
|
+
- Calculate pacing from the full calendar budget window; provider budgets override agent budgets for their routes.
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Activity ratios for requests/turns/tool calls, reported as `N/A` when their inputs are absent.
|
|
14
|
+
- Read-only parser-drift and unreachable-source warnings; retained history is never deleted.
|
|
15
|
+
- `eurysx doctor` for terminal-only harness, source, pricing-cache, and configuration diagnostics. Failed-refresh report warnings are agent-scoped.
|
|
16
|
+
- Preference budgets, deterministic pacing, and exact unresolved-route diagnostics; subscription billing remains `N/A`.
|
|
17
|
+
- Stable JSON schema v1 plus CSV and Markdown exports from the shared analysis result.
|
|
18
|
+
- Operational manual with CLI/output redirects and a source-drift regression check.
|
|
19
|
+
- Trusted-Publishing GitHub workflow: validation, PyPI upload, and changelog-based GitHub Release.
|
|
20
|
+
|
|
21
|
+
### Tests
|
|
22
|
+
|
|
23
|
+
- Coverage for timestamp scope, Pi attribution, ratios, diagnostics, stored-source failures, and the doctor command.
|
|
24
|
+
|
|
25
|
+
## [0.0.5] - More hardening: pushdown, selectors, grouping, comparisons
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
|
|
29
|
+
- `--model` and `--provider` selectors, SQL WHERE filters in `store.events()`,
|
|
30
|
+
combinable with `--agent` and the period selectors; NULL providers match
|
|
31
|
+
`--provider unknown` (COALESCE).
|
|
32
|
+
- `--billing-mode` (metered|subscription|credit|quota|local|unknown), applied
|
|
33
|
+
post-pricing via the `analyze_agent(billing_modes=...)` hook: billing_mode
|
|
34
|
+
is a pricing-time artifact flipped to `metered` on recorded-cost conflict,
|
|
35
|
+
so SQL cannot pre-filter it.
|
|
36
|
+
- `period_comparison`: bounded runs compare the current period against the
|
|
37
|
+
same-length previous window (`_previous_window`, same filters) — terminal
|
|
38
|
+
`PERIOD COMPARISON` (tokens, cost, entries, requests + Δ) and an additive
|
|
39
|
+
JSON block; all-time runs omit it.
|
|
40
|
+
|
|
41
|
+
### Changed
|
|
42
|
+
|
|
43
|
+
- OpenCode timestamps stored as ISO-8601 (parser v3); epoch-millis rows
|
|
44
|
+
re-collect on refresh.
|
|
45
|
+
- Claude Code aggregate scope warning now via a store presence check, so it
|
|
46
|
+
survives SQL filtering.
|
|
47
|
+
- `store.events()` filters agents, dates, models, and providers in SQL; the
|
|
48
|
+
Python date filter remains as the equivalence reference.
|
|
49
|
+
- Indices on provider, model, project, session (additive, idempotent).
|
|
50
|
+
- `AgentStats` gained `project_breakdown`/`session_breakdown` (model_breakdown
|
|
51
|
+
shape; `unknown` bucket for unattributed rows), shown in terminal as
|
|
52
|
+
`BREAKDOWN BY SESSION`/`BREAKDOWN BY PROJECT` and in JSON; unattributed-only
|
|
53
|
+
sections print `No ... attribution available.`.
|
|
54
|
+
|
|
55
|
+
### Tests
|
|
56
|
+
|
|
57
|
+
- SQL-vs-Python equivalence, presence check, indices, grouping (incl.
|
|
58
|
+
unattributed), two-period reuse/disjointness.
|
|
59
|
+
- Per-selector and combination tests incl.
|
|
60
|
+
recorded-cost-flips-to-metered; previous-window math; simulated-CLI
|
|
61
|
+
comparison asserting values and delta.
|
|
62
|
+
- Phase 1 baseline extended for additive keys `project_breakdown`,
|
|
63
|
+
`session_breakdown`, `period_comparison`; Phase 6 pins the final contract.
|
|
64
|
+
|
|
65
|
+
## [0.0.4] - Report baseline + result seams
|
|
66
|
+
|
|
67
|
+
### Added
|
|
68
|
+
|
|
69
|
+
- Tests lock JSON `--output` schema and terminal report key sections against a hermetic fixture to assert exact values.
|
|
70
|
+
- Added cache read and cache efficiency ratios to JSON exports (previously terminal-only).
|
|
71
|
+
- `AnalysisReport` encapsulates period, per-agent stats/display periods, and pricing/preferences provenance; moved JSON assembly from CLI to `render.py`.
|
|
72
|
+
- `UsageAnalyzer.display_period` unit tests for ranged and all-time period derivations.
|
|
73
|
+
|
|
74
|
+
### Changed
|
|
75
|
+
|
|
76
|
+
- Terminal report, comparison summary, and JSON export now consume `AnalysisReport` instead of CLI-assembled payloads.
|
|
77
|
+
- Internal test-only models moved out of CLI exports; tests now import `eurysx.models` directly.
|
|
78
|
+
|
|
79
|
+
## [0.0.3] - Incremental collection + attribution and diagnostics
|
|
80
|
+
|
|
81
|
+
### Added
|
|
82
|
+
|
|
83
|
+
- Incremental per-source collection: collectors enumerate raw sources with stat
|
|
84
|
+
fingerprints and a parser version; the CLI skips unchanged sources and
|
|
85
|
+
transactionally replaces only sources that moved.
|
|
86
|
+
- Best-effort project attribution: Pi session-header `cwd`, Codex
|
|
87
|
+
`session_meta.cwd`, and OpenCode's `session.directory` (when present) are
|
|
88
|
+
stored per event as `project_id`; Claude Code aggregate rows stay unattributed.
|
|
89
|
+
- Failed source refreshes keep their last good events, record the error on the
|
|
90
|
+
source row, and `report` warns when last-good data is being shown.
|
|
91
|
+
|
|
92
|
+
### Changed
|
|
93
|
+
|
|
94
|
+
- Default and `report` commands both read usage back from the store after
|
|
95
|
+
collection; legacy per-agent bulk `collector:<agent>` store rows are purged.
|
|
96
|
+
- Collectors propagate read errors instead of printing and returning partial
|
|
97
|
+
data. Pi, Codex, and OpenCode parser versions moved to 2.
|
|
98
|
+
|
|
99
|
+
## [0.0.2] - Local store implementation + module restructure
|
|
100
|
+
|
|
101
|
+
### Added
|
|
102
|
+
|
|
103
|
+
- Local SQLite usage storage with decimal-text recorded costs.
|
|
104
|
+
- `eurysx collect` and `eurysx report` workflows; stored reports do not collect
|
|
105
|
+
agent history.
|
|
106
|
+
|
|
107
|
+
### Changed
|
|
108
|
+
|
|
109
|
+
- Source layout now uses the `src/eurysx` package
|
|
110
|
+
- CLI orchestration now delegates to focused collector, pricing, analysis, and rendering modules.
|
|
111
|
+
|
|
112
|
+
## [0.0.1] - Core CLI baseline
|
|
113
|
+
|
|
114
|
+
### Added
|
|
115
|
+
|
|
116
|
+
- `eurysx` CLI for Claude Code, OpenCode, Pi, and Codex local usage data.
|
|
117
|
+
- Token, request, turn, tool-call, model, provider, session, and pricing-source reporting.
|
|
118
|
+
- JSON reports, `--version`/`-v`, and explicit rolling, calendar, and ISO date selectors.
|
|
119
|
+
- Checkout-local pricing config/cache paths with explicit environment overrides.
|
|
120
|
+
- Configurable pricing resolution: recorded cost, overrides, enabled sources, cache fallback, then unknown.
|
|
121
|
+
- User-owned per-agent route and billing preferences with pricing-provider mapping.
|
|
122
|
+
- Ordered provider-aware pricing source fallbacks and a project-local cache.
|
|
123
|
+
- Sanitized collector fixtures, pricing regression tests, setuptools metadata, and MIT license.
|
|
124
|
+
|
|
125
|
+
### Changed
|
|
126
|
+
|
|
127
|
+
- Reports label money as known cost and expose unknown-cost tokens and priced-token coverage.
|
|
128
|
+
- Selected date ranges exclude `Claude Code`'s aggregate stats-cache data and emit a scope warning.
|
|
129
|
+
- Source distributions include the changelog and safe pricing configuration sample.
|
|
130
|
+
- Empty-token coverage is `N/A`; malformed pricing configuration is reported as a diagnostic.
|
|
131
|
+
- `OpenCode` turn detection no longer depends on SQLite message-row order.
|
|
132
|
+
- All-time reports derive cost-rate periods from observed usage dates.
|
|
133
|
+
- Reports separate metered token coverage from subscription, credit, quota, local, and unknown usage.
|
|
134
|
+
- Codex preserves recorded route-provider metadata; provider-qualified prices no longer cross-match.
|
|
135
|
+
- Preferences now use agent defaults and provider overrides; `aws-bedrock` is
|
|
136
|
+
renamed to `amazon-bedrock` in pricing configuration and cache provenance.
|
|
137
|
+
- Configuration documentation and samples now distinguish required enabled-source
|
|
138
|
+
settings from optional agent and provider policies.
|
|
139
|
+
- OpenCode collector parity now uses a tracked, sanitized SQL fixture that builds
|
|
140
|
+
its temporary SQLite database during tests.
|
eurysx-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 openlines
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
eurysx-0.1.0/MANIFEST.in
ADDED
eurysx-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: eurysx
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Local usage intelligence for AI coding agents
|
|
5
|
+
Author: openlines
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Requires-Python: >=3.11
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Dynamic: license-file
|
|
11
|
+
|
|
12
|
+
# Eurysx
|
|
13
|
+
|
|
14
|
+
Local-first usage observability for Claude Code, OpenCode, Pi, and Codex.
|
|
15
|
+
|
|
16
|
+
Eurysx reads local agent history and reports tokens, requests, turns, tool calls,
|
|
17
|
+
estimated or recorded cost, and pricing provenance. It does not upload usage data
|
|
18
|
+
or persist prompts, responses, file contents, tool arguments, or tool results.
|
|
19
|
+
|
|
20
|
+
> Eurysx v0.1.0 is a local CLI, not a hosted service.
|
|
21
|
+
|
|
22
|
+
## Install
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
python3 -m pip install .
|
|
26
|
+
eurysx --help
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Run
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
eurysx --version
|
|
33
|
+
eurysx
|
|
34
|
+
eurysx --agent codex --days 30
|
|
35
|
+
eurysx --agent all --month 2026-08
|
|
36
|
+
eurysx --agent pi --from 2026-08-01 --to 2026-08-15
|
|
37
|
+
eurysx --agent all --days 30 --output reports/usage.json
|
|
38
|
+
eurysx --refresh-pricing
|
|
39
|
+
eurysx collect --agent codex
|
|
40
|
+
eurysx report --agent codex --days 30
|
|
41
|
+
eurysx doctor
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`reports/` is ignored by Git.
|
|
45
|
+
|
|
46
|
+
`eurysx` collects current local metadata and then reports it. `collect` stores
|
|
47
|
+
metadata only; `report` reads the local store without collecting. `doctor` is
|
|
48
|
+
terminal-only and reports local harness, source, pricing-cache, and configuration
|
|
49
|
+
health without parsing history, refreshing prices, or deleting retained data. During Act II,
|
|
50
|
+
the store is `data/eurysx.db` relative to the current project directory. Set
|
|
51
|
+
`EURYSX_DATA_DIR` only to deliberately relocate it.
|
|
52
|
+
|
|
53
|
+
Period selectors are mutually exclusive: `--days N`, `--weeks N`,
|
|
54
|
+
`--from YYYY-MM-DD [--to YYYY-MM-DD]`, `--month YYYY-MM`,
|
|
55
|
+
`--quarter YYYY-QN`, `--year YYYY`, and `--ytd`. Rolling periods include today.
|
|
56
|
+
|
|
57
|
+
Filter selectors `--model`, `--provider`, and `--billing-mode` narrow the
|
|
58
|
+
analyzed rows and combine with `--agent` and the period selectors; bounded
|
|
59
|
+
period runs also compare against the same-length previous window. See the
|
|
60
|
+
[operational manual](docs/manual.md) for details.
|
|
61
|
+
|
|
62
|
+
## Documentation
|
|
63
|
+
|
|
64
|
+
The [operational manual](docs/manual.md) is the authoritative command, output,
|
|
65
|
+
configuration, and diagnostics reference. Legacy [CLI](docs/cli.md) and
|
|
66
|
+
[output](docs/output.md) pages redirect there.
|
|
67
|
+
|
|
68
|
+
This manual is the authoritative contract for the JSONC configuration files.
|
|
69
|
+
|
|
70
|
+
## Configuration manual
|
|
71
|
+
|
|
72
|
+
Eurysx is checkout-local during Act I. It reads and writes only these paths by
|
|
73
|
+
default, relative to the directory where you run `eurysx`:
|
|
74
|
+
|
|
75
|
+
```text
|
|
76
|
+
eurysx/
|
|
77
|
+
├── config/pricing.jsonc
|
|
78
|
+
├── config/preferences.jsonc
|
|
79
|
+
└── cache/
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
It does not use `~/Library/Application Support`, XDG directories, or other
|
|
83
|
+
system-level application folders. The local configuration and cache are ignored
|
|
84
|
+
by Git. Create them from the tracked templates:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
cp config/pricing.jsonc.sample config/pricing.jsonc
|
|
88
|
+
cp config/preferences.jsonc.sample config/preferences.jsonc
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Both files are JSONC: comments and trailing commas are allowed. Both are
|
|
92
|
+
optional. Without them, Eurysx retains recorded usage and marks unresolved cost
|
|
93
|
+
as unknown. Use `EURYSX_CONFIG_DIR` and `EURYSX_CACHE_DIR` only when deliberately
|
|
94
|
+
relocating those two directories, for example to a removable development volume.
|
|
95
|
+
|
|
96
|
+
### `preferences.jsonc`: agent and provider policy
|
|
97
|
+
|
|
98
|
+
`preferences.jsonc` declares a schema version 2 policy. An agent-level policy
|
|
99
|
+
applies to every model when the collector has no provider metadata. `providers`
|
|
100
|
+
overrides that policy only for an exact recorded provider. There are no
|
|
101
|
+
model-match rules.
|
|
102
|
+
|
|
103
|
+
```jsonc
|
|
104
|
+
{
|
|
105
|
+
"schemaVersion": 2,
|
|
106
|
+
"agents": {
|
|
107
|
+
"claude-code": {
|
|
108
|
+
"provider": "amazon-bedrock",
|
|
109
|
+
"billingMode": "metered",
|
|
110
|
+
"pricing": {
|
|
111
|
+
"source": "amazon-bedrock",
|
|
112
|
+
"otherSources": ["models-dev", "pi-models-store"]
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
"codex": {
|
|
116
|
+
"providers": {
|
|
117
|
+
"openai": { "billingMode": "subscription" },
|
|
118
|
+
"amazon-bedrock": {
|
|
119
|
+
"billingMode": "metered",
|
|
120
|
+
"pricing": { "source": "amazon-bedrock", "otherSources": ["models-dev"] }
|
|
121
|
+
},
|
|
122
|
+
"litellm": { "billingMode": "local" }
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
`schemaVersion` and `agents` are the expected top-level fields. `schemaVersion`
|
|
130
|
+
is currently informational; Eurysx does not reject the file based on its value.
|
|
131
|
+
The file itself and each agent entry are optional. Omit an agent entry when you
|
|
132
|
+
want its usage to remain unclassified. Supported agent keys are `claude-code`,
|
|
133
|
+
`codex`, `opencode`, and `pi`; unknown keys are ignored.
|
|
134
|
+
|
|
135
|
+
| Policy field | Required? | Meaning |
|
|
136
|
+
| --- | --- | --- |
|
|
137
|
+
| `provider` | Optional | Effective provider when the collector does not record one. Usually needed for an agent-level metered policy. |
|
|
138
|
+
| `billingMode` | Optional | `metered`, `subscription`, `credit`, `quota`, `local`, or `unknown`. Omit it to let a matching provider policy decide; if no policy supplies it, Eurysx uses `unknown`. |
|
|
139
|
+
| `providers` | Optional | Map of exact recorded provider names to policy objects. Provider-policy fields override the agent-level fields. |
|
|
140
|
+
| `pricing` | Optional | Pricing lookup policy. For a config-priced metered route, include at least one valid `source` or `otherSources` entry. |
|
|
141
|
+
| `pricing.source` | Optional | Primary enabled source name from `pricing.jsonc`. |
|
|
142
|
+
| `pricing.otherSources` | Optional | Ordered enabled fallback source names from `pricing.jsonc`. |
|
|
143
|
+
|
|
144
|
+
`subscription`, `credit`, `quota`, and `local` report `N/A` incremental USD.
|
|
145
|
+
`metered` resolves pricing. A source name that is missing, disabled, or lacks an
|
|
146
|
+
exact provider/model price is skipped. Recorded harness cost always wins.
|
|
147
|
+
|
|
148
|
+
For an agent using more than one provider, omit agent-level `billingMode` rather
|
|
149
|
+
than setting it to `unknown` or an empty value. JSON has no useful blank value
|
|
150
|
+
here: `"billingMode": ""` is invalid policy data and is reported as unknown.
|
|
151
|
+
For example, Codex can classify its recorded OpenAI route as `subscription`, its
|
|
152
|
+
recorded Bedrock route as `metered`, and its recorded LiteLLM route as `local`.
|
|
153
|
+
If a record has no provider, or its provider is absent from `providers`, its
|
|
154
|
+
billing mode is `unknown` unless the agent-level policy defines one. Optional
|
|
155
|
+
budgets use `{"usd": 100, "period": "month"}` under an agent or exact provider;
|
|
156
|
+
invalid budgets disable pacing with a warning.
|
|
157
|
+
|
|
158
|
+
Billing modes describe incremental cost, not capability:
|
|
159
|
+
|
|
160
|
+
| Mode | Eurysx cost treatment |
|
|
161
|
+
| --- | --- |
|
|
162
|
+
| `metered` | Resolves per-token USD pricing. |
|
|
163
|
+
| `subscription`, `credit`, `quota`, `local` | Reports `N/A` incremental USD. Eurysx does not allocate fees or convert credits. |
|
|
164
|
+
| `unknown` | Retains usage and reports cost as unknown until you classify it or add pricing. |
|
|
165
|
+
|
|
166
|
+
Recorded harness cost always wins. If a recorded cost conflicts with a
|
|
167
|
+
non-metered policy, Eurysx keeps the recorded cost and warns.
|
|
168
|
+
|
|
169
|
+
### `pricing.jsonc`: price sources and manual overrides
|
|
170
|
+
|
|
171
|
+
`pricing.jsonc` supplies per-million-token USD prices only for `metered` usage.
|
|
172
|
+
It has `sources`, provider-scoped `aliases`, and `overrides`. The file is
|
|
173
|
+
optional. Configure an enabled source before naming it in `pricing.source` or
|
|
174
|
+
`pricing.otherSources`.
|
|
175
|
+
|
|
176
|
+
```jsonc
|
|
177
|
+
{
|
|
178
|
+
"schemaVersion": 2,
|
|
179
|
+
"sources": {
|
|
180
|
+
"amazon-bedrock": {
|
|
181
|
+
"enabled": true,
|
|
182
|
+
"profile": "your-aws-profile",
|
|
183
|
+
"region": "ap-southeast-1",
|
|
184
|
+
"refreshDays": 7
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
"aliases": {
|
|
188
|
+
"amazon-bedrock": {
|
|
189
|
+
"claude-sonnet-4-6": "global.anthropic.claude-sonnet-4-6"
|
|
190
|
+
}
|
|
191
|
+
},
|
|
192
|
+
"overrides": {
|
|
193
|
+
"amazon-bedrock/bedrock.gpt-5.6": {
|
|
194
|
+
"input": 0,
|
|
195
|
+
"output": 0,
|
|
196
|
+
"cacheRead": 0,
|
|
197
|
+
"cacheWrite": 0
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Supported sources are:
|
|
204
|
+
|
|
205
|
+
| Source | Required when enabled | Optional | Reads from |
|
|
206
|
+
| --- | --- | --- | --- |
|
|
207
|
+
| `amazon-bedrock` | `enabled: true`, `profile`, `region` | `refreshDays` | `aws pricing get-products` for Amazon Bedrock. |
|
|
208
|
+
| `pi-models-store` | `enabled: true` | `refreshDays` | `~/.pi/agent/models-store.json`. |
|
|
209
|
+
| `models-dev` | `enabled: true`, `url` | `refreshDays` | The configured models.dev-compatible URL. |
|
|
210
|
+
|
|
211
|
+
Aliases map collector model names to a source's canonical model ID without
|
|
212
|
+
changing billing policy. Override keys are `provider/model`; values are USD per
|
|
213
|
+
one million tokens. An override requires `input` and `output`; `cacheRead` and
|
|
214
|
+
`cacheWrite` are optional and default to zero. Never use a bare model override
|
|
215
|
+
to price multiple providers.
|
|
216
|
+
|
|
217
|
+
Resolution order is: recorded cost, explicit override, the route primary source,
|
|
218
|
+
the route's `otherSources` in order, then unknown. Eurysx never guesses a number
|
|
219
|
+
for an unpriced model.
|
|
220
|
+
|
|
221
|
+
### Refreshing and inspecting pricing
|
|
222
|
+
|
|
223
|
+
Eurysx creates `cache/` in the current project directory on every run. Enabled
|
|
224
|
+
sources cache normalized results in `cache/pricing-<source>.json`. Use the
|
|
225
|
+
normal command to use a fresh cache, or force a refresh:
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
eurysx --refresh-pricing
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
If refresh fails, Eurysx uses a valid existing cache and reports a warning. If
|
|
232
|
+
no valid price is available, the associated metered usage remains unknown rather
|
|
233
|
+
than being reported as free. The cache contains pricing metadata, not prompts or
|
|
234
|
+
credentials. Do not add API keys or LiteLLM master keys to either configuration
|
|
235
|
+
file.
|
|
236
|
+
|
|
237
|
+
## Current limits
|
|
238
|
+
|
|
239
|
+
- Claude Code's stats cache is aggregate-only. Eurysx excludes it from selected
|
|
240
|
+
date ranges and reports a scope warning; it remains available for all-time use.
|
|
241
|
+
Its single row per model is stamped with `lastComputedDate`, so all-time Claude
|
|
242
|
+
Code rates spread the whole aggregate over that observed span and its
|
|
243
|
+
day-by-day activity table stays empty (`n/a` per-active-day lines) rather than
|
|
244
|
+
inventing a one-day spike.
|
|
245
|
+
- The supported collectors are Claude Code, OpenCode, Pi, and Codex only.
|
|
246
|
+
- Pricing data is metadata only. Source pricing may be unavailable, in which case
|
|
247
|
+
the relevant cost remains unknown.
|
|
248
|
+
- Preferences use recorded route metadata or exact user rules. Eurysx does not
|
|
249
|
+
call LiteLLM or provider APIs for route discovery and never reads credentials.
|
|
250
|
+
- A report with usage entries but no tokens displays priced-token coverage as
|
|
251
|
+
`N/A`.
|
|
252
|
+
- Collector fixtures verify known file shapes, not every live harness release.
|
|
253
|
+
|
|
254
|
+
## Development
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
PYTHONPATH=src python3 -m unittest -v tests/test_eurysx.py
|
|
258
|
+
python3 -m py_compile src/eurysx/*.py
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
Sanitized collector fixtures cover Claude Code, Codex, Pi, and OpenCode. The
|
|
262
|
+
OpenCode SQL fixture builds a temporary SQLite database during the test rather
|
|
263
|
+
than committing a binary database file.
|
eurysx-0.1.0/README.md
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
# Eurysx
|
|
2
|
+
|
|
3
|
+
Local-first usage observability for Claude Code, OpenCode, Pi, and Codex.
|
|
4
|
+
|
|
5
|
+
Eurysx reads local agent history and reports tokens, requests, turns, tool calls,
|
|
6
|
+
estimated or recorded cost, and pricing provenance. It does not upload usage data
|
|
7
|
+
or persist prompts, responses, file contents, tool arguments, or tool results.
|
|
8
|
+
|
|
9
|
+
> Eurysx v0.1.0 is a local CLI, not a hosted service.
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
python3 -m pip install .
|
|
15
|
+
eurysx --help
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Run
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
eurysx --version
|
|
22
|
+
eurysx
|
|
23
|
+
eurysx --agent codex --days 30
|
|
24
|
+
eurysx --agent all --month 2026-08
|
|
25
|
+
eurysx --agent pi --from 2026-08-01 --to 2026-08-15
|
|
26
|
+
eurysx --agent all --days 30 --output reports/usage.json
|
|
27
|
+
eurysx --refresh-pricing
|
|
28
|
+
eurysx collect --agent codex
|
|
29
|
+
eurysx report --agent codex --days 30
|
|
30
|
+
eurysx doctor
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
`reports/` is ignored by Git.
|
|
34
|
+
|
|
35
|
+
`eurysx` collects current local metadata and then reports it. `collect` stores
|
|
36
|
+
metadata only; `report` reads the local store without collecting. `doctor` is
|
|
37
|
+
terminal-only and reports local harness, source, pricing-cache, and configuration
|
|
38
|
+
health without parsing history, refreshing prices, or deleting retained data. During Act II,
|
|
39
|
+
the store is `data/eurysx.db` relative to the current project directory. Set
|
|
40
|
+
`EURYSX_DATA_DIR` only to deliberately relocate it.
|
|
41
|
+
|
|
42
|
+
Period selectors are mutually exclusive: `--days N`, `--weeks N`,
|
|
43
|
+
`--from YYYY-MM-DD [--to YYYY-MM-DD]`, `--month YYYY-MM`,
|
|
44
|
+
`--quarter YYYY-QN`, `--year YYYY`, and `--ytd`. Rolling periods include today.
|
|
45
|
+
|
|
46
|
+
Filter selectors `--model`, `--provider`, and `--billing-mode` narrow the
|
|
47
|
+
analyzed rows and combine with `--agent` and the period selectors; bounded
|
|
48
|
+
period runs also compare against the same-length previous window. See the
|
|
49
|
+
[operational manual](docs/manual.md) for details.
|
|
50
|
+
|
|
51
|
+
## Documentation
|
|
52
|
+
|
|
53
|
+
The [operational manual](docs/manual.md) is the authoritative command, output,
|
|
54
|
+
configuration, and diagnostics reference. Legacy [CLI](docs/cli.md) and
|
|
55
|
+
[output](docs/output.md) pages redirect there.
|
|
56
|
+
|
|
57
|
+
This manual is the authoritative contract for the JSONC configuration files.
|
|
58
|
+
|
|
59
|
+
## Configuration manual
|
|
60
|
+
|
|
61
|
+
Eurysx is checkout-local during Act I. It reads and writes only these paths by
|
|
62
|
+
default, relative to the directory where you run `eurysx`:
|
|
63
|
+
|
|
64
|
+
```text
|
|
65
|
+
eurysx/
|
|
66
|
+
├── config/pricing.jsonc
|
|
67
|
+
├── config/preferences.jsonc
|
|
68
|
+
└── cache/
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
It does not use `~/Library/Application Support`, XDG directories, or other
|
|
72
|
+
system-level application folders. The local configuration and cache are ignored
|
|
73
|
+
by Git. Create them from the tracked templates:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
cp config/pricing.jsonc.sample config/pricing.jsonc
|
|
77
|
+
cp config/preferences.jsonc.sample config/preferences.jsonc
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Both files are JSONC: comments and trailing commas are allowed. Both are
|
|
81
|
+
optional. Without them, Eurysx retains recorded usage and marks unresolved cost
|
|
82
|
+
as unknown. Use `EURYSX_CONFIG_DIR` and `EURYSX_CACHE_DIR` only when deliberately
|
|
83
|
+
relocating those two directories, for example to a removable development volume.
|
|
84
|
+
|
|
85
|
+
### `preferences.jsonc`: agent and provider policy
|
|
86
|
+
|
|
87
|
+
`preferences.jsonc` declares a schema version 2 policy. An agent-level policy
|
|
88
|
+
applies to every model when the collector has no provider metadata. `providers`
|
|
89
|
+
overrides that policy only for an exact recorded provider. There are no
|
|
90
|
+
model-match rules.
|
|
91
|
+
|
|
92
|
+
```jsonc
|
|
93
|
+
{
|
|
94
|
+
"schemaVersion": 2,
|
|
95
|
+
"agents": {
|
|
96
|
+
"claude-code": {
|
|
97
|
+
"provider": "amazon-bedrock",
|
|
98
|
+
"billingMode": "metered",
|
|
99
|
+
"pricing": {
|
|
100
|
+
"source": "amazon-bedrock",
|
|
101
|
+
"otherSources": ["models-dev", "pi-models-store"]
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
"codex": {
|
|
105
|
+
"providers": {
|
|
106
|
+
"openai": { "billingMode": "subscription" },
|
|
107
|
+
"amazon-bedrock": {
|
|
108
|
+
"billingMode": "metered",
|
|
109
|
+
"pricing": { "source": "amazon-bedrock", "otherSources": ["models-dev"] }
|
|
110
|
+
},
|
|
111
|
+
"litellm": { "billingMode": "local" }
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
`schemaVersion` and `agents` are the expected top-level fields. `schemaVersion`
|
|
119
|
+
is currently informational; Eurysx does not reject the file based on its value.
|
|
120
|
+
The file itself and each agent entry are optional. Omit an agent entry when you
|
|
121
|
+
want its usage to remain unclassified. Supported agent keys are `claude-code`,
|
|
122
|
+
`codex`, `opencode`, and `pi`; unknown keys are ignored.
|
|
123
|
+
|
|
124
|
+
| Policy field | Required? | Meaning |
|
|
125
|
+
| --- | --- | --- |
|
|
126
|
+
| `provider` | Optional | Effective provider when the collector does not record one. Usually needed for an agent-level metered policy. |
|
|
127
|
+
| `billingMode` | Optional | `metered`, `subscription`, `credit`, `quota`, `local`, or `unknown`. Omit it to let a matching provider policy decide; if no policy supplies it, Eurysx uses `unknown`. |
|
|
128
|
+
| `providers` | Optional | Map of exact recorded provider names to policy objects. Provider-policy fields override the agent-level fields. |
|
|
129
|
+
| `pricing` | Optional | Pricing lookup policy. For a config-priced metered route, include at least one valid `source` or `otherSources` entry. |
|
|
130
|
+
| `pricing.source` | Optional | Primary enabled source name from `pricing.jsonc`. |
|
|
131
|
+
| `pricing.otherSources` | Optional | Ordered enabled fallback source names from `pricing.jsonc`. |
|
|
132
|
+
|
|
133
|
+
`subscription`, `credit`, `quota`, and `local` report `N/A` incremental USD.
|
|
134
|
+
`metered` resolves pricing. A source name that is missing, disabled, or lacks an
|
|
135
|
+
exact provider/model price is skipped. Recorded harness cost always wins.
|
|
136
|
+
|
|
137
|
+
For an agent using more than one provider, omit agent-level `billingMode` rather
|
|
138
|
+
than setting it to `unknown` or an empty value. JSON has no useful blank value
|
|
139
|
+
here: `"billingMode": ""` is invalid policy data and is reported as unknown.
|
|
140
|
+
For example, Codex can classify its recorded OpenAI route as `subscription`, its
|
|
141
|
+
recorded Bedrock route as `metered`, and its recorded LiteLLM route as `local`.
|
|
142
|
+
If a record has no provider, or its provider is absent from `providers`, its
|
|
143
|
+
billing mode is `unknown` unless the agent-level policy defines one. Optional
|
|
144
|
+
budgets use `{"usd": 100, "period": "month"}` under an agent or exact provider;
|
|
145
|
+
invalid budgets disable pacing with a warning.
|
|
146
|
+
|
|
147
|
+
Billing modes describe incremental cost, not capability:
|
|
148
|
+
|
|
149
|
+
| Mode | Eurysx cost treatment |
|
|
150
|
+
| --- | --- |
|
|
151
|
+
| `metered` | Resolves per-token USD pricing. |
|
|
152
|
+
| `subscription`, `credit`, `quota`, `local` | Reports `N/A` incremental USD. Eurysx does not allocate fees or convert credits. |
|
|
153
|
+
| `unknown` | Retains usage and reports cost as unknown until you classify it or add pricing. |
|
|
154
|
+
|
|
155
|
+
Recorded harness cost always wins. If a recorded cost conflicts with a
|
|
156
|
+
non-metered policy, Eurysx keeps the recorded cost and warns.
|
|
157
|
+
|
|
158
|
+
### `pricing.jsonc`: price sources and manual overrides
|
|
159
|
+
|
|
160
|
+
`pricing.jsonc` supplies per-million-token USD prices only for `metered` usage.
|
|
161
|
+
It has `sources`, provider-scoped `aliases`, and `overrides`. The file is
|
|
162
|
+
optional. Configure an enabled source before naming it in `pricing.source` or
|
|
163
|
+
`pricing.otherSources`.
|
|
164
|
+
|
|
165
|
+
```jsonc
|
|
166
|
+
{
|
|
167
|
+
"schemaVersion": 2,
|
|
168
|
+
"sources": {
|
|
169
|
+
"amazon-bedrock": {
|
|
170
|
+
"enabled": true,
|
|
171
|
+
"profile": "your-aws-profile",
|
|
172
|
+
"region": "ap-southeast-1",
|
|
173
|
+
"refreshDays": 7
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
"aliases": {
|
|
177
|
+
"amazon-bedrock": {
|
|
178
|
+
"claude-sonnet-4-6": "global.anthropic.claude-sonnet-4-6"
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
"overrides": {
|
|
182
|
+
"amazon-bedrock/bedrock.gpt-5.6": {
|
|
183
|
+
"input": 0,
|
|
184
|
+
"output": 0,
|
|
185
|
+
"cacheRead": 0,
|
|
186
|
+
"cacheWrite": 0
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Supported sources are:
|
|
193
|
+
|
|
194
|
+
| Source | Required when enabled | Optional | Reads from |
|
|
195
|
+
| --- | --- | --- | --- |
|
|
196
|
+
| `amazon-bedrock` | `enabled: true`, `profile`, `region` | `refreshDays` | `aws pricing get-products` for Amazon Bedrock. |
|
|
197
|
+
| `pi-models-store` | `enabled: true` | `refreshDays` | `~/.pi/agent/models-store.json`. |
|
|
198
|
+
| `models-dev` | `enabled: true`, `url` | `refreshDays` | The configured models.dev-compatible URL. |
|
|
199
|
+
|
|
200
|
+
Aliases map collector model names to a source's canonical model ID without
|
|
201
|
+
changing billing policy. Override keys are `provider/model`; values are USD per
|
|
202
|
+
one million tokens. An override requires `input` and `output`; `cacheRead` and
|
|
203
|
+
`cacheWrite` are optional and default to zero. Never use a bare model override
|
|
204
|
+
to price multiple providers.
|
|
205
|
+
|
|
206
|
+
Resolution order is: recorded cost, explicit override, the route primary source,
|
|
207
|
+
the route's `otherSources` in order, then unknown. Eurysx never guesses a number
|
|
208
|
+
for an unpriced model.
|
|
209
|
+
|
|
210
|
+
### Refreshing and inspecting pricing
|
|
211
|
+
|
|
212
|
+
Eurysx creates `cache/` in the current project directory on every run. Enabled
|
|
213
|
+
sources cache normalized results in `cache/pricing-<source>.json`. Use the
|
|
214
|
+
normal command to use a fresh cache, or force a refresh:
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
eurysx --refresh-pricing
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
If refresh fails, Eurysx uses a valid existing cache and reports a warning. If
|
|
221
|
+
no valid price is available, the associated metered usage remains unknown rather
|
|
222
|
+
than being reported as free. The cache contains pricing metadata, not prompts or
|
|
223
|
+
credentials. Do not add API keys or LiteLLM master keys to either configuration
|
|
224
|
+
file.
|
|
225
|
+
|
|
226
|
+
## Current limits
|
|
227
|
+
|
|
228
|
+
- Claude Code's stats cache is aggregate-only. Eurysx excludes it from selected
|
|
229
|
+
date ranges and reports a scope warning; it remains available for all-time use.
|
|
230
|
+
Its single row per model is stamped with `lastComputedDate`, so all-time Claude
|
|
231
|
+
Code rates spread the whole aggregate over that observed span and its
|
|
232
|
+
day-by-day activity table stays empty (`n/a` per-active-day lines) rather than
|
|
233
|
+
inventing a one-day spike.
|
|
234
|
+
- The supported collectors are Claude Code, OpenCode, Pi, and Codex only.
|
|
235
|
+
- Pricing data is metadata only. Source pricing may be unavailable, in which case
|
|
236
|
+
the relevant cost remains unknown.
|
|
237
|
+
- Preferences use recorded route metadata or exact user rules. Eurysx does not
|
|
238
|
+
call LiteLLM or provider APIs for route discovery and never reads credentials.
|
|
239
|
+
- A report with usage entries but no tokens displays priced-token coverage as
|
|
240
|
+
`N/A`.
|
|
241
|
+
- Collector fixtures verify known file shapes, not every live harness release.
|
|
242
|
+
|
|
243
|
+
## Development
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
PYTHONPATH=src python3 -m unittest -v tests/test_eurysx.py
|
|
247
|
+
python3 -m py_compile src/eurysx/*.py
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Sanitized collector fixtures cover Claude Code, Codex, Pi, and OpenCode. The
|
|
251
|
+
OpenCode SQL fixture builds a temporary SQLite database during the test rather
|
|
252
|
+
than committing a binary database file.
|