Fix alias display bug. - #249
Conversation
- Request event log: show model_alias in the model column, fall back to original name
- Model filter dropdown: returns {value, label} pairs, label prefers alias
- Realtime panel Top5: uses model_alias as display label
- Analysis page (pie chart, efficiency scatter, heatmap): replace original model name with alias via loadModelAliasMap() post-processing
- Cost calculation: new lookupPricingByModelOrAlias() falls back to alias when original model name has no price entry
- Window stats (quota window cost): includes model_alias in GROUP BY and pricing lookup
- All backend layers (repo DTO, service DTO, API payload) carry ModelAlias through
Also fixes duplicate ServiceTier field in usageEventProjectionToRecord.
There was a problem hiding this comment.
Code Review
This pull request introduces support for model aliases across usage events, overview statistics, and analysis panels, updating both backend Go APIs and frontend React components to use a structured ModelFilterOption (with value and label) instead of plain strings. Feedback on these changes suggests utilizing a 'key' field instead of 'value' in frontend-facing DTOs to avoid rendering issues, removing a redundant 'model' variable in usageEventRecordCost, and optimizing the database query in loadModelAliasMap to prevent performance bottlenecks on the hot usage_events table.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| } | ||
| body := resp.Body.String() | ||
| if body != `{"models":["claude-sonnet","gpt-5"]}` { | ||
| if body != `{"models":[{"value":"claude-sonnet","label":"claude-sonnet"},{"value":"gpt-5","label":"gpt-5"}]}` { |
There was a problem hiding this comment.
In DTOs intended for frontend consumption, maintain unique identifiers in the 'key' field and use a separate 'label' field strictly for display purposes. Overwriting unique keys with display labels can cause rendering issues in frameworks like React and prevent the client from uniquely identifying data sources.
| if body != `{"models":[{"value":"claude-sonnet","label":"claude-sonnet"},{"value":"gpt-5","label":"gpt-5"}]}` { | |
| if body != "{\"models\":[{\"key\":\"claude-sonnet\",\"label\":\"claude-sonnet\"},{\"key\":\"gpt-5\",\"label\":\"gpt-5\"}]}" { |
References
- In DTOs intended for frontend consumption, maintain unique identifiers in the 'key' field and use a separate 'label' field strictly for display purposes. Overwriting unique keys with display labels can cause rendering issues in frameworks like React and prevent the client from uniquely identifying data sources.
| model := strings.TrimSpace(record.Model) | ||
| pricing, ok := lookupPricingByModelOrAlias(pricingByModel, model, record.ModelAlias) |
There was a problem hiding this comment.
The model variable is redundant because lookupPricingByModelOrAlias already trims the model name internally. You can pass record.Model directly to simplify the code.
| model := strings.TrimSpace(record.Model) | |
| pricing, ok := lookupPricingByModelOrAlias(pricingByModel, model, record.ModelAlias) | |
| pricing, ok := lookupPricingByModelOrAlias(pricingByModel, record.Model, record.ModelAlias) |
| subQuery := db.Model(&entities.UsageEvent{}). | ||
| Select("MAX(id)"). | ||
| Where("model_alias IS NOT NULL AND model_alias != ''"). | ||
| Group("model") | ||
| if err := db.Model(&entities.UsageEvent{}). | ||
| Select("model, model_alias"). | ||
| Where("id IN (?)", subQuery). | ||
| Find(&rows).Error; err != nil { | ||
| return nil | ||
| } |
There was a problem hiding this comment.
Querying the hot usage_events transaction log table with a Group By and IN subquery on every request to load the model alias map can cause severe performance bottlenecks as the table grows. Consider caching this mapping in-memory (e.g., with a short TTL or invalidation on new alias creation) or ensuring that an appropriate index exists on (model_alias, model, id) to avoid full table scans.
References
- When performing database lookups for specific records, use parameterized queries and ensure the search is supported by an index to optimize performance and protect against injection attacks.
- Remove pseudo-3D effects: drop inset box-shadow and ::before flame gradient - Restore warm orange color scale for semantic heat meaning - Flatten cell styling to match overall design language - Sync test assertions with new color values
…seMemo 依赖数组补充 speedTotalHint; remove: 删除 Homebrew tap 自动更新
在设置页新增「生成 API Key」入口,通过 PATCH CPA /v0/management/api-keys 在 上游生成带 kpr_ 前缀的随机 Key,写回本地库并保存别名,一次性完整展示供复制。 管理员专用接口 POST /usage/api-keys/generate。
同一上游模型名配置不同 alias 时,请求事件页能区分,但概览实时 Token 占比和 分析页仍按原始 model 名聚合,导致多个 alias 被合并成一行。改为按 alias (无 alias 时回退 model)作为模型维度 key 与 label,保持与请求事件页一致。 - realtime current usage 模型维度 key/label 均使用 alias - 分析 ModelComposition/ModelEfficiency/Heatmap 按 alias 拆分 - 移除 applyAnalysisModelAliases 后处理(按 model 只取最新一条 alias 会覆盖合并) - 新增 alias 拆分回归测试
同一上游模型名配置不同 alias 时,模型下拉只显示其中一条 alias 且筛选 仍按 model 名聚合,无法只筛某个别名。改为: - 筛选项按 (model, model_alias) 去重生成展示值(alias 优先),每个 别名一个独立选项,value=label=展示值 - 列表过滤按展示值匹配:命中对应 model_alias,或命中无 alias 且 model 名相同的事件 - 移除不再需要的 loadModelAliasMap 全局 alias 映射 - 新增 alias 拆分与按别名过滤的回归测试
No description provided.