Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions docs/design/issue-4479-token-usage-stats-coordination.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Issue #4479 token usage stats coordination

## Context

Issue #4479 asks for daily Qwen Code token-consumption visibility. The scope was
clarified in the issue thread to prefer a CLI command, export support, monthly
summaries, and per-model token consumption. A maintainer comment also called out
coordination with adjacent statistics work:

- #4252: generation timing metrics in `/stats` such as TTFT, generation duration,
and TPS.
- #4182: content-free session-scale counters for memory diagnostics.

## Coordination decisions

1. **Use `/stats`, not a new top-level command.**
Token usage is exposed as `/stats daily`, `/stats monthly`, and
`/stats export` so it shares the existing statistics command surface with
session stats and future generation metrics.

2. **Persist token counters as local JSONL.**
Each API response appends one content-free record to
`usage/token-usage-YYYY-MM.jsonl` under the runtime directory. This satisfies
daily/monthly aggregation without adding SQLite as a new dependency.

3. **Keep #4252 timing semantics separate.**
Token usage summaries may include `apiDurationMs`, which is the existing
end-to-end API response duration from telemetry. It is deliberately named as
API duration and must not be presented as generation duration, TTFT, or TPS.
#4252 remains the owner for generation timing metrics.

4. **Keep #4182 privacy and memory-diagnostic boundaries.**
Usage records store aggregate counters and stable dimensions only: local date,
month, session id, model, auth type, source, token counters, and API duration.
They do not store prompt text, response text, tool content, project paths,
prompt ids, or response ids.

5. **Export remains aggregate-only.**
CSV and JSON exports are summaries, not raw transcript exports. They group by
total, model, auth type, model/auth type, and source.

## Non-goals

