ai-spend-tracker 0.2.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.
- ai_spend_tracker-0.2.0/LICENSE +21 -0
- ai_spend_tracker-0.2.0/PKG-INFO +132 -0
- ai_spend_tracker-0.2.0/README.md +107 -0
- ai_spend_tracker-0.2.0/ai_spend_tracker/__init__.py +0 -0
- ai_spend_tracker-0.2.0/ai_spend_tracker/collectors/__init__.py +104 -0
- ai_spend_tracker-0.2.0/ai_spend_tracker/collectors/base.py +104 -0
- ai_spend_tracker-0.2.0/ai_spend_tracker/collectors/claude_code.py +273 -0
- ai_spend_tracker-0.2.0/ai_spend_tracker/collectors/codex.py +128 -0
- ai_spend_tracker-0.2.0/ai_spend_tracker/collectors/copilot.py +225 -0
- ai_spend_tracker-0.2.0/ai_spend_tracker/collectors/hermes.py +124 -0
- ai_spend_tracker-0.2.0/ai_spend_tracker/collectors/kimi.py +233 -0
- ai_spend_tracker-0.2.0/ai_spend_tracker/collectors/openclaw.py +255 -0
- ai_spend_tracker-0.2.0/ai_spend_tracker/collectors/opencode.py +252 -0
- ai_spend_tracker-0.2.0/ai_spend_tracker/config.py +259 -0
- ai_spend_tracker-0.2.0/ai_spend_tracker/demo.py +119 -0
- ai_spend_tracker-0.2.0/ai_spend_tracker/display.py +186 -0
- ai_spend_tracker-0.2.0/ai_spend_tracker/main.py +255 -0
- ai_spend_tracker-0.2.0/ai_spend_tracker/models.py +65 -0
- ai_spend_tracker-0.2.0/ai_spend_tracker.egg-info/PKG-INFO +132 -0
- ai_spend_tracker-0.2.0/ai_spend_tracker.egg-info/SOURCES.txt +24 -0
- ai_spend_tracker-0.2.0/ai_spend_tracker.egg-info/dependency_links.txt +1 -0
- ai_spend_tracker-0.2.0/ai_spend_tracker.egg-info/entry_points.txt +2 -0
- ai_spend_tracker-0.2.0/ai_spend_tracker.egg-info/requires.txt +1 -0
- ai_spend_tracker-0.2.0/ai_spend_tracker.egg-info/top_level.txt +1 -0
- ai_spend_tracker-0.2.0/pyproject.toml +45 -0
- ai_spend_tracker-0.2.0/setup.cfg +4 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 vick
|
|
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,132 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ai-spend-tracker
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Aggregate token usage & cost across all your AI coding agents (Hermes, Codex, Claude Code, Copilot, OpenCode, OpenClaw, Kimi)
|
|
5
|
+
Author: vick
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/vick/ai-spend-tracker
|
|
8
|
+
Project-URL: Repository, https://github.com/vick/ai-spend-tracker
|
|
9
|
+
Project-URL: Bug Tracker, https://github.com/vick/ai-spend-tracker/issues
|
|
10
|
+
Keywords: token-usage,cost-tracking,ai-coding-agent,claude-code,opencode
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Utilities
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
Requires-Dist: rich>=13.0.0
|
|
25
|
+
|
|
26
|
+
# AI Spend Tracker
|
|
27
|
+
|
|
28
|
+
**Aggregate token usage & cost across all your AI coding agents in one CLI.**
|
|
29
|
+
|
|
30
|
+
If you run multiple AI coding tools (Claude Code, Codex, Hermes, OpenClaw, OpenCode, GitHub Copilot, Kimi), you're probably flying blind on how much you're actually spending. AI Spend Tracker reads session data from every agent's local storage and shows you the big picture.
|
|
31
|
+
|
|
32
|
+
## Features
|
|
33
|
+
|
|
34
|
+
- **7 built-in collectors** — Hermes Agent, Codex CLI, GitHub Copilot CLI, OpenCode, Claude Code, OpenClaw, Kimi Code CLI
|
|
35
|
+
- **Cross-platform** — Windows (native + WSL), Linux, macOS
|
|
36
|
+
- **Multi-agent aggregation** — all agents in one report
|
|
37
|
+
- **Extensible** — drop a custom collector in `~/.ai-spend/collectors/`
|
|
38
|
+
- **Path override** — manual data source path via `~/.ai-spend/config.json`
|
|
39
|
+
- **Rich terminal output** — agent summary, model breakdown, daily trends
|
|
40
|
+
- **JSON output** — pipe data into your own dashboards
|
|
41
|
+
|
|
42
|
+
## Supported Agents
|
|
43
|
+
|
|
44
|
+
| Collector | Agent | Data Source |
|
|
45
|
+
|-----------|-------|-------------|
|
|
46
|
+
| `hermes` | Hermes Agent (Nous Research) | `~/.hermes/state.db` |
|
|
47
|
+
| `codex` | OpenAI Codex CLI | `~/.codex/state_*.sqlite` |
|
|
48
|
+
| `copilot` | GitHub Copilot CLI | `~/.copilot/session-store.db` |
|
|
49
|
+
| `opencode` | OpenCode CLI | `~/.local/share/opencode/opencode.db` |
|
|
50
|
+
| `claude-code` | Claude Code (Anthropic) | `~/.claude/projects/*.jsonl` |
|
|
51
|
+
| `openclaw` | OpenClaw | `~/.openclaw/agents/*/sessions/*.jsonl` |
|
|
52
|
+
| `kimi` | Kimi Code CLI (Moonshot AI) | `~/.kimi/sessions/*/*/wire.jsonl` |
|
|
53
|
+
|
|
54
|
+
> Note: Claude Code v2.1.140+ may not persist session logs to disk. See [anthropics/claude-code#25941](https://github.com/anthropics/claude-code/issues/25941).
|
|
55
|
+
|
|
56
|
+
## Quick Start
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
# Install
|
|
60
|
+
pip install ai-spend-tracker
|
|
61
|
+
|
|
62
|
+
# See your usage for the last 7 days
|
|
63
|
+
ai-spend
|
|
64
|
+
|
|
65
|
+
# List available data sources
|
|
66
|
+
ai-spend --list-agents
|
|
67
|
+
|
|
68
|
+
# See only Hermes data
|
|
69
|
+
ai-spend --agent hermes
|
|
70
|
+
|
|
71
|
+
# All historical data (no time limit)
|
|
72
|
+
ai-spend --days 0
|
|
73
|
+
|
|
74
|
+
# JSON output
|
|
75
|
+
ai-spend --format json
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Usage
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
ai-spend [options]
|
|
82
|
+
|
|
83
|
+
Options:
|
|
84
|
+
--list-agents List all available data collectors
|
|
85
|
+
--init [name] Initialize ~/.ai-spend/ directory
|
|
86
|
+
--agent AGENT Filter by agent name (comma-separated)
|
|
87
|
+
--days DAYS Days to look back (default: 7, 0 = all time)
|
|
88
|
+
--since YYYY-MM-DD Start date
|
|
89
|
+
--until YYYY-MM-DD End date
|
|
90
|
+
--format {table,json} Output format (default: table)
|
|
91
|
+
--demo Show sample data (no real agents needed)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Path Override
|
|
95
|
+
|
|
96
|
+
If auto-detection fails, manually specify data source paths:
|
|
97
|
+
|
|
98
|
+
```json
|
|
99
|
+
// ~/.ai-spend/config.json
|
|
100
|
+
{"paths": {
|
|
101
|
+
"hermes": "D:/custom/hermes/state.db",
|
|
102
|
+
"codex": "C:/Users/me/.codex/state_1.sqlite",
|
|
103
|
+
"copilot": "D:/copilot/session-store.db",
|
|
104
|
+
"opencode": "D:/opencode/opencode.db",
|
|
105
|
+
"claude-code": "D:/claude/projects",
|
|
106
|
+
"openclaw": "D:/.openclaw",
|
|
107
|
+
"kimi": "D:/.kimi"
|
|
108
|
+
}}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Custom Collectors
|
|
112
|
+
|
|
113
|
+
Create your own collector in `~/.ai-spend/collectors/`:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
ai-spend init my-agent
|
|
117
|
+
# Edit ~/.ai-spend/collectors/my-agent.py
|
|
118
|
+
# Implement BaseCollector.name(), display_name(), collect()
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Platform Support
|
|
122
|
+
|
|
123
|
+
| Platform | Status |
|
|
124
|
+
|----------|--------|
|
|
125
|
+
| Linux | ✅ Full |
|
|
126
|
+
| macOS | ✅ Full |
|
|
127
|
+
| Windows (native) | ✅ Full |
|
|
128
|
+
| Windows (WSL) | ✅ Full |
|
|
129
|
+
|
|
130
|
+
## License
|
|
131
|
+
|
|
132
|
+
MIT
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# AI Spend Tracker
|
|
2
|
+
|
|
3
|
+
**Aggregate token usage & cost across all your AI coding agents in one CLI.**
|
|
4
|
+
|
|
5
|
+
If you run multiple AI coding tools (Claude Code, Codex, Hermes, OpenClaw, OpenCode, GitHub Copilot, Kimi), you're probably flying blind on how much you're actually spending. AI Spend Tracker reads session data from every agent's local storage and shows you the big picture.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **7 built-in collectors** — Hermes Agent, Codex CLI, GitHub Copilot CLI, OpenCode, Claude Code, OpenClaw, Kimi Code CLI
|
|
10
|
+
- **Cross-platform** — Windows (native + WSL), Linux, macOS
|
|
11
|
+
- **Multi-agent aggregation** — all agents in one report
|
|
12
|
+
- **Extensible** — drop a custom collector in `~/.ai-spend/collectors/`
|
|
13
|
+
- **Path override** — manual data source path via `~/.ai-spend/config.json`
|
|
14
|
+
- **Rich terminal output** — agent summary, model breakdown, daily trends
|
|
15
|
+
- **JSON output** — pipe data into your own dashboards
|
|
16
|
+
|
|
17
|
+
## Supported Agents
|
|
18
|
+
|
|
19
|
+
| Collector | Agent | Data Source |
|
|
20
|
+
|-----------|-------|-------------|
|
|
21
|
+
| `hermes` | Hermes Agent (Nous Research) | `~/.hermes/state.db` |
|
|
22
|
+
| `codex` | OpenAI Codex CLI | `~/.codex/state_*.sqlite` |
|
|
23
|
+
| `copilot` | GitHub Copilot CLI | `~/.copilot/session-store.db` |
|
|
24
|
+
| `opencode` | OpenCode CLI | `~/.local/share/opencode/opencode.db` |
|
|
25
|
+
| `claude-code` | Claude Code (Anthropic) | `~/.claude/projects/*.jsonl` |
|
|
26
|
+
| `openclaw` | OpenClaw | `~/.openclaw/agents/*/sessions/*.jsonl` |
|
|
27
|
+
| `kimi` | Kimi Code CLI (Moonshot AI) | `~/.kimi/sessions/*/*/wire.jsonl` |
|
|
28
|
+
|
|
29
|
+
> Note: Claude Code v2.1.140+ may not persist session logs to disk. See [anthropics/claude-code#25941](https://github.com/anthropics/claude-code/issues/25941).
|
|
30
|
+
|
|
31
|
+
## Quick Start
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# Install
|
|
35
|
+
pip install ai-spend-tracker
|
|
36
|
+
|
|
37
|
+
# See your usage for the last 7 days
|
|
38
|
+
ai-spend
|
|
39
|
+
|
|
40
|
+
# List available data sources
|
|
41
|
+
ai-spend --list-agents
|
|
42
|
+
|
|
43
|
+
# See only Hermes data
|
|
44
|
+
ai-spend --agent hermes
|
|
45
|
+
|
|
46
|
+
# All historical data (no time limit)
|
|
47
|
+
ai-spend --days 0
|
|
48
|
+
|
|
49
|
+
# JSON output
|
|
50
|
+
ai-spend --format json
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Usage
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
ai-spend [options]
|
|
57
|
+
|
|
58
|
+
Options:
|
|
59
|
+
--list-agents List all available data collectors
|
|
60
|
+
--init [name] Initialize ~/.ai-spend/ directory
|
|
61
|
+
--agent AGENT Filter by agent name (comma-separated)
|
|
62
|
+
--days DAYS Days to look back (default: 7, 0 = all time)
|
|
63
|
+
--since YYYY-MM-DD Start date
|
|
64
|
+
--until YYYY-MM-DD End date
|
|
65
|
+
--format {table,json} Output format (default: table)
|
|
66
|
+
--demo Show sample data (no real agents needed)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Path Override
|
|
70
|
+
|
|
71
|
+
If auto-detection fails, manually specify data source paths:
|
|
72
|
+
|
|
73
|
+
```json
|
|
74
|
+
// ~/.ai-spend/config.json
|
|
75
|
+
{"paths": {
|
|
76
|
+
"hermes": "D:/custom/hermes/state.db",
|
|
77
|
+
"codex": "C:/Users/me/.codex/state_1.sqlite",
|
|
78
|
+
"copilot": "D:/copilot/session-store.db",
|
|
79
|
+
"opencode": "D:/opencode/opencode.db",
|
|
80
|
+
"claude-code": "D:/claude/projects",
|
|
81
|
+
"openclaw": "D:/.openclaw",
|
|
82
|
+
"kimi": "D:/.kimi"
|
|
83
|
+
}}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Custom Collectors
|
|
87
|
+
|
|
88
|
+
Create your own collector in `~/.ai-spend/collectors/`:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
ai-spend init my-agent
|
|
92
|
+
# Edit ~/.ai-spend/collectors/my-agent.py
|
|
93
|
+
# Implement BaseCollector.name(), display_name(), collect()
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Platform Support
|
|
97
|
+
|
|
98
|
+
| Platform | Status |
|
|
99
|
+
|----------|--------|
|
|
100
|
+
| Linux | ✅ Full |
|
|
101
|
+
| macOS | ✅ Full |
|
|
102
|
+
| Windows (native) | ✅ Full |
|
|
103
|
+
| Windows (WSL) | ✅ Full |
|
|
104
|
+
|
|
105
|
+
## License
|
|
106
|
+
|
|
107
|
+
MIT
|
|
File without changes
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CollectorRegistry — 自动发现并注册所有可用的数据采集器。
|
|
3
|
+
|
|
4
|
+
发现路径:
|
|
5
|
+
1. ai_spend_tracker/collectors/ 下的 .py 文件 → 内置 collector(正常 import)
|
|
6
|
+
2. ~/.ai-spend/collectors/ 下的 .py 文件 → 用户自定义 collector(file import)
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import importlib
|
|
12
|
+
import importlib.util
|
|
13
|
+
import inspect
|
|
14
|
+
import sys
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
from types import ModuleType
|
|
17
|
+
from typing import Optional
|
|
18
|
+
|
|
19
|
+
from ai_spend_tracker.collectors.base import BaseCollector
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _builtin_dir() -> Path:
|
|
23
|
+
return Path(__file__).parent.resolve()
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _user_dir() -> Path:
|
|
27
|
+
return Path.home() / ".ai-spend" / "collectors"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _import_user_module(file_path: Path) -> Optional[ModuleType]:
|
|
31
|
+
"""从文件路径导入用户自定义模块。"""
|
|
32
|
+
try:
|
|
33
|
+
module_name = f"_custom_collector_{file_path.stem}"
|
|
34
|
+
spec = importlib.util.spec_from_file_location(module_name, file_path)
|
|
35
|
+
if spec is None or spec.loader is None:
|
|
36
|
+
return None
|
|
37
|
+
module = importlib.util.module_from_spec(spec)
|
|
38
|
+
sys.modules[module_name] = module
|
|
39
|
+
spec.loader.exec_module(module)
|
|
40
|
+
return module
|
|
41
|
+
except Exception:
|
|
42
|
+
return None
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _find_collectors_in_module(
|
|
46
|
+
module: ModuleType, base_module: str = ""
|
|
47
|
+
) -> list[BaseCollector]:
|
|
48
|
+
"""在模块中找出所有 BaseCollector 的非抽象子类实例。"""
|
|
49
|
+
collectors: list[BaseCollector] = []
|
|
50
|
+
for _name, obj in inspect.getmembers(module, inspect.isclass):
|
|
51
|
+
if (
|
|
52
|
+
issubclass(obj, BaseCollector)
|
|
53
|
+
and obj is not BaseCollector
|
|
54
|
+
and not inspect.isabstract(obj)
|
|
55
|
+
):
|
|
56
|
+
try:
|
|
57
|
+
collectors.append(obj())
|
|
58
|
+
except Exception:
|
|
59
|
+
continue
|
|
60
|
+
return collectors
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def get_all_collectors() -> list[BaseCollector]:
|
|
64
|
+
"""返回所有可用的采集器(内置 + 用户自定义)。"""
|
|
65
|
+
collectors: list[BaseCollector] = []
|
|
66
|
+
|
|
67
|
+
# 1. 内置 collector — 通过正常 import 发现
|
|
68
|
+
builtin_dir = _builtin_dir()
|
|
69
|
+
if builtin_dir.exists():
|
|
70
|
+
for file_path in sorted(builtin_dir.iterdir()):
|
|
71
|
+
if (
|
|
72
|
+
not file_path.name.endswith(".py")
|
|
73
|
+
or file_path.name == "__init__.py"
|
|
74
|
+
or file_path.name == "base.py"
|
|
75
|
+
):
|
|
76
|
+
continue
|
|
77
|
+
module_name = f"ai_spend_tracker.collectors.{file_path.stem}"
|
|
78
|
+
try:
|
|
79
|
+
module = importlib.import_module(module_name)
|
|
80
|
+
collectors.extend(_find_collectors_in_module(module))
|
|
81
|
+
except Exception:
|
|
82
|
+
continue
|
|
83
|
+
|
|
84
|
+
# 2. 用户自定义 collector — 通过文件路径导入
|
|
85
|
+
user_dir = _user_dir()
|
|
86
|
+
if user_dir.exists():
|
|
87
|
+
for file_path in sorted(user_dir.iterdir()):
|
|
88
|
+
if (
|
|
89
|
+
not file_path.name.endswith(".py")
|
|
90
|
+
or file_path.name == "__init__.py"
|
|
91
|
+
):
|
|
92
|
+
continue
|
|
93
|
+
module = _import_user_module(file_path)
|
|
94
|
+
if module:
|
|
95
|
+
collectors.extend(_find_collectors_in_module(module))
|
|
96
|
+
|
|
97
|
+
return collectors
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def get_collector(name: str) -> Optional[BaseCollector]:
|
|
101
|
+
for c in get_all_collectors():
|
|
102
|
+
if c.name() == name:
|
|
103
|
+
return c
|
|
104
|
+
return None
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"""
|
|
2
|
+
BaseCollector — 所有数据采集器的抽象基类。
|
|
3
|
+
|
|
4
|
+
内置 collector 放在 ai_spend_tracker/collectors/ 下,
|
|
5
|
+
用户自定义 collector 放在 ~/.ai-spend/collectors/ 下,
|
|
6
|
+
两者都继承此类即可自动被 CollectorRegistry 发现。
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from abc import ABC, abstractmethod
|
|
12
|
+
from datetime import datetime
|
|
13
|
+
from typing import Optional
|
|
14
|
+
|
|
15
|
+
from ai_spend_tracker.models import SessionRecord
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# 常用模型定价表(USD per 1M input tokens)
|
|
19
|
+
# 用户自定义 collector 可以复用,也可以覆盖
|
|
20
|
+
DEFAULT_PRICING: dict[str, float] = {
|
|
21
|
+
# DeepSeek
|
|
22
|
+
"deepseek-v4-pro": 3.0,
|
|
23
|
+
"deepseek-v4-flash": 0.5,
|
|
24
|
+
"deepseek-v3.2": 2.0,
|
|
25
|
+
"deepseek-v3.1": 2.0,
|
|
26
|
+
"deepseek-v3": 2.0,
|
|
27
|
+
"deepseek-r1": 4.0,
|
|
28
|
+
# Qwen
|
|
29
|
+
"qwen3.7-max": 4.0,
|
|
30
|
+
"qwen3.6-max": 3.5,
|
|
31
|
+
"qwen3.5-plus": 2.0,
|
|
32
|
+
"qwen3.5-flash": 0.5,
|
|
33
|
+
"qwen-max": 4.0,
|
|
34
|
+
"qwen-plus": 2.0,
|
|
35
|
+
"qwen-turbo": 0.5,
|
|
36
|
+
"qwen3.5-omni-plus": 3.0,
|
|
37
|
+
# MiniMax
|
|
38
|
+
"MiniMax-M2.7": 3.0,
|
|
39
|
+
"MiniMax-M2.5": 2.0,
|
|
40
|
+
"MiniMax-M2.1": 1.0,
|
|
41
|
+
# Claude
|
|
42
|
+
"claude-sonnet-4-6": 15.0,
|
|
43
|
+
"claude-sonnet-4": 15.0,
|
|
44
|
+
"claude-opus-4": 15.0,
|
|
45
|
+
"claude-opus-4-8": 15.0,
|
|
46
|
+
"claude-sonnet-4.5": 15.0,
|
|
47
|
+
"claude-haiku-3.5": 1.0,
|
|
48
|
+
# Claude Code 内部模型别名
|
|
49
|
+
"claude-sonnet-4-8": 15.0,
|
|
50
|
+
"claude-opus-4-5": 15.0,
|
|
51
|
+
# GitHub Copilot(常见模型)
|
|
52
|
+
"gpt-5.4": 10.0,
|
|
53
|
+
"gpt-5.5": 15.0,
|
|
54
|
+
"gpt-5.1": 5.0,
|
|
55
|
+
"claude-sonnet-4.5": 15.0,
|
|
56
|
+
# Kimi (Moonshot AI)
|
|
57
|
+
"kimi-for-coding": 4.0,
|
|
58
|
+
"moonshot-k2.5": 4.0,
|
|
59
|
+
"moonshot-k2.6": 4.0,
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def estimate_cost(
|
|
64
|
+
input_tokens: int,
|
|
65
|
+
output_tokens: int,
|
|
66
|
+
model: str,
|
|
67
|
+
pricing: dict[str, float] | None = None,
|
|
68
|
+
output_multiplier: float = 4.0,
|
|
69
|
+
) -> float:
|
|
70
|
+
"""根据 token 用量和模型估算费用。"""
|
|
71
|
+
table = pricing if pricing is not None else DEFAULT_PRICING
|
|
72
|
+
price_per_1m_input = table.get(model, 2.0)
|
|
73
|
+
cost_input = input_tokens / 1_000_000 * price_per_1m_input
|
|
74
|
+
cost_output = output_tokens / 1_000_000 * price_per_1m_input * output_multiplier
|
|
75
|
+
return round(cost_input + cost_output, 6)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class BaseCollector(ABC):
|
|
79
|
+
"""所有数据采集器必须实现此接口。"""
|
|
80
|
+
|
|
81
|
+
@abstractmethod
|
|
82
|
+
def name(self) -> str:
|
|
83
|
+
"""采集器名称,如 'hermes'、'codex'、'my-agent'。"""
|
|
84
|
+
...
|
|
85
|
+
|
|
86
|
+
@abstractmethod
|
|
87
|
+
def display_name(self) -> str:
|
|
88
|
+
"""用户友好的显示名称,如 'Hermes Agent'、'Codex CLI'。"""
|
|
89
|
+
...
|
|
90
|
+
|
|
91
|
+
@abstractmethod
|
|
92
|
+
def collect(
|
|
93
|
+
self,
|
|
94
|
+
since: Optional[datetime] = None,
|
|
95
|
+
until: Optional[datetime] = None,
|
|
96
|
+
) -> list[SessionRecord]:
|
|
97
|
+
"""从数据源读取会话记录。"""
|
|
98
|
+
...
|
|
99
|
+
|
|
100
|
+
def description(self) -> str:
|
|
101
|
+
return self.display_name()
|
|
102
|
+
|
|
103
|
+
def pricing_table(self) -> dict[str, float]:
|
|
104
|
+
return DEFAULT_PRICING
|