qwencode-branch-stats 0.24.0.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.
- qwencode_branch_stats-0.24.0.0/LICENSE +21 -0
- qwencode_branch_stats-0.24.0.0/PKG-INFO +507 -0
- qwencode_branch_stats-0.24.0.0/README.md +480 -0
- qwencode_branch_stats-0.24.0.0/pyproject.toml +52 -0
- qwencode_branch_stats-0.24.0.0/setup.cfg +4 -0
- qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/__init__.py +4 -0
- qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/aggregation.py +265 -0
- qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/cli.py +140 -0
- qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/git.py +56 -0
- qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/hooks/__init__.py +2 -0
- qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/hooks/session_end.py +52 -0
- qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/mappings.py +87 -0
- qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/models.py +147 -0
- qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/qwen/__init__.py +2 -0
- qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/qwen/jsonl.py +37 -0
- qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/qwen/paths.py +42 -0
- qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/qwen/sessions.py +60 -0
- qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/qwen/settings.py +35 -0
- qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/qwen/subagents.py +72 -0
- qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/qwen/tools.py +100 -0
- qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/qwen/usage.py +71 -0
- qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/reports/__init__.py +2 -0
- qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/reports/json_report.py +19 -0
- qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/reports/markdown_report.py +142 -0
- qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats/service.py +72 -0
- qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats.egg-info/PKG-INFO +507 -0
- qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats.egg-info/SOURCES.txt +30 -0
- qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats.egg-info/dependency_links.txt +1 -0
- qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats.egg-info/entry_points.txt +3 -0
- qwencode_branch_stats-0.24.0.0/src/qwencode_branch_stats.egg-info/top_level.txt +1 -0
- qwencode_branch_stats-0.24.0.0/tests/test_qwencode_branch_stats.py +217 -0
- qwencode_branch_stats-0.24.0.0/tests/test_version.py +40 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 qwencode-branch-stats 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,507 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: qwencode-branch-stats
|
|
3
|
+
Version: 0.24.0.0
|
|
4
|
+
Summary: Local Qwen Code usage metrics by Git repository and branch
|
|
5
|
+
Author: qwencode-branch-stats contributors
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/helhrave/qwencode-branch-stats
|
|
8
|
+
Project-URL: Repository, https://github.com/helhrave/qwencode-branch-stats
|
|
9
|
+
Project-URL: Issues, https://github.com/helhrave/qwencode-branch-stats/issues
|
|
10
|
+
Keywords: qwen,qwen-code,cli,git,statistics,metrics
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
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 :: Only
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Topic :: Software Development
|
|
23
|
+
Requires-Python: >=3.10
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Dynamic: license-file
|
|
27
|
+
|
|
28
|
+
# qwencode-branch-stats
|
|
29
|
+
|
|
30
|
+
`qwencode-branch-stats` (краткое имя команды из консоли — `qbs`) —
|
|
31
|
+
кроссплатформенный CLI-инструмент на Python для расчёта
|
|
32
|
+
стоимости и метрик использования Qwen Code в разрезе Git-ветки.
|
|
33
|
+
|
|
34
|
+
## 1. Что делает приложение
|
|
35
|
+
|
|
36
|
+
Инструмент связывает завершённые Qwen Code sessions с текущими Git repository
|
|
37
|
+
и branch, читает локальную телеметрию Qwen, а затем создаёт два согласованных
|
|
38
|
+
отчёта:
|
|
39
|
+
|
|
40
|
+
- `report.md` — удобный отчёт для человека;
|
|
41
|
+
- `report.json` — те же данные в машиночитаемом виде.
|
|
42
|
+
|
|
43
|
+
В отчёте показываются:
|
|
44
|
+
|
|
45
|
+
- общая стоимость работы в ветке;
|
|
46
|
+
- стоимость, запросы и токены по моделям;
|
|
47
|
+
- стоимость по sessions, main agent и именам subagents;
|
|
48
|
+
- input, cached input, output и reasoning tokens;
|
|
49
|
+
- API duration, tool duration и subagent duration;
|
|
50
|
+
- вызовы обычных tools и MCP tools;
|
|
51
|
+
- количество и иерархия запусков subagents;
|
|
52
|
+
- предупреждения о неполных или повреждённых данных.
|
|
53
|
+
|
|
54
|
+
Одна ветка может включать несколько sessions, например «Исследование»,
|
|
55
|
+
«Реализация» и «Написание тестов». Одна session может использовать несколько
|
|
56
|
+
моделей.
|
|
57
|
+
|
|
58
|
+
Отчёты сохраняются в папку `.qbs/` в корне проекта и автоматически
|
|
59
|
+
обновляются при завершении каждой Qwen session (через `SessionEnd` hook).
|
|
60
|
+
Команду `qbs report` можно запускать в любой момент — она перестраивает те же
|
|
61
|
+
файлы заново из исходных данных.
|
|
62
|
+
|
|
63
|
+
### Пример отчёта
|
|
64
|
+
|
|
65
|
+
Фрагмент `report.md`:
|
|
66
|
+
|
|
67
|
+
```markdown
|
|
68
|
+
# feature/PROJ-1234-add-cache
|
|
69
|
+
|
|
70
|
+
Repository: my-project
|
|
71
|
+
Branch: feature/PROJ-1234-add-cache
|
|
72
|
+
Sessions: 3
|
|
73
|
+
Observation span: 2026-09-17T10:20:00Z — 2026-09-18T14:45:00Z
|
|
74
|
+
|
|
75
|
+
## Cost by model
|
|
76
|
+
|
|
77
|
+
| Model | Requests | Input | Cached | Output | Reasoning | Cost |
|
|
78
|
+
|---|---:|---:|---:|---:|---:|---:|
|
|
79
|
+
| routerai/deepseek/deepseek-v4-flash | 42 | 1,200,000 | 800,000 | 15,000 | 3,000 | 7.38 |
|
|
80
|
+
| routerai/qwen/qwen3.8-flash | 15 | 450,000 | 300,000 | 8,000 | 1,200 | 7.61 |
|
|
81
|
+
|
|
82
|
+
Total cost: 14.99
|
|
83
|
+
|
|
84
|
+
## Sessions
|
|
85
|
+
|
|
86
|
+
| Session | Title | Models | Requests | Input | Cached | Output | Reasoning | Cost |
|
|
87
|
+
|---|---|---|---:|---:|---:|---:|---:|---:|
|
|
88
|
+
| 18697f75… | Исследование архитектуры | deepseek-v4-flash | 17 | 410,000 | 250,000 | 6,000 | 1,200 | 3.41 |
|
|
89
|
+
| a1b2c3d4… | Реализация API | qwen3.8-flash | 28 | 870,000 | 590,000 | 12,000 | 2,000 | 8.17 |
|
|
90
|
+
| f9e8d7c6… | Написание тестов | deepseek-v4-flash, qwen3.8-flash | 12 | 370,000 | 260,000 | 5,000 | 1,000 | 3.41 |
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Кроме показанных таблиц, полный Markdown-отчёт содержит секции `Cost by agent`,
|
|
94
|
+
`Overall usage`, `Session details`, `Tools`, `MCP`, `Subagents` и
|
|
95
|
+
`Data quality / warnings`.
|
|
96
|
+
|
|
97
|
+
## 2. Как начать пользоваться
|
|
98
|
+
|
|
99
|
+
### Требования
|
|
100
|
+
|
|
101
|
+
- Python 3.10 или новее;
|
|
102
|
+
- Git, доступный через команду `git`;
|
|
103
|
+
- установленный и используемый Qwen Code;
|
|
104
|
+
- запуск команд внутри Git working tree.
|
|
105
|
+
|
|
106
|
+
### Версии
|
|
107
|
+
|
|
108
|
+
Версия инструмента имеет формат
|
|
109
|
+
`<версия Qwen Code, на которой код проверен>.<версия приложения>` —
|
|
110
|
+
например, `0.24.0.0`. Версия приложения начинается с `0` на каждой версии
|
|
111
|
+
Qwen Code. Подробности — в разделах [Версионирование](#4-версионирование) и
|
|
112
|
+
[Как обновить](#5-как-обновить).
|
|
113
|
+
|
|
114
|
+
### Установка
|
|
115
|
+
|
|
116
|
+
Из каталога с исходным кодом:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
python -m pip install .
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Проверка установки:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
qbs --version
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Шаг 1. Подключить SessionEnd hook
|
|
129
|
+
|
|
130
|
+
Настройте Qwen Code так, чтобы при завершении session он запускал команду:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
qbs hook session-end
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Hook должен получать JSON-событие Qwen через standard input. Инструмент
|
|
137
|
+
распознаёт идентификатор session в одном из вариантов:
|
|
138
|
+
|
|
139
|
+
```json
|
|
140
|
+
{"sessionId": "18697f75-6ead-472a-b700-18afb74ab2a2"}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
```json
|
|
144
|
+
{"session_id": "18697f75-6ead-472a-b700-18afb74ab2a2"}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
```json
|
|
148
|
+
{"session": {"id": "18697f75-6ead-472a-b700-18afb74ab2a2"}}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Точный синтаксис регистрации hook зависит от версии Qwen Code. В конфигурации
|
|
152
|
+
нужно указать команду выше для события `SessionEnd` и не менять рабочий каталог:
|
|
153
|
+
hook определяет repository и branch именно в момент завершения session.
|
|
154
|
+
|
|
155
|
+
Для ручной проверки из нужного Git-репозитория можно выполнить:
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
echo '{"sessionId":"18697f75-6ead-472a-b700-18afb74ab2a2"}' \
|
|
159
|
+
| qbs hook session-end
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Также идентификатор можно передать явно:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
qbs hook session-end \
|
|
166
|
+
--session-id 18697f75-6ead-472a-b700-18afb74ab2a2
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Шаг 2. Работать с Qwen Code
|
|
170
|
+
|
|
171
|
+
Работайте в Git-ветке как обычно. Для удобства последующего анализа задавайте
|
|
172
|
+
sessions понятные custom titles средствами Qwen Code, например:
|
|
173
|
+
|
|
174
|
+
- `Исследование архитектуры`;
|
|
175
|
+
- `Реализация API`;
|
|
176
|
+
- `Написание тестов`.
|
|
177
|
+
|
|
178
|
+
Если session переименовывалась несколько раз, в отчёт попадёт последнее
|
|
179
|
+
сохранённое custom title. Если title не задан, значение останется пустым —
|
|
180
|
+
`qwencode-branch-stats` не генерирует названия самостоятельно.
|
|
181
|
+
|
|
182
|
+
### Шаг 3. Проверить окружение
|
|
183
|
+
|
|
184
|
+
Из рабочей директории проекта:
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
qbs doctor
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Для машиночитаемого результата:
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
qbs doctor --json
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Команда проверяет Git-контекст, наличие каталога Qwen, `settings.json`, usage
|
|
197
|
+
files и число sessions, связанных с текущей веткой.
|
|
198
|
+
|
|
199
|
+
### Шаг 4. Построить отчёт
|
|
200
|
+
|
|
201
|
+
Из нужной Git-ветки выполните:
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
qbs report
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
По умолчанию отчёты сохраняются в папку `.qbs/` в текущем каталоге.
|
|
208
|
+
После подключения hook из шага 1 эти файлы также автоматически
|
|
209
|
+
пересоздаются при каждом завершении Qwen session — отдельный запуск команды
|
|
210
|
+
для этого не требуется:
|
|
211
|
+
|
|
212
|
+
```text
|
|
213
|
+
.qbs/
|
|
214
|
+
├── report.json
|
|
215
|
+
└── report.md
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Каталог вывода можно изменить параметром `--output-dir`:
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
qbs report --output-dir /path/to/reports
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Повторный запуск безопасен: отчёт заново строится из исходных данных Qwen.
|
|
225
|
+
Записи usage дедуплицируются по `usage.id`, а tool calls — по `call_id`, если
|
|
226
|
+
он присутствует.
|
|
227
|
+
|
|
228
|
+
### Нестандартное расположение данных
|
|
229
|
+
|
|
230
|
+
По умолчанию Qwen-артефакты читаются из `~/.qwen`. Путь можно изменить:
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
export QBS_QWEN_HOME=/path/to/qwen-data
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Также поддерживается переменная `QWEN_HOME`.
|
|
237
|
+
|
|
238
|
+
Расположение внутреннего хранилища связей session с Git можно изменить:
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
export QBS_DATA_DIR=/path/to/qbs-data
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Для разового запуска доступны параметры `--qwen-home` и `--data-dir`:
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
qbs report \
|
|
248
|
+
--qwen-home /path/to/qwen-data \
|
|
249
|
+
--data-dir /path/to/qbs-data
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
В Windows используйте синтаксис переменных окружения и путей, соответствующий
|
|
253
|
+
PowerShell или `cmd.exe`.
|
|
254
|
+
|
|
255
|
+
## 3. Как работает
|
|
256
|
+
|
|
257
|
+
### Общая схема
|
|
258
|
+
|
|
259
|
+
```text
|
|
260
|
+
Qwen Code session
|
|
261
|
+
│
|
|
262
|
+
│ SessionEnd
|
|
263
|
+
▼
|
|
264
|
+
session ID → repository → branch
|
|
265
|
+
│
|
|
266
|
+
│ qbs report или SessionEnd hook
|
|
267
|
+
▼
|
|
268
|
+
┌─────────────────────────────────────────┐
|
|
269
|
+
│ token usage + chats + subagents │
|
|
270
|
+
│ + model pricing │
|
|
271
|
+
└───────────────────┬─────────────────────┘
|
|
272
|
+
▼
|
|
273
|
+
нормализация и агрегация
|
|
274
|
+
│
|
|
275
|
+
┌──────┴──────┐
|
|
276
|
+
▼ ▼
|
|
277
|
+
report.json report.md
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### 3.1. Привязка session к Git-ветке
|
|
281
|
+
|
|
282
|
+
Команда `qbs hook session-end` получает session ID и запускает:
|
|
283
|
+
|
|
284
|
+
```bash
|
|
285
|
+
git rev-parse --show-toplevel
|
|
286
|
+
git branch --show-current
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
Полученная связь сохраняется локально:
|
|
290
|
+
|
|
291
|
+
```text
|
|
292
|
+
session ID + абсолютный путь repository + branch + captured_at
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
Абсолютный нормализованный путь позволяет различать репозитории с одинаковыми
|
|
296
|
+
названиями веток. Каждая session хранится в отдельном атомарно заменяемом файле,
|
|
297
|
+
поэтому несколько Qwen-процессов могут завершаться параллельно.
|
|
298
|
+
|
|
299
|
+
В сами отчёты в качестве repository попадает только название папки проекта —
|
|
300
|
+
папки, в которой находится `.git`. Полный путь используется лишь как внутренний
|
|
301
|
+
идентификатор в хранилище связей и в отчёт не записывается.
|
|
302
|
+
|
|
303
|
+
После сохранения связи хук автоматически перестраивает `report.json` и
|
|
304
|
+
`report.md` в папку `.qbs/` этого repository, поэтому отчёты актуальны сразу
|
|
305
|
+
после завершения session. Если построение отчёта не удалось, сохранённый
|
|
306
|
+
mapping не откатывается — текст ошибки выводится в stderr хука.
|
|
307
|
+
|
|
308
|
+
### 3.2. Поиск sessions для отчёта
|
|
309
|
+
|
|
310
|
+
При запуске `qbs report` инструмент снова определяет текущие repository
|
|
311
|
+
и branch, после чего выбирает только связанные с этой комбинацией завершённые
|
|
312
|
+
sessions.
|
|
313
|
+
|
|
314
|
+
Команда `qwen sessions list` не используется: все данные читаются напрямую из
|
|
315
|
+
локальных артефактов Qwen Code.
|
|
316
|
+
|
|
317
|
+
### 3.3. Источники данных
|
|
318
|
+
|
|
319
|
+
| Метрика | Источник |
|
|
320
|
+
|---|---|
|
|
321
|
+
| Repository и branch | SessionEnd hook + Git |
|
|
322
|
+
| Title и время session | `~/.qwen/projects/.../chats/<session-id>.jsonl` |
|
|
323
|
+
| Модели, токены и API duration | `~/.qwen/usage/token-usage-YYYY-MM.jsonl` |
|
|
324
|
+
| Цена моделей | `~/.qwen/settings.json` → `modelPricing` |
|
|
325
|
+
| Main tools и MCP | transcript основной session |
|
|
326
|
+
| Запуски и иерархия subagents | `subagents/<session-id>/*.meta.json` |
|
|
327
|
+
| Tools subagents | `subagents/<session-id>/*.jsonl` |
|
|
328
|
+
|
|
329
|
+
JSONL-файлы обрабатываются построчно. Сначала выполняется фильтрация по нужным
|
|
330
|
+
session IDs, поэтому большие usage и transcript files не загружаются целиком в
|
|
331
|
+
память.
|
|
332
|
+
|
|
333
|
+
### 3.4. Расчёт стоимости
|
|
334
|
+
|
|
335
|
+
Для каждого LLM request цена берётся из `settings.json` и рассчитывается так:
|
|
336
|
+
|
|
337
|
+
```text
|
|
338
|
+
input cost = inputTokens / 1 000 000 × inputPerMillionTokens
|
|
339
|
+
output cost = outputTokens / 1 000 000 × outputPerMillionTokens
|
|
340
|
+
cost = input cost + output cost
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
`cachedTokens` показываются отдельно, но при текущей структуре Qwen pricing не
|
|
344
|
+
имеют отдельного тарифа и уже входят в расчёт через `inputTokens`.
|
|
345
|
+
|
|
346
|
+
`thoughtsTokens` выводятся как reasoning tokens и не прибавляются повторно к
|
|
347
|
+
`outputTokens`.
|
|
348
|
+
|
|
349
|
+
Далее каждый request агрегируется по:
|
|
350
|
+
|
|
351
|
+
```text
|
|
352
|
+
session + model + agent → session → repository + branch
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
Если для хотя бы одной использованной модели нет pricing, её стоимость и
|
|
356
|
+
зависящие от неё общие суммы получают значение `null` в JSON и `unknown` в
|
|
357
|
+
Markdown. В отчёт также добавляется warning `pricing_missing` — частичная сумма
|
|
358
|
+
не выдаётся за полную.
|
|
359
|
+
|
|
360
|
+
### 3.5. Tools, MCP и subagents
|
|
361
|
+
|
|
362
|
+
Tool calls группируются по имени инструмента. Для каждого имени считаются:
|
|
363
|
+
|
|
364
|
+
- общее число вызовов;
|
|
365
|
+
- успешные и неуспешные вызовы;
|
|
366
|
+
- суммарная длительность.
|
|
367
|
+
|
|
368
|
+
Имена вида:
|
|
369
|
+
|
|
370
|
+
```text
|
|
371
|
+
mcp__gitlab__get_mcp_server_version
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
нормализуются в MCP server `gitlab` и tool `get_mcp_server_version`. MCP-вызовы
|
|
375
|
+
одновременно входят в общее число tool calls.
|
|
376
|
+
|
|
377
|
+
Запуски subagents считаются по metadata files. Поля `parentSessionId`,
|
|
378
|
+
`parentAgentId` и `depth` сохраняют иерархию вложенных агентов. Расходы LLM
|
|
379
|
+
агрегируются по значению `source`, например `main` или `general-purpose`.
|
|
380
|
+
|
|
381
|
+
### 3.6. Предупреждения и частичные данные
|
|
382
|
+
|
|
383
|
+
Отсутствие части данных не останавливает построение отчёта. Вместо этого в
|
|
384
|
+
`report.json` и `report.md` добавляются warnings, например:
|
|
385
|
+
|
|
386
|
+
- `pricing_missing`;
|
|
387
|
+
- `session_mapping_missing`;
|
|
388
|
+
- `transcript_missing`;
|
|
389
|
+
- `subagent_metadata_missing`;
|
|
390
|
+
- `malformed_jsonl`;
|
|
391
|
+
- `unknown_qwen_schema`.
|
|
392
|
+
|
|
393
|
+
Так можно получить доступные метрики и одновременно увидеть, какие значения
|
|
394
|
+
нельзя считать полными.
|
|
395
|
+
|
|
396
|
+
### 3.7. Приватность
|
|
397
|
+
|
|
398
|
+
В отчёты попадают только необходимые metadata и числовые метрики. Инструмент не
|
|
399
|
+
копирует исходные Qwen events целиком и не записывает в отчёты:
|
|
400
|
+
|
|
401
|
+
- prompts и ответы assistant;
|
|
402
|
+
- reasoning text;
|
|
403
|
+
- аргументы и результаты tools;
|
|
404
|
+
- shell-команды и их вывод;
|
|
405
|
+
- MCP payloads;
|
|
406
|
+
- содержимое файлов;
|
|
407
|
+
- API keys и credentials;
|
|
408
|
+
- полные пути repository на диске.
|
|
409
|
+
|
|
410
|
+
Разрешены session titles, названия моделей, agents и tools, MCP server/tool,
|
|
411
|
+
название папки проекта и Git branch, timestamps, statuses и числовые показатели.
|
|
412
|
+
|
|
413
|
+
## 4. Версионирование
|
|
414
|
+
|
|
415
|
+
Формат версии `qwencode-branch-stats`:
|
|
416
|
+
`<версия Qwen Code, на которой код проверен>.<версия приложения>`.
|
|
417
|
+
Например, версия `0.24.0.1` означает, что код протестирован с Qwen Code
|
|
418
|
+
`0.24.0` (`qwen --version`) и это второй релиз приложения на ней. Версия
|
|
419
|
+
приложения начинается с `0` на каждой версии Qwen Code и увеличивается на 1
|
|
420
|
+
при каждом следующем релизе на той же версии Qwen Code.
|
|
421
|
+
|
|
422
|
+
Совпадать должны три значения; четвёртое выводится из них:
|
|
423
|
+
|
|
424
|
+
| Место | Пример значения |
|
|
425
|
+
|----------------------------------------------------------|-------------------------------------|
|
|
426
|
+
| git tag репозитория | `0.24.0.0` |
|
|
427
|
+
| `version` в `[project]` внутри `pyproject.toml` | `0.24.0.0` |
|
|
428
|
+
| `__version__` в `src/qwencode_branch_stats/__init__.py` | `0.24.0.0` |
|
|
429
|
+
| вывод `qbs --version` | `qwencode-branch-stats 0.24.0.0` |
|
|
430
|
+
|
|
431
|
+
Версией Qwen Code, на которой проверен инструмент, является всё, кроме
|
|
432
|
+
последнего сегмента; последний сегмент — номер релиза приложения на ней.
|
|
433
|
+
`qbs doctor` помогает быстро проверить совместимость с окружением.
|
|
434
|
+
|
|
435
|
+
## 5. Как обновить
|
|
436
|
+
|
|
437
|
+
### После обновления Qwen Code
|
|
438
|
+
|
|
439
|
+
1. Узнайте версию Qwen Code:
|
|
440
|
+
|
|
441
|
+
```bash
|
|
442
|
+
qwen --version
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
2. Проверьте код на этой версии. Тесты:
|
|
446
|
+
|
|
447
|
+
```bash
|
|
448
|
+
python -m unittest discover -s tests -v
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
Затем прогоните одну реальную Qwen session и убедитесь, что SessionEnd
|
|
452
|
+
hook сохранил mapping и обновил `.qbs/report.md` и `.qbs/report.json`
|
|
453
|
+
с корректными метриками. Диагностика — `qbs doctor`.
|
|
454
|
+
|
|
455
|
+
3. Если проверка прошла, поднимите версию до `<версия Qwen Code>.0` в трёх
|
|
456
|
+
местах (git tag, `pyproject.toml`, `__version__`) — для Qwen Code
|
|
457
|
+
`0.25.0` это `0.25.0.0` — и переустановите пакет:
|
|
458
|
+
|
|
459
|
+
```bash
|
|
460
|
+
pip install --force-reinstall --no-deps .
|
|
461
|
+
qbs --version
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
4. Если parsers не разбирают артефакты новой версии Qwen Code (изменились
|
|
465
|
+
форматы usage, chats, subagents или `settings.json`), версию не
|
|
466
|
+
поднимайте: сначала почините разбор (`qwen/` и `aggregation.py`),
|
|
467
|
+
затем повторите проверку.
|
|
468
|
+
|
|
469
|
+
### Релиз приложения на той же версии Qwen Code
|
|
470
|
+
|
|
471
|
+
Если код меняется, а версия проверенного Qwen Code та же (`X`), растёт
|
|
472
|
+
только версия приложения: `X.N` → `X.N+1`. Например, второй релиз на
|
|
473
|
+
Qwen Code `0.24.0` — это `0.24.0.1`.
|
|
474
|
+
|
|
475
|
+
### Установка версии под конкретный Qwen Code
|
|
476
|
+
|
|
477
|
+
Релизы соответствуют git tag:
|
|
478
|
+
|
|
479
|
+
```bash
|
|
480
|
+
git checkout 0.24.0.0
|
|
481
|
+
pip install .
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
## Основные команды
|
|
485
|
+
|
|
486
|
+
```bash
|
|
487
|
+
# Зафиксировать Git-контекст завершённой session и обновить отчёты в .qbs/
|
|
488
|
+
qbs hook session-end
|
|
489
|
+
|
|
490
|
+
# Проверить окружение
|
|
491
|
+
qbs doctor
|
|
492
|
+
|
|
493
|
+
# Построить report.json и report.md (по умолчанию в .qbs/)
|
|
494
|
+
qbs report
|
|
495
|
+
|
|
496
|
+
# Показать версию
|
|
497
|
+
qbs --version
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
## Запуск тестов
|
|
501
|
+
|
|
502
|
+
Проект использует стандартный `unittest`, дополнительные test dependencies не
|
|
503
|
+
требуются:
|
|
504
|
+
|
|
505
|
+
```bash
|
|
506
|
+
python -m unittest discover -s tests -v
|
|
507
|
+
```
|