agent-roi-tracker 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.
- agent_roi_tracker-0.1.0/.claude/settings.local.json +8 -0
- agent_roi_tracker-0.1.0/.github/ISSUE_TEMPLATE/bug_report.md +24 -0
- agent_roi_tracker-0.1.0/.github/ISSUE_TEMPLATE/feature_request.md +18 -0
- agent_roi_tracker-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +14 -0
- agent_roi_tracker-0.1.0/.github/workflows/ci.yml +52 -0
- agent_roi_tracker-0.1.0/.gitignore +30 -0
- agent_roi_tracker-0.1.0/CLAUDE.md +84 -0
- agent_roi_tracker-0.1.0/CODE_OF_CONDUCT.md +37 -0
- agent_roi_tracker-0.1.0/CONTRIBUTING.md +78 -0
- agent_roi_tracker-0.1.0/CONTRIBUTING.zh.md +75 -0
- agent_roi_tracker-0.1.0/LICENSE +21 -0
- agent_roi_tracker-0.1.0/PKG-INFO +163 -0
- agent_roi_tracker-0.1.0/README.md +128 -0
- agent_roi_tracker-0.1.0/README.zh.md +137 -0
- agent_roi_tracker-0.1.0/design/DESIGN.md +821 -0
- agent_roi_tracker-0.1.0/design/README.md +18 -0
- agent_roi_tracker-0.1.0/docs/architecture.md +59 -0
- agent_roi_tracker-0.1.0/docs/architecture.zh.md +54 -0
- agent_roi_tracker-0.1.0/docs/collectors.md +81 -0
- agent_roi_tracker-0.1.0/docs/collectors.zh.md +75 -0
- agent_roi_tracker-0.1.0/docs/configuration.md +53 -0
- agent_roi_tracker-0.1.0/docs/configuration.zh.md +51 -0
- agent_roi_tracker-0.1.0/pyproject.toml +73 -0
- agent_roi_tracker-0.1.0/pyrightconfig.json +6 -0
- agent_roi_tracker-0.1.0/scripts/build_web.sh +23 -0
- agent_roi_tracker-0.1.0/scripts/install.sh +43 -0
- agent_roi_tracker-0.1.0/src/agent_roi/__init__.py +3 -0
- agent_roi_tracker-0.1.0/src/agent_roi/api/__init__.py +1 -0
- agent_roi_tracker-0.1.0/src/agent_roi/api/app.py +179 -0
- agent_roi_tracker-0.1.0/src/agent_roi/classify/__init__.py +26 -0
- agent_roi_tracker-0.1.0/src/agent_roi/classify/base.py +44 -0
- agent_roi_tracker-0.1.0/src/agent_roi/classify/semantic.py +197 -0
- agent_roi_tracker-0.1.0/src/agent_roi/cli/__init__.py +1 -0
- agent_roi_tracker-0.1.0/src/agent_roi/cli/main.py +200 -0
- agent_roi_tracker-0.1.0/src/agent_roi/collectors/__init__.py +31 -0
- agent_roi_tracker-0.1.0/src/agent_roi/collectors/base.py +49 -0
- agent_roi_tracker-0.1.0/src/agent_roi/collectors/claude_code.py +165 -0
- agent_roi_tracker-0.1.0/src/agent_roi/collectors/codex.py +157 -0
- agent_roi_tracker-0.1.0/src/agent_roi/collectors/copilot.py +210 -0
- agent_roi_tracker-0.1.0/src/agent_roi/collectors/gemini.py +220 -0
- agent_roi_tracker-0.1.0/src/agent_roi/core/__init__.py +1 -0
- agent_roi_tracker-0.1.0/src/agent_roi/core/config.py +58 -0
- agent_roi_tracker-0.1.0/src/agent_roi/core/models.py +241 -0
- agent_roi_tracker-0.1.0/src/agent_roi/core/platform.py +113 -0
- agent_roi_tracker-0.1.0/src/agent_roi/core/pricing.py +79 -0
- agent_roi_tracker-0.1.0/src/agent_roi/core/project.py +52 -0
- agent_roi_tracker-0.1.0/src/agent_roi/core/service.py +172 -0
- agent_roi_tracker-0.1.0/src/agent_roi/core/timeframe.py +76 -0
- agent_roi_tracker-0.1.0/src/agent_roi/core/tokens.py +30 -0
- agent_roi_tracker-0.1.0/src/agent_roi/storage/__init__.py +5 -0
- agent_roi_tracker-0.1.0/src/agent_roi/storage/db.py +542 -0
- agent_roi_tracker-0.1.0/tests/test_claude_code_collector.py +66 -0
- agent_roi_tracker-0.1.0/tests/test_codex_collector.py +69 -0
- agent_roi_tracker-0.1.0/tests/test_copilot_collector.py +55 -0
- agent_roi_tracker-0.1.0/tests/test_pricing.py +32 -0
- agent_roi_tracker-0.1.0/tests/test_reporting.py +124 -0
- agent_roi_tracker-0.1.0/tests/test_semantic_classifier.py +92 -0
- agent_roi_tracker-0.1.0/tests/test_sessions.py +66 -0
- agent_roi_tracker-0.1.0/tests/test_storage.py +76 -0
- agent_roi_tracker-0.1.0/tests/test_timeframe.py +49 -0
- agent_roi_tracker-0.1.0/tests/test_tokens.py +24 -0
- agent_roi_tracker-0.1.0/uv.lock +1443 -0
- agent_roi_tracker-0.1.0/web/index.html +18 -0
- agent_roi_tracker-0.1.0/web/package-lock.json +2198 -0
- agent_roi_tracker-0.1.0/web/package.json +26 -0
- agent_roi_tracker-0.1.0/web/src/App.tsx +81 -0
- agent_roi_tracker-0.1.0/web/src/components/BreakdownModal.tsx +190 -0
- agent_roi_tracker-0.1.0/web/src/components/Controls.tsx +64 -0
- agent_roi_tracker-0.1.0/web/src/components/LanguageSwitcher.tsx +27 -0
- agent_roi_tracker-0.1.0/web/src/components/PricingModal.tsx +62 -0
- agent_roi_tracker-0.1.0/web/src/components/RollupChart.tsx +52 -0
- agent_roi_tracker-0.1.0/web/src/components/RollupTable.tsx +61 -0
- agent_roi_tracker-0.1.0/web/src/components/SessionModal.tsx +218 -0
- agent_roi_tracker-0.1.0/web/src/components/SourcesPanel.tsx +90 -0
- agent_roi_tracker-0.1.0/web/src/components/StatsCards.tsx +42 -0
- agent_roi_tracker-0.1.0/web/src/components/ToolIcon.tsx +142 -0
- agent_roi_tracker-0.1.0/web/src/components/Toolbar.tsx +48 -0
- agent_roi_tracker-0.1.0/web/src/components/charts/SharePieChart.tsx +72 -0
- agent_roi_tracker-0.1.0/web/src/components/charts/StackedAreaChart.tsx +57 -0
- agent_roi_tracker-0.1.0/web/src/components/charts/TrendLineChart.tsx +70 -0
- agent_roi_tracker-0.1.0/web/src/components/layout/AppShell.tsx +43 -0
- agent_roi_tracker-0.1.0/web/src/components/layout/DateRangeFilter.tsx +79 -0
- agent_roi_tracker-0.1.0/web/src/components/layout/GranularityFilter.tsx +31 -0
- agent_roi_tracker-0.1.0/web/src/components/layout/Sidebar.tsx +141 -0
- agent_roi_tracker-0.1.0/web/src/i18n/index.ts +72 -0
- agent_roi_tracker-0.1.0/web/src/i18n/locales/af.json +173 -0
- agent_roi_tracker-0.1.0/web/src/i18n/locales/de.json +173 -0
- agent_roi_tracker-0.1.0/web/src/i18n/locales/en.json +173 -0
- agent_roi_tracker-0.1.0/web/src/i18n/locales/es.json +173 -0
- agent_roi_tracker-0.1.0/web/src/i18n/locales/fr.json +173 -0
- agent_roi_tracker-0.1.0/web/src/i18n/locales/ja.json +173 -0
- agent_roi_tracker-0.1.0/web/src/i18n/locales/ko.json +173 -0
- agent_roi_tracker-0.1.0/web/src/i18n/locales/tr.json +173 -0
- agent_roi_tracker-0.1.0/web/src/i18n/locales/uk.json +173 -0
- agent_roi_tracker-0.1.0/web/src/i18n/locales/zh-CN.json +173 -0
- agent_roi_tracker-0.1.0/web/src/i18n/locales/zh-TW.json +173 -0
- agent_roi_tracker-0.1.0/web/src/index.css +885 -0
- agent_roi_tracker-0.1.0/web/src/lib/api.ts +191 -0
- agent_roi_tracker-0.1.0/web/src/lib/chartTheme.ts +32 -0
- agent_roi_tracker-0.1.0/web/src/lib/dateFilter.ts +17 -0
- agent_roi_tracker-0.1.0/web/src/lib/format.ts +39 -0
- agent_roi_tracker-0.1.0/web/src/lib/sessionView.ts +64 -0
- agent_roi_tracker-0.1.0/web/src/lib/timeseriesView.ts +22 -0
- agent_roi_tracker-0.1.0/web/src/main.tsx +11 -0
- agent_roi_tracker-0.1.0/web/src/pages/OverviewPage.tsx +109 -0
- agent_roi_tracker-0.1.0/web/src/pages/PricingPage.tsx +57 -0
- agent_roi_tracker-0.1.0/web/src/pages/SourcesPage.tsx +23 -0
- agent_roi_tracker-0.1.0/web/src/pages/TopicsPage.tsx +87 -0
- agent_roi_tracker-0.1.0/web/src/pages/TrendsPage.tsx +112 -0
- agent_roi_tracker-0.1.0/web/tsconfig.json +20 -0
- agent_roi_tracker-0.1.0/web/vite.config.ts +16 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: Report a problem with Agent-ROI
|
|
4
|
+
title: "[Bug] "
|
|
5
|
+
labels: bug
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
**Describe the bug**
|
|
9
|
+
A clear description of what went wrong.
|
|
10
|
+
|
|
11
|
+
**To reproduce**
|
|
12
|
+
Steps to reproduce the behavior (commands run, config used).
|
|
13
|
+
|
|
14
|
+
**Expected behavior**
|
|
15
|
+
What you expected to happen.
|
|
16
|
+
|
|
17
|
+
**Environment**
|
|
18
|
+
- OS: [e.g. macOS 14 / Windows 11 / Ubuntu 22.04 / WSL2]
|
|
19
|
+
- Python version: [`python --version`]
|
|
20
|
+
- Agent-ROI version: [`agent-roi --version` or commit]
|
|
21
|
+
- AI tools tracked: [e.g. Claude Code, Codex]
|
|
22
|
+
|
|
23
|
+
**Logs / output**
|
|
24
|
+
Paste any relevant error output (redact anything sensitive).
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature request
|
|
3
|
+
about: Suggest an idea or a new tool integration
|
|
4
|
+
title: "[Feature] "
|
|
5
|
+
labels: enhancement
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
**Problem**
|
|
9
|
+
What problem does this solve? Which AI tool or workflow is involved?
|
|
10
|
+
|
|
11
|
+
**Proposed solution**
|
|
12
|
+
What would you like to happen?
|
|
13
|
+
|
|
14
|
+
**Alternatives considered**
|
|
15
|
+
Any alternative approaches you've thought about.
|
|
16
|
+
|
|
17
|
+
**Additional context**
|
|
18
|
+
Anything else (links, screenshots, log formats for a new collector).
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
|
|
3
|
+
<!-- What does this PR do and why? -->
|
|
4
|
+
|
|
5
|
+
## Changes
|
|
6
|
+
|
|
7
|
+
<!-- Bullet list of notable changes -->
|
|
8
|
+
|
|
9
|
+
## Checklist
|
|
10
|
+
|
|
11
|
+
- [ ] Tests added/updated and `uv run pytest` passes
|
|
12
|
+
- [ ] `uv run ruff check src tests` passes
|
|
13
|
+
- [ ] `uv run mypy` passes
|
|
14
|
+
- [ ] Docs updated (both `*.md` and `*.zh.md` where applicable)
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
backend:
|
|
10
|
+
runs-on: ${{ matrix.os }}
|
|
11
|
+
strategy:
|
|
12
|
+
fail-fast: false
|
|
13
|
+
matrix:
|
|
14
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
15
|
+
python-version: ["3.10", "3.12"]
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Install uv
|
|
20
|
+
uses: astral-sh/setup-uv@v3
|
|
21
|
+
with:
|
|
22
|
+
enable-cache: true
|
|
23
|
+
|
|
24
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
25
|
+
run: uv python install ${{ matrix.python-version }}
|
|
26
|
+
|
|
27
|
+
- name: Install dependencies
|
|
28
|
+
run: uv sync --extra dev
|
|
29
|
+
|
|
30
|
+
- name: Lint
|
|
31
|
+
run: uv run ruff check src tests
|
|
32
|
+
|
|
33
|
+
- name: Type check
|
|
34
|
+
run: uv run mypy
|
|
35
|
+
|
|
36
|
+
- name: Test
|
|
37
|
+
run: uv run pytest --cov=agent_roi --cov-report=term-missing
|
|
38
|
+
|
|
39
|
+
frontend:
|
|
40
|
+
runs-on: ubuntu-latest
|
|
41
|
+
defaults:
|
|
42
|
+
run:
|
|
43
|
+
working-directory: web
|
|
44
|
+
steps:
|
|
45
|
+
- uses: actions/checkout@v4
|
|
46
|
+
- uses: actions/setup-node@v4
|
|
47
|
+
with:
|
|
48
|
+
node-version: "22"
|
|
49
|
+
cache: npm
|
|
50
|
+
cache-dependency-path: web/package-lock.json
|
|
51
|
+
- run: npm ci
|
|
52
|
+
- run: npm run build
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
.venv/
|
|
5
|
+
*.egg-info/
|
|
6
|
+
.pytest_cache/
|
|
7
|
+
.mypy_cache/
|
|
8
|
+
.ruff_cache/
|
|
9
|
+
.coverage
|
|
10
|
+
htmlcov/
|
|
11
|
+
dist/
|
|
12
|
+
build/
|
|
13
|
+
|
|
14
|
+
# Node / web
|
|
15
|
+
web/node_modules/
|
|
16
|
+
web/dist/
|
|
17
|
+
web/*.tsbuildinfo
|
|
18
|
+
*.log
|
|
19
|
+
|
|
20
|
+
# Web UI bundled into the package at build time
|
|
21
|
+
src/agent_roi/webui/
|
|
22
|
+
|
|
23
|
+
# Local data & config
|
|
24
|
+
*.db
|
|
25
|
+
.env
|
|
26
|
+
|
|
27
|
+
# Editors / OS
|
|
28
|
+
.DS_Store
|
|
29
|
+
.idea/
|
|
30
|
+
.vscode/
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Commands
|
|
6
|
+
|
|
7
|
+
Backend (Python, managed with `uv`):
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
uv sync --extra dev # install deps incl. dev tools
|
|
11
|
+
uv run pytest # run the full test suite
|
|
12
|
+
uv run pytest tests/test_semantic_classifier.py # single file
|
|
13
|
+
uv run pytest tests/test_sessions.py::test_name -x # single test
|
|
14
|
+
uv run ruff check src tests # lint
|
|
15
|
+
uv run mypy # type-check (strict; checks src/ only)
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Frontend (React + Vite, in `web/`, managed with npm):
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
cd web
|
|
22
|
+
npm install
|
|
23
|
+
npm run dev # Vite dev server on :5173 (CORS-allowed by the API)
|
|
24
|
+
npm run build # tsc -b && vite build
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Run the app locally:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
uv run agent-roi ingest # collect logs from enabled tools, then classify
|
|
31
|
+
uv run agent-roi report --by tool --since 7d
|
|
32
|
+
uv run agent-roi serve # FastAPI on :8000 (serves built web UI if present)
|
|
33
|
+
uv run agent-roi doctor # which tools were detected, where, and what was found
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
During UI dev run `agent-roi serve` (API on :8000) and `npm run dev` (UI on :5173) together; the API allows the Vite origin via CORS.
|
|
37
|
+
|
|
38
|
+
## Release builds
|
|
39
|
+
|
|
40
|
+
The web UI is bundled into the Python package so `agent-roi serve` works after a plain install. The bundle lives at `src/agent_roi/webui/` — it is **gitignored** but listed as a hatch build artifact, so it must be regenerated before building a wheel:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
./scripts/build_web.sh # npm ci + build, then copy web/dist -> src/agent_roi/webui
|
|
44
|
+
uv build # wheel/sdist (includes the web UI)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Architecture
|
|
48
|
+
|
|
49
|
+
A local-first pipeline that turns the session logs AI coding tools already write into a per-topic view of token cost. Data never leaves the machine; everything is in one SQLite file.
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
Collectors ──▶ Storage ──▶ Classifier ──▶ Storage ──▶ Reports (CLI / API / Web)
|
|
53
|
+
(parse logs) (SQLite) (semantic) (topics)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
`core/service.py` (`Service`) is the single orchestration point wiring collectors → storage → classifier. **Both the CLI (`cli/main.py`, Typer) and the REST API (`api/app.py`, FastAPI) are thin layers over `Service`** — put logic in `Service`, not in either entry point. The API serves the built web UI as static files when present.
|
|
57
|
+
|
|
58
|
+
### Pipeline stages
|
|
59
|
+
|
|
60
|
+
1. **Collectors** (`collectors/`) — one `Collector` subclass per tool (Claude Code, Codex, Copilot, Gemini CLI). They parse local logs into normalized `Interaction` objects and are **read-only and idempotent**: each `Interaction.id` is stable, so re-running `ingest` upserts rather than double-counts. Collectors expose `is_available()`, `collect()`, plus diagnostics hooks (`search_paths()`, `count_files()`, `note()`) surfaced by `doctor`.
|
|
61
|
+
|
|
62
|
+
2. **Storage** (`storage/db.py`, `Database`) — SQLite via SQLAlchemy. Upserts interactions, computes per-interaction USD cost at write time from the pricing table, and does all aggregation (`rollup`, `topic_breakdown`, `sessions`, `session_detail`). Topic labels are stored on rows and cleared/rebuilt by classify.
|
|
63
|
+
|
|
64
|
+
3. **Classifier** (`classify/`) — **model-free, offline only**. The single provider is `semantic` (`classify/semantic.py`): TF-IDF + cosine-similarity clustering, no model weights, no API keys, no network. It classifies **whole sessions as a unit** (a session = one continuous piece of work) and applies the discovered topic to all of that session's rows, so cost can be aggregated *per subject* rather than per request. `classify()` defaults to `reclassify=True`, which wipes and rebuilds all topics to keep clustering globally consistent.
|
|
65
|
+
|
|
66
|
+
4. **Reports** — `Service.report(dimension=...)` aggregates by `topic | tool | model | project`, optionally time-windowed (`parse_since` accepts dates or shorthand like `7d`, `24h`, `today`). Drill into a topic with `topic_breakdown` (split by tool and model). Estimated token counts (tools that don't report usage) are badged distinctly from exact ones throughout CLI/API/UI.
|
|
67
|
+
|
|
68
|
+
### Core domain (`core/`)
|
|
69
|
+
|
|
70
|
+
`models.py` defines the canonical types — `Interaction` (the unit), `Rollup`, `TopicBreakdown`, `SessionSummary/Detail`, `CollectorStatus`. `pricing.py` is the per-model price table (USD per 1M tokens) behind every cost figure; surfaced verbatim by `agent-roi pricing` for trust. `platform.py` handles cross-platform log discovery (Windows/macOS/Linux + WSL where tools run on the Windows side) — use `find_tool_dirs(...)` from collectors. `config.py` loads `~/.config/agent-roi/config.toml` (override via `AGENT_ROI_CONFIG`); all fields have defaults so the tool works with zero config.
|
|
71
|
+
|
|
72
|
+
## Adding a collector
|
|
73
|
+
|
|
74
|
+
1. Create `collectors/<tool>.py` subclassing `Collector`; set `tool` and `name`.
|
|
75
|
+
2. Implement `is_available()` and `collect()`; use `core.platform.find_tool_dirs(...)` for log discovery so all platforms work.
|
|
76
|
+
3. Register it in `collectors/__init__.py` (and the default `collectors.enabled` list in `core/config.py` if it should be on by default).
|
|
77
|
+
|
|
78
|
+
See `docs/collectors.md` for the full guide.
|
|
79
|
+
|
|
80
|
+
## Conventions
|
|
81
|
+
|
|
82
|
+
- The frontend follows the design system in `design/DESIGN.md`; its tokens are mirrored as CSS variables in `web/src/index.css`. Read it before changing UI styles.
|
|
83
|
+
- Docs are bilingual: every `docs/*.md` (and `README.md`, `CONTRIBUTING.md`) has a `*.zh.md` translation — update both when changing docs.
|
|
84
|
+
- Python is `strict` mypy and ruff-linted (`E,F,I,UP,B,SIM`, line length 100).
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
|
2
|
+
|
|
3
|
+
## Our Pledge
|
|
4
|
+
|
|
5
|
+
We as members, contributors, and leaders pledge to make participation in our
|
|
6
|
+
community a harassment-free experience for everyone, regardless of age, body
|
|
7
|
+
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
|
8
|
+
identity and expression, level of experience, education, socio-economic status,
|
|
9
|
+
nationality, personal appearance, race, religion, or sexual identity and
|
|
10
|
+
orientation.
|
|
11
|
+
|
|
12
|
+
## Our Standards
|
|
13
|
+
|
|
14
|
+
Examples of behavior that contributes to a positive environment:
|
|
15
|
+
|
|
16
|
+
- Demonstrating empathy and kindness toward other people
|
|
17
|
+
- Being respectful of differing opinions, viewpoints, and experiences
|
|
18
|
+
- Giving and gracefully accepting constructive feedback
|
|
19
|
+
- Accepting responsibility and apologizing to those affected by our mistakes
|
|
20
|
+
|
|
21
|
+
Examples of unacceptable behavior:
|
|
22
|
+
|
|
23
|
+
- The use of sexualized language or imagery, and sexual attention or advances
|
|
24
|
+
- Trolling, insulting or derogatory comments, and personal or political attacks
|
|
25
|
+
- Public or private harassment
|
|
26
|
+
- Publishing others' private information without explicit permission
|
|
27
|
+
|
|
28
|
+
## Enforcement
|
|
29
|
+
|
|
30
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
|
31
|
+
reported to the project maintainers. All complaints will be reviewed and
|
|
32
|
+
investigated promptly and fairly.
|
|
33
|
+
|
|
34
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
|
35
|
+
version 2.1.
|
|
36
|
+
|
|
37
|
+
[homepage]: https://www.contributor-covenant.org
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Contributing to Agent-ROI
|
|
2
|
+
|
|
3
|
+
Thanks for your interest in improving Agent-ROI! This guide gets you set up and
|
|
4
|
+
explains how we work.
|
|
5
|
+
|
|
6
|
+
> 繁體中文版:[CONTRIBUTING.zh.md](./CONTRIBUTING.zh.md)
|
|
7
|
+
|
|
8
|
+
## Development setup
|
|
9
|
+
|
|
10
|
+
Agent-ROI has a Python backend (managed with [uv](https://docs.astral.sh/uv/))
|
|
11
|
+
and a React frontend (managed with npm).
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Backend
|
|
15
|
+
uv sync --extra dev
|
|
16
|
+
uv run pytest # run tests
|
|
17
|
+
uv run ruff check src # lint
|
|
18
|
+
uv run mypy # type-check
|
|
19
|
+
|
|
20
|
+
# Frontend
|
|
21
|
+
cd web
|
|
22
|
+
npm install
|
|
23
|
+
npm run build
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Project layout
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
src/agent_roi/
|
|
30
|
+
collectors/ # parse each tool's local logs -> Interaction
|
|
31
|
+
classify/ # model-free semantic topic discovery (TF-IDF + cosine clustering)
|
|
32
|
+
storage/ # SQLite persistence + aggregation
|
|
33
|
+
core/ # domain models, config, pricing, platform, service
|
|
34
|
+
api/ # FastAPI REST layer
|
|
35
|
+
cli/ # Typer command-line interface
|
|
36
|
+
web/ # React + Vite dashboard
|
|
37
|
+
design/ # DESIGN.md design system (Linear) — read before UI changes
|
|
38
|
+
docs/ # English docs (*.md) + Chinese translations (*.zh.md)
|
|
39
|
+
tests/ # pytest suite
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The frontend follows the design system in [`design/DESIGN.md`](./design/DESIGN.md)
|
|
43
|
+
(Notion). Its tokens are mirrored as CSS variables in `web/src/index.css`; read
|
|
44
|
+
it before changing UI styles so the look stays consistent.
|
|
45
|
+
|
|
46
|
+
### Building a release
|
|
47
|
+
|
|
48
|
+
The web UI is bundled into the Python package so `agent-roi serve` works after a
|
|
49
|
+
plain install. Before building a wheel:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
./scripts/build_web.sh # builds web/ and copies it into src/agent_roi/webui
|
|
53
|
+
uv build # produces the wheel/sdist (includes the web UI)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Adding a collector
|
|
57
|
+
|
|
58
|
+
A new tool integration is just a `Collector` subclass:
|
|
59
|
+
|
|
60
|
+
1. Create `src/agent_roi/collectors/<tool>.py` subclassing `Collector`.
|
|
61
|
+
2. Implement `is_available()` and `collect()` (see existing collectors).
|
|
62
|
+
3. Use `core.platform.find_tool_dirs(...)` to locate logs so Windows/macOS/Linux
|
|
63
|
+
and WSL all work.
|
|
64
|
+
4. Register it in `collectors/__init__.py`.
|
|
65
|
+
5. Add a fixture-based test under `tests/`.
|
|
66
|
+
|
|
67
|
+
See [docs/collectors.md](./docs/collectors.md) for the full guide.
|
|
68
|
+
|
|
69
|
+
## Pull requests
|
|
70
|
+
|
|
71
|
+
- Keep PRs focused; one logical change per PR.
|
|
72
|
+
- Add or update tests for behavior changes.
|
|
73
|
+
- Run `uv run ruff check src tests` and `uv run pytest` before pushing.
|
|
74
|
+
- Update both the English doc and its `.zh.md` translation when changing docs.
|
|
75
|
+
|
|
76
|
+
## Code of Conduct
|
|
77
|
+
|
|
78
|
+
By participating you agree to our [Code of Conduct](./CODE_OF_CONDUCT.md).
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# 貢獻 Agent-ROI
|
|
2
|
+
|
|
3
|
+
感謝你有興趣改善 Agent-ROI!本指南帶你完成環境設定,並說明我們的協作方式。
|
|
4
|
+
|
|
5
|
+
> English version: [CONTRIBUTING.md](./CONTRIBUTING.md)
|
|
6
|
+
|
|
7
|
+
## 開發環境設定
|
|
8
|
+
|
|
9
|
+
Agent-ROI 有一個 Python 後端(以 [uv](https://docs.astral.sh/uv/) 管理)與一個
|
|
10
|
+
React 前端(以 npm 管理)。
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
# 後端
|
|
14
|
+
uv sync --extra dev
|
|
15
|
+
uv run pytest # 跑測試
|
|
16
|
+
uv run ruff check src # lint
|
|
17
|
+
uv run mypy # 型別檢查
|
|
18
|
+
|
|
19
|
+
# 前端
|
|
20
|
+
cd web
|
|
21
|
+
npm install
|
|
22
|
+
npm run build
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## 專案結構
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
src/agent_roi/
|
|
29
|
+
collectors/ # 解析各工具的本地 log -> Interaction
|
|
30
|
+
classify/ # 免模型的語意主題歸納(TF-IDF + 餘弦相似度分群)
|
|
31
|
+
storage/ # SQLite 持久化 + 彙總
|
|
32
|
+
core/ # 領域模型、設定、定價、平台、服務
|
|
33
|
+
api/ # FastAPI REST 層
|
|
34
|
+
cli/ # Typer 命令列介面
|
|
35
|
+
web/ # React + Vite 儀表板
|
|
36
|
+
design/ # DESIGN.md 設計系統(Linear)— 改 UI 前請先閱讀
|
|
37
|
+
docs/ # 英文文件 (*.md) + 中文翻譯 (*.zh.md)
|
|
38
|
+
tests/ # pytest 測試
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
前端遵循 [`design/DESIGN.md`](./design/DESIGN.md)(Notion)的設計系統。其 token 已
|
|
42
|
+
鏡射為 `web/src/index.css` 的 CSS 變數;改動 UI 樣式前請先閱讀,讓外觀維持一致。
|
|
43
|
+
|
|
44
|
+
### 建置發佈版本
|
|
45
|
+
|
|
46
|
+
web UI 會被打包進 Python 套件,讓一般安裝後 `agent-roi serve` 也能運作。建置 wheel 前:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
./scripts/build_web.sh # 建置 web/ 並複製進 src/agent_roi/webui
|
|
50
|
+
uv build # 產生 wheel/sdist(含 web UI)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## 新增採集器
|
|
54
|
+
|
|
55
|
+
新的工具整合就是一個 `Collector` 子類:
|
|
56
|
+
|
|
57
|
+
1. 建立 `src/agent_roi/collectors/<tool>.py`,繼承 `Collector`。
|
|
58
|
+
2. 實作 `is_available()` 與 `collect()`(參考既有採集器)。
|
|
59
|
+
3. 使用 `core.platform.find_tool_dirs(...)` 定位 log,讓 Windows/macOS/Linux 與
|
|
60
|
+
WSL 都能運作。
|
|
61
|
+
4. 在 `collectors/__init__.py` 中註冊。
|
|
62
|
+
5. 在 `tests/` 下新增以 fixture 為基礎的測試。
|
|
63
|
+
|
|
64
|
+
完整指南見 [docs/collectors.zh.md](./docs/collectors.zh.md)。
|
|
65
|
+
|
|
66
|
+
## Pull Request
|
|
67
|
+
|
|
68
|
+
- 保持 PR 聚焦;一個 PR 一個邏輯變更。
|
|
69
|
+
- 行為變更請新增或更新測試。
|
|
70
|
+
- push 前請執行 `uv run ruff check src tests` 與 `uv run pytest`。
|
|
71
|
+
- 變更文件時,請同時更新英文文件與其 `.zh.md` 翻譯。
|
|
72
|
+
|
|
73
|
+
## 行為準則
|
|
74
|
+
|
|
75
|
+
參與本專案即表示你同意我們的[行為準則](./CODE_OF_CONDUCT.md)。
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Agent-ROI contributors
|
|
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.
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agent-roi-tracker
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Track the cost, usage, and ROI of your AI coding agents across every tool.
|
|
5
|
+
Project-URL: Homepage, https://github.com/Agent-ROI/agent-roi
|
|
6
|
+
Project-URL: Repository, https://github.com/Agent-ROI/agent-roi
|
|
7
|
+
Project-URL: Issues, https://github.com/Agent-ROI/agent-roi/issues
|
|
8
|
+
Author: Agent-ROI contributors
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: ai,claude,codex,cost,llm,observability,roi,tokens
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
17
|
+
Requires-Python: >=3.10
|
|
18
|
+
Requires-Dist: fastapi>=0.111
|
|
19
|
+
Requires-Dist: httpx>=0.27
|
|
20
|
+
Requires-Dist: platformdirs>=4.2
|
|
21
|
+
Requires-Dist: pydantic-settings>=2.3
|
|
22
|
+
Requires-Dist: pydantic>=2.7
|
|
23
|
+
Requires-Dist: rich>=13.7
|
|
24
|
+
Requires-Dist: sqlalchemy>=2.0
|
|
25
|
+
Requires-Dist: tomli>=2.0; python_version < '3.11'
|
|
26
|
+
Requires-Dist: typer>=0.12
|
|
27
|
+
Requires-Dist: uvicorn[standard]>=0.30
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
30
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
31
|
+
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
|
|
32
|
+
Requires-Dist: pytest>=8.2; extra == 'dev'
|
|
33
|
+
Requires-Dist: ruff>=0.5; extra == 'dev'
|
|
34
|
+
Description-Content-Type: text/markdown
|
|
35
|
+
|
|
36
|
+
<div align="center">
|
|
37
|
+
|
|
38
|
+
# Agent-ROI
|
|
39
|
+
|
|
40
|
+
**Track the cost, usage, and ROI of your AI coding agents — across every tool.**
|
|
41
|
+
|
|
42
|
+
[](LICENSE)
|
|
43
|
+
[](https://www.python.org/downloads/)
|
|
44
|
+
[](https://github.com/Agent-ROI/agent-roi/actions/workflows/ci.yml)
|
|
45
|
+
|
|
46
|
+
[English](./README.md) · [繁體中文](./README.zh.md)
|
|
47
|
+
|
|
48
|
+
</div>
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## What is Agent-ROI?
|
|
53
|
+
|
|
54
|
+
When you use multiple AI coding tools — Claude Code, Codex CLI, GitHub Copilot, Cursor, and others — your token spend is scattered everywhere and impossible to evaluate. **Agent-ROI** unifies all of it.
|
|
55
|
+
|
|
56
|
+
It reads the local session logs each tool already writes, uses a **model-free semantic classifier** to discover *what topic / task* each session was about, and then shows you **how many tokens each topic consumed** — so you can measure the **return on investment** of your agents, not just raw token counts.
|
|
57
|
+
|
|
58
|
+
> The core question Agent-ROI answers: *"For this feature / bug / topic, how many tokens did my agents burn — and was it worth it?"*
|
|
59
|
+
|
|
60
|
+
## Features
|
|
61
|
+
|
|
62
|
+
- 🔌 **Tool-agnostic collectors** — parse local logs from Claude Code, Codex CLI, GitHub Copilot, and Gemini CLI (no proxy, no workflow change).
|
|
63
|
+
- 🧠 **Topic classification** — a model-free semantic classifier groups sessions by topic so you see cost *per subject*, not per request. Runs fully offline, costs nothing, requires no external service.
|
|
64
|
+
- 💰 **Cost & ROI tracking** — token usage mapped to per-model pricing, aggregated by **topic, tool, or model**, over a **custom time window**.
|
|
65
|
+
- 🔎 **Drill-down & trust** — click any topic to see which tools and models its tokens came from; every figure is backed by a **viewable pricing table**, and estimated numbers are clearly badged vs exact ones.
|
|
66
|
+
- 🖥️ **CLI** — `report`, per-topic drill-down, and a `pricing` command straight from the terminal.
|
|
67
|
+
- 🌐 **Web UI** — a modern React dashboard with dimension/time controls, breakdowns, and drill-downs.
|
|
68
|
+
- 🗄️ **Local-first** — everything stays on your machine (SQLite); fully offline; classification never sends data anywhere.
|
|
69
|
+
|
|
70
|
+
## Architecture
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
|
74
|
+
│ Collectors │──▶│ Classifier │──▶│ Storage │
|
|
75
|
+
│ (parse logs) │ │ (semantic) │ │ (SQLite) │
|
|
76
|
+
└──────────────┘ └──────────────┘ └──────┬───────┘
|
|
77
|
+
│
|
|
78
|
+
┌──────────────────┼──────────────────┐
|
|
79
|
+
▼ ▼
|
|
80
|
+
┌────────────┐ ┌────────────┐
|
|
81
|
+
│ CLI │ │ REST API │──▶ Web UI (React)
|
|
82
|
+
└────────────┘ └────────────┘
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
See [docs/architecture.md](./docs/architecture.md) for details.
|
|
86
|
+
|
|
87
|
+
## Install
|
|
88
|
+
|
|
89
|
+
One line (macOS / Linux / WSL). Installs `uv` if needed, then the `agent-roi` command:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
curl -LsSf https://raw.githubusercontent.com/Agent-ROI/agent-roi/main/scripts/install.sh | sh
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
<details>
|
|
96
|
+
<summary>Other ways to install</summary>
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
# With pipx
|
|
100
|
+
pipx install agent-roi
|
|
101
|
+
|
|
102
|
+
# With uv
|
|
103
|
+
uv tool install agent-roi
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
To install the latest from source before a release is published, set
|
|
107
|
+
`AGENT_ROI_FROM_GIT=1` before running the install script.
|
|
108
|
+
</details>
|
|
109
|
+
|
|
110
|
+
## Quick Start
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
# Ingest logs from all detected tools
|
|
114
|
+
agent-roi ingest
|
|
115
|
+
|
|
116
|
+
# Discover topics from your sessions (model-free, fully local)
|
|
117
|
+
agent-roi classify
|
|
118
|
+
|
|
119
|
+
# Cost breakdown — group by topic, tool, or model, over a time window
|
|
120
|
+
agent-roi report --by tool --since 7d
|
|
121
|
+
|
|
122
|
+
# Drill into one topic: which tools/models did its tokens come from?
|
|
123
|
+
agent-roi topic "auth refactor"
|
|
124
|
+
|
|
125
|
+
# Inspect the pricing table behind every cost figure
|
|
126
|
+
agent-roi pricing
|
|
127
|
+
|
|
128
|
+
# Launch the web dashboard (API + React UI), then open http://127.0.0.1:8000
|
|
129
|
+
agent-roi serve
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
> Developing Agent-ROI itself? See [CONTRIBUTING.md](./CONTRIBUTING.md) — local
|
|
133
|
+
> dev uses `uv` and runs the frontend on a separate Vite dev server.
|
|
134
|
+
|
|
135
|
+
## Configuration
|
|
136
|
+
|
|
137
|
+
Agent-ROI looks for config at `~/.config/agent-roi/config.toml`. See [docs/configuration.md](./docs/configuration.md).
|
|
138
|
+
|
|
139
|
+
```toml
|
|
140
|
+
[classifier]
|
|
141
|
+
similarity_threshold = 0.18 # higher = more, smaller topics
|
|
142
|
+
label_terms = 3 # words used to name each topic
|
|
143
|
+
|
|
144
|
+
[collectors]
|
|
145
|
+
enabled = ["claude_code", "codex", "copilot", "gemini"]
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Documentation
|
|
149
|
+
|
|
150
|
+
| Doc | English | 繁體中文 |
|
|
151
|
+
|-----|---------|----------|
|
|
152
|
+
| Architecture | [architecture.md](./docs/architecture.md) | [architecture.zh.md](./docs/architecture.zh.md) |
|
|
153
|
+
| Configuration | [configuration.md](./docs/configuration.md) | [configuration.zh.md](./docs/configuration.zh.md) |
|
|
154
|
+
| Collectors | [collectors.md](./docs/collectors.md) | [collectors.zh.md](./docs/collectors.zh.md) |
|
|
155
|
+
| Contributing | [CONTRIBUTING.md](./CONTRIBUTING.md) | [CONTRIBUTING.zh.md](./CONTRIBUTING.zh.md) |
|
|
156
|
+
|
|
157
|
+
## Contributing
|
|
158
|
+
|
|
159
|
+
Contributions are welcome! Please read [CONTRIBUTING.md](./CONTRIBUTING.md) and our [Code of Conduct](./CODE_OF_CONDUCT.md).
|
|
160
|
+
|
|
161
|
+
## License
|
|
162
|
+
|
|
163
|
+
[MIT](./LICENSE) © Agent-ROI contributors
|