[Bug]: token usage rows always have model=NULL for local-runtime-v2 sessions (modelIdentity reads id, projected model carries model_id)
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 78/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- sqlite, typescript
調査の方向性
packages/local-runtime-v2/src/service/session-system/owner.ts の modelIdentity() 周辺を読み、その結果が pi-usage.ts の使用量行にどう渡されるかをたどってください。packages/local-runtime-v2/src/service/turn-system/agent-host/assembly-context.ts にある投影後のモデル形状を確認してください。issue では model_id フィールドの不一致が指摘されています。v2 の使用量記録経路を実行し、新しい local_runtime_token_usage 行にモデルが含まれていることを確認して、修正を検証してください。
索引モデルが issue の本文から書いたものです。
説明
Product or interface
Desktop app (also affects CLI TUI / headless / ACP — all paths that record usage through local-runtime-v2)
Version
Desktop 3.1.3 (macOS); source analysis at main 9a93560 (v0.6.5)
Platform
macOS
OS version and architecture
macOS 26 arm64
Issue area
Other (local usage ledger / local_runtime_token_usage)
Steps to reproduce
- Use MiniMax Code desktop 3.1.3 (or any build recording usage via
local-runtime-v2) for a normal coding session with a MiniMax model (e.g.minimax/MiniMax-M3.1-Flash). - Inspect
~/.minimax/v2/sqlite/runtime-state.sqlite:
SELECT model, count(*) FROM local_runtime_token_usage GROUP BY model;
-- after upgrading to 3.1.3: every new row has model = NULL
On my machine: 1314 rows written by the previous version all have model = 'minimax/MiniMax-M3'; all 7 rows written after the 3.1.3 upgrade have model = NULL (session layout v2-final-dated-session, so they went through the v2 runtime).
Expected and actual behavior
Expected: the model column records the model used for each turn (as the v1 runtime path did, and as the model column, the idx_local_runtime_token_usage_model_ts index, and the group=model query path in usage/repo/drizzle.ts all imply).
Actual: rows written by local-runtime-v2 always have model = NULL.
Downstream impact: every tool that reads this table for statistics (including the built-in summarizeGroupBy('model') API, which falls back to coalesce(model, 'unknown')) can only show "unknown" for new sessions. See also cc-switch #7705 where a third-party importer hits the same thing ("mcode session 用量导入模型恒为 unknown").
Root cause analysis (source at main 9a93560)
The v2 write chain feeds modelIdentity() a model object whose keys can never match:
packages/local-runtime-v2/src/service/turn-system/agent-host/assembly-context.ts—projectResolvedModel()returns{ provider, model_id: resolved.id, context_window, max_tokens, … }.MODEL_ALLOWLIST(lines 42–58) containsmodel_id/modelIdbut noidkey, so the projected object can never carryid.- That object flows to
executionModel(local-agent-host.ts:231) and then to the usage projector (committed-history-writer.ts:321→owner.ts:697). packages/local-runtime-v2/src/service/session-system/owner.ts:802-808—modelIdentity()readsReflect.get(model, 'id')only. With themodel_id-shaped object it always returnsnull, andpi-usage.tswritesmodel: nullintolocal_runtime_token_usage.
modelIdentity() matches the pi framework's Model shape ({ id, provider, … }, third_party/pi-mono/packages/ai/src/types.ts:593), which is why the compat layer's modelIdentity(turn.model) calls still produce correct provider/id strings. Only the v2 projected shape is broken — the same function consumes two shapes and one of them silently degrades to null.
Additional notes:
- Both files are unchanged since the initial import commit (c59cf53, 2026-09-18), so this is not a recent regression in the public history — it has been there since the first snapshot.
- The assistant messages themselves carry the model (e.g.
messages.jsonlentries have"model": "MiniMax-M3.1-Flash"keyed by the sameturnId), so a fallback atcommittedPiUsageRowswould also work.
Suggested fix (either or both)
// owner.ts
function modelIdentity(model: unknown): string | null {
if (!model || typeof model !== 'object') return null;
const provider = Reflect.get(model, 'provider');
const id = Reflect.get(model, 'id') ?? Reflect.get(model, 'model_id') ?? Reflect.get(model, 'modelId');
if (typeof provider === 'string' && typeof id === 'string') return `${provider}/${id}`;
return typeof id === 'string' ? id : null;
}
or in pi-usage.ts committedPiUsageRows: fall back to the assistant message's own model field when input.model is null.
Before submitting
- I have searched existing issues.
- I have included my version and removed sensitive information.
- 主要言語
- TypeScript
- スター
- 2k
- フォーク
- 259
- 平均マージ
- 9時間 41分
- マージ済み PR(30日)
- 143
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
MiniMax-AI/minimax-code のほかの issue
-
bug needs-triage tui
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
MiniMax-AI/minimax-code#481 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
bug cli documentation needs-triage
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
MiniMax-AI/minimax-code#299 · コメント 3 件 ·
メンテナーはふだん 1 日以内に返信
-
bug desktop needs-triage
難易度 3/5 1〜2日 初心者へのやさしさ 56/100
MiniMax-AI/minimax-code#506 ·
メンテナーはふだん 1 日以内に返信
-
tui
難易度 3/5 1〜2日 初心者へのやさしさ 74/100
MiniMax-AI/minimax-code#505 ·
メンテナーはふだん 1 日以内に返信
-
tui
難易度 2/5 1〜3時間 初心者へのやさしさ 35/100
MiniMax-AI/minimax-code#504 ·
メンテナーはふだん 1 日以内に返信
MiniMax-AI/minimax-code の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
jessepollak/home#2223 ·
メンテナーはふだん 1 日以内に返信
-
grep fixture corpus test follows the corpus's loop symlink under the receipt runner (fails on main)オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
code-yeongyu/senpi#3756 ·
メンテナーはふだん 1 日以内に返信
-
org:external package:deepagents priority:triage topic:memory topic:middleware type:bug
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
langchain-ai/deepagents#7059 ·
メンテナーはふだん 1 日以内に返信
-
難易度 1/5 1時間未満 初心者へのやさしさ 92/100
osmlab/name-suggestion-index#12992 ·
メンテナーはふだん 1 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 66/100
hemilabs/ui-monorepo#2506 ·
メンテナーはふだん 1 日以内に返信