- Do not implement #4252's TTFT/TPS/generation-duration instrumentation here.
- Do not extend `/doctor memory` or implement #4182 in this change.
- Do not add a separate token-usage top-level slash command.
49 changes: 47 additions & 2 deletions packages/cli/src/i18n/locales/ca.js
Original file line number Diff line number Diff line change
Expand Up @@ -489,12 +489,57 @@ export default {
'Auto Edit': 'Edició automàtica',
YOLO: 'YOLO',
'toggle vim mode on/off': 'activar/desactivar el mode Vim',
'check session stats. Usage: /stats [model|tools]':
'comprovar les estadístiques de la sessió. Ús: /stats [model|tools]',
'Show model-specific usage statistics.':
"Mostrar les estadístiques d'ús específiques del model.",
'Show tool-specific usage statistics.':
"Mostrar les estadístiques d'ús específiques de les eines.",
'Show daily token usage statistics.':
"Mostrar les estadístiques diàries d'ús de tokens.",
'Show monthly token usage statistics.':
"Mostrar les estadístiques mensuals d'ús de tokens.",
'Export token usage statistics to CSV or JSON.':
"Exportar les estadístiques d'ús de tokens a CSV o JSON.",
'No usage data.': "No hi ha dades d'ús.",
'{{label}}: {{tokens}} tokens ({{requests}} requests)':
'{{label}}: {{tokens}} tokens ({{requests}} sol·licituds)',
'Daily token usage for {{value}}': 'Ús diari de tokens per a {{value}}',
'Monthly token usage for {{value}}': 'Ús mensual de tokens per a {{value}}',
'Total: {{tokens}} tokens': 'Total: {{tokens}} tokens',
'Requests: {{requests}}': 'Sol·licituds: {{requests}}',
'Breakdown:': 'Desglossament:',
'Input: {{tokens}}': 'Entrada: {{tokens}}',
'Output: {{tokens}}': 'Sortida: {{tokens}}',
'Cached (included in Input): {{tokens}}':
'Memòria cau (inclosa a l’entrada): {{tokens}}',
'Thoughts: {{tokens}}': 'Raonament: {{tokens}}',
'By model:': 'Per model:',
'By auth type:': "Per tipus d'autenticació:",
'By model/auth type:': "Per model/tipus d'autenticació:",
'By source:': 'Per origen:',
'Failed to load token usage stats: {{error}}':
"No s'han pogut carregar les estadístiques d'ús de tokens: {{error}}",
'Expected --format csv or --format json.':
"S'esperava --format csv o --format json.",
'Expected a file path after --output.':
"S'esperava una ruta de fitxer després de --output.",
'Unexpected argument: {{argument}}': 'Argument inesperat: {{argument}}',
'Usage: /stats export <daily|monthly> [YYYY-MM-DD|YYYY-MM] [--format csv|json] [--output path]':
'Ús: /stats export <daily|monthly> [YYYY-MM-DD|YYYY-MM] [--format csv|json] [--output path]',
'Token usage export path must be within the project working directory.':
"La ruta d'exportació de l'ús de tokens ha d'estar dins del directori de treball del projecte.",
'Export target does not exist: {{path}}':
"La destinació d'exportació no existeix: {{path}}",
'Cannot resolve export path within the working directory.':
"No s'ha pogut resoldre la ruta d'exportació dins del directori de treball.",
'Could not create a temporary export file.':
"No s'ha pogut crear un fitxer temporal d'exportació.",
'Token usage exported to {{format}}: {{path}}':
'Ús de tokens exportat a {{format}}: {{path}}',
'Failed to export token usage stats: {{error}}':
"No s'han pogut exportar les estadístiques d'ús de tokens: {{error}}",
'Unclosed quote in arguments.': 'Cometes sense tancar als arguments.',
'Note: generation timing (TTFT/TPS) belongs to generation metrics.':
'Nota: el temps de generació (TTFT/TPS) pertany a les mètriques de generació.',
'exit the cli': 'sortir del CLI',
'Manage workspace directories':
"Gestionar els directoris de l'espai de treball",
Expand Down
50 changes: 48 additions & 2 deletions packages/cli/src/i18n/locales/de.js
Original file line number Diff line number Diff line change
Expand Up @@ -420,12 +420,58 @@ export default {
'Auto Edit': 'Automatisch bearbeiten',
YOLO: 'YOLO',
'toggle vim mode on/off': 'Vim-Modus ein-/ausschalten',
'check session stats. Usage: /stats [model|tools]':
'Sitzungsstatistiken prüfen. Verwendung: /stats [model|tools]',
'Show model-specific usage statistics.':
'Modellspezifische Nutzungsstatistiken anzeigen.',
'Show tool-specific usage statistics.':
'Werkzeugspezifische Nutzungsstatistiken anzeigen.',
'Show daily token usage statistics.':
'Tägliche Token-Nutzungsstatistiken anzeigen.',
'Show monthly token usage statistics.':
'Monatliche Token-Nutzungsstatistiken anzeigen.',
'Export token usage statistics to CSV or JSON.':
'Token-Nutzungsstatistiken als CSV oder JSON exportieren.',
'No usage data.': 'Keine Nutzungsdaten.',
'{{label}}: {{tokens}} tokens ({{requests}} requests)':
'{{label}}: {{tokens}} Tokens ({{requests}} Anfragen)',
'Daily token usage for {{value}}': 'Tägliche Token-Nutzung für {{value}}',
'Monthly token usage for {{value}}': 'Monatliche Token-Nutzung für {{value}}',
'Total: {{tokens}} tokens': 'Gesamt: {{tokens}} Tokens',
'Requests: {{requests}}': 'Anfragen: {{requests}}',
'Breakdown:': 'Aufschlüsselung:',
'Input: {{tokens}}': 'Eingabe: {{tokens}}',
'Output: {{tokens}}': 'Ausgabe: {{tokens}}',
'Cached (included in Input): {{tokens}}':
'Cache (in Eingabe enthalten): {{tokens}}',
'Thoughts: {{tokens}}': 'Gedanken: {{tokens}}',
'By model:': 'Nach Modell:',
'By auth type:': 'Nach Authentifizierungstyp:',
'By model/auth type:': 'Nach Modell/Authentifizierungstyp:',
'By source:': 'Nach Quelle:',
'Failed to load token usage stats: {{error}}':
'Token-Nutzungsstatistiken konnten nicht geladen werden: {{error}}',
'Expected --format csv or --format json.':
'--format csv oder --format json erwartet.',
'Expected a file path after --output.':
'Nach --output wird ein Dateipfad erwartet.',
'Unexpected argument: {{argument}}': 'Unerwartetes Argument: {{argument}}',
'Usage: /stats export <daily|monthly> [YYYY-MM-DD|YYYY-MM] [--format csv|json] [--output path]':
'Verwendung: /stats export <daily|monthly> [YYYY-MM-DD|YYYY-MM] [--format csv|json] [--output path]',
'Token usage export path must be within the project working directory.':
'Der Exportpfad für die Token-Nutzung muss im Arbeitsverzeichnis des Projekts liegen.',
'Export target does not exist: {{path}}':
'Exportziel existiert nicht: {{path}}',
'Cannot resolve export path within the working directory.':
'Der Exportpfad kann nicht innerhalb des Arbeitsverzeichnisses aufgelöst werden.',
'Could not create a temporary export file.':
'Temporäre Exportdatei konnte nicht erstellt werden.',
'Token usage exported to {{format}}: {{path}}':
'Token-Nutzung nach {{format}} exportiert: {{path}}',
'Failed to export token usage stats: {{error}}':
'Token-Nutzungsstatistiken konnten nicht exportiert werden: {{error}}',
'Unclosed quote in arguments.':
'Nicht geschlossenes Anführungszeichen in Argumenten.',
'Note: generation timing (TTFT/TPS) belongs to generation metrics.':
'Hinweis: Generierungszeiten (TTFT/TPS) gehören zu den Generierungsmetriken.',
'exit the cli': 'CLI beenden',
'Manage workspace directories': 'Arbeitsbereichsverzeichnisse verwalten',
'Add directories to the workspace. Use comma to separate multiple paths':
Expand Down
46 changes: 46 additions & 0 deletions packages/cli/src/i18n/locales/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,52 @@ export default {
'Show model-specific usage statistics.',
'Show tool-specific usage statistics.':
'Show tool-specific usage statistics.',
'Show daily token usage statistics.': 'Show daily token usage statistics.',
'Show monthly token usage statistics.':
'Show monthly token usage statistics.',
'Export token usage statistics to CSV or JSON.':
'Export token usage statistics to CSV or JSON.',
'No usage data.': 'No usage data.',
'{{label}}: {{tokens}} tokens ({{requests}} requests)':
'{{label}}: {{tokens}} tokens ({{requests}} requests)',
'Daily token usage for {{value}}': 'Daily token usage for {{value}}',
'Monthly token usage for {{value}}': 'Monthly token usage for {{value}}',
'Total: {{tokens}} tokens': 'Total: {{tokens}} tokens',
'Requests: {{requests}}': 'Requests: {{requests}}',
'Breakdown:': 'Breakdown:',
'Input: {{tokens}}': 'Input: {{tokens}}',
'Output: {{tokens}}': 'Output: {{tokens}}',
'Cached (included in Input): {{tokens}}':
'Cached (included in Input): {{tokens}}',
'Thoughts: {{tokens}}': 'Thoughts: {{tokens}}',
'By model:': 'By model:',
'By auth type:': 'By auth type:',
'By model/auth type:': 'By model/auth type:',
'By source:': 'By source:',
'Failed to load token usage stats: {{error}}':
'Failed to load token usage stats: {{error}}',
'Expected --format csv or --format json.':
'Expected --format csv or --format json.',
'Expected a file path after --output.':
'Expected a file path after --output.',
'Unexpected argument: {{argument}}': 'Unexpected argument: {{argument}}',
'Usage: /stats export <daily|monthly> [YYYY-MM-DD|YYYY-MM] [--format csv|json] [--output path]':
'Usage: /stats export <daily|monthly> [YYYY-MM-DD|YYYY-MM] [--format csv|json] [--output path]',
'Token usage export path must be within the project working directory.':
'Token usage export path must be within the project working directory.',
'Export target does not exist: {{path}}':
'Export target does not exist: {{path}}',
'Cannot resolve export path within the working directory.':
'Cannot resolve export path within the working directory.',
'Could not create a temporary export file.':
'Could not create a temporary export file.',
'Token usage exported to {{format}}: {{path}}':
'Token usage exported to {{format}}: {{path}}',
'Failed to export token usage stats: {{error}}':
'Failed to export token usage stats: {{error}}',
'Unclosed quote in arguments.': 'Unclosed quote in arguments.',
'Note: generation timing (TTFT/TPS) belongs to generation metrics.':
'Note: generation timing (TTFT/TPS) belongs to generation metrics.',
'exit the cli': 'exit the cli',
'Manage workspace directories': 'Manage workspace directories',
'Add directories to the workspace. Use comma to separate multiple paths':
Expand Down
51 changes: 49 additions & 2 deletions packages/cli/src/i18n/locales/fr.js
Original file line number Diff line number Diff line change
Expand Up @@ -494,12 +494,59 @@ export default {
'Auto Edit': 'Édition automatique',
YOLO: 'YOLO',
'toggle vim mode on/off': 'activer/désactiver le mode Vim',
'check session stats. Usage: /stats [model|tools]':
'vérifier les stats de session. Utilisation : /stats [modèle|outils]',
'Show model-specific usage statistics.':
"Afficher les statistiques d'utilisation spécifiques au modèle.",
'Show tool-specific usage statistics.':
"Afficher les statistiques d'utilisation spécifiques aux outils.",
'Show daily token usage statistics.':
"Afficher les statistiques quotidiennes d'utilisation des tokens.",
'Show monthly token usage statistics.':
"Afficher les statistiques mensuelles d'utilisation des tokens.",
'Export token usage statistics to CSV or JSON.':
"Exporter les statistiques d'utilisation des tokens en CSV ou JSON.",
'No usage data.': "Aucune donnée d'utilisation.",
'{{label}}: {{tokens}} tokens ({{requests}} requests)':
'{{label}} : {{tokens}} tokens ({{requests}} requêtes)',
'Daily token usage for {{value}}':
'Utilisation quotidienne des tokens pour {{value}}',
'Monthly token usage for {{value}}':
'Utilisation mensuelle des tokens pour {{value}}',
'Total: {{tokens}} tokens': 'Total : {{tokens}} tokens',
'Requests: {{requests}}': 'Requêtes : {{requests}}',
'Breakdown:': 'Détail :',
'Input: {{tokens}}': 'Entrée : {{tokens}}',
'Output: {{tokens}}': 'Sortie : {{tokens}}',
'Cached (included in Input): {{tokens}}':
'Cache (inclus dans l’entrée) : {{tokens}}',
'Thoughts: {{tokens}}': 'Raisonnement : {{tokens}}',
'By model:': 'Par modèle :',
'By auth type:': "Par type d'authentification :",
'By model/auth type:': "Par modèle/type d'authentification :",
'By source:': 'Par source :',
'Failed to load token usage stats: {{error}}':
"Échec du chargement des statistiques d'utilisation des tokens : {{error}}",
'Expected --format csv or --format json.':
'--format csv ou --format json attendu.',
'Expected a file path after --output.':
'Un chemin de fichier est attendu après --output.',
'Unexpected argument: {{argument}}': 'Argument inattendu : {{argument}}',
'Usage: /stats export <daily|monthly> [YYYY-MM-DD|YYYY-MM] [--format csv|json] [--output path]':
'Utilisation : /stats export <daily|monthly> [YYYY-MM-DD|YYYY-MM] [--format csv|json] [--output path]',
'Token usage export path must be within the project working directory.':
"Le chemin d'export de l'utilisation des tokens doit rester dans le répertoire de travail du projet.",
'Export target does not exist: {{path}}':
"La cible d'export n'existe pas : {{path}}",
'Cannot resolve export path within the working directory.':
"Impossible de résoudre le chemin d'export dans le répertoire de travail.",
'Could not create a temporary export file.':
"Impossible de créer un fichier d'export temporaire.",
'Token usage exported to {{format}}: {{path}}':
'Utilisation des tokens exportée en {{format}} : {{path}}',
'Failed to export token usage stats: {{error}}':
"Échec de l'export des statistiques d'utilisation des tokens : {{error}}",
'Unclosed quote in arguments.': 'Guillemet non fermé dans les arguments.',
'Note: generation timing (TTFT/TPS) belongs to generation metrics.':
'Remarque : les temps de génération (TTFT/TPS) relèvent des métriques de génération.',
'exit the cli': 'quitter le CLI',
'Manage workspace directories':
"Gérer les répertoires de l'espace de travail",
Expand Down
47 changes: 45 additions & 2 deletions packages/cli/src/i18n/locales/ja.js
Original file line number Diff line number Diff line change
Expand Up @@ -360,10 +360,53 @@ export default {
'Auto (detect from system)': '自動(システムから検出)',
'Auto (detect terminal theme)': '自動(端末テーマを検出)',
Auto: '自動',
'check session stats. Usage: /stats [model|tools]':
'セッション統計を確認。使い方: /stats [model|tools]',
'Show model-specific usage statistics.': 'モデル別の使用統計を表示',
'Show tool-specific usage statistics.': 'ツール別の使用統計を表示',
'Show daily token usage statistics.': '日次 token 使用統計を表示',
'Show monthly token usage statistics.': '月次 token 使用統計を表示',
'Export token usage statistics to CSV or JSON.':
'token 使用統計を CSV または JSON にエクスポート',
'No usage data.': '使用データはありません。',
'{{label}}: {{tokens}} tokens ({{requests}} requests)':
'{{label}}: {{tokens}} tokens({{requests}} リクエスト)',
'Daily token usage for {{value}}': '{{value}} の日次 token 使用量',
'Monthly token usage for {{value}}': '{{value}} の月次 token 使用量',
'Total: {{tokens}} tokens': '合計: {{tokens}} tokens',
'Requests: {{requests}}': 'リクエスト数: {{requests}}',
'Breakdown:': '内訳:',
'Input: {{tokens}}': '入力: {{tokens}}',
'Output: {{tokens}}': '出力: {{tokens}}',
'Cached (included in Input): {{tokens}}':
'キャッシュ(入力に含まれる): {{tokens}}',
'Thoughts: {{tokens}}': '思考: {{tokens}}',
'By model:': 'モデル別:',
'By auth type:': '認証タイプ別:',
'By model/auth type:': 'モデル/認証タイプ別:',
'By source:': 'ソース別:',
'Failed to load token usage stats: {{error}}':
'token 使用統計の読み込みに失敗しました: {{error}}',
'Expected --format csv or --format json.':
'--format csv または --format json を指定してください。',
'Expected a file path after --output.':
'--output の後にファイルパスを指定してください。',
'Unexpected argument: {{argument}}': '予期しない引数: {{argument}}',
'Usage: /stats export <daily|monthly> [YYYY-MM-DD|YYYY-MM] [--format csv|json] [--output path]':
'使い方: /stats export <daily|monthly> [YYYY-MM-DD|YYYY-MM] [--format csv|json] [--output path]',
'Token usage export path must be within the project working directory.':
'token 使用量のエクスポート先はプロジェクト作業ディレクトリ内である必要があります。',
'Export target does not exist: {{path}}':
'エクスポート先が存在しません: {{path}}',
'Cannot resolve export path within the working directory.':
'作業ディレクトリ内でエクスポートパスを解決できません。',
'Could not create a temporary export file.':
'一時エクスポートファイルを作成できませんでした。',
'Token usage exported to {{format}}: {{path}}':
'token 使用量を {{format}} にエクスポートしました: {{path}}',
'Failed to export token usage stats: {{error}}':
'token 使用統計のエクスポートに失敗しました: {{error}}',
'Unclosed quote in arguments.': '引数の引用符が閉じられていません。',
'Note: generation timing (TTFT/TPS) belongs to generation metrics.':
'注: 生成時間(TTFT/TPS)は生成メトリクスに属します。',
'Manage workspace directories': 'ワークスペースディレクトリを管理',
'Add directories to the workspace. Use comma to separate multiple paths':
'ワークスペースにディレクトリを追加。複数パスはカンマで区切ってください',
Expand Down
Loading
Loading