Skip to content
This repository was archived by the owner on Jul 30, 2026. It is now read-only.

fix(models): canonicalize GPT-5.6 reasoning efforts - #136

Merged
makoMakoGo merged 8 commits into
personal/local-clientsfrom
agent/fix-gpt-5-6-model-canonicalization
Jul 12, 2026
Merged

fix(models): canonicalize GPT-5.6 reasoning efforts#136
makoMakoGo merged 8 commits into
personal/local-clientsfrom
agent/fix-gpt-5-6-model-canonicalization

Conversation

@makoMakoGo

@makoMakoGo makoMakoGo commented Jul 11, 2026

Copy link
Copy Markdown
Owner

Summary

  • canonicalize Factory custom GPT-5.6 Sol, Terra, and Luna model entries to their API model identities before grouping and pricing
  • resolve the official gpt-5.6 alias to gpt-5.6-sol, including reasoning efforts, free-channel tags, release suffixes, and Factory custom-entry forms
  • strip global lexical decorations before source-specific semantic canonicalization so canonical model IDs are stable after one pass
  • treat max as a reasoning effort only for the GPT-5.6 family, preserving model identities such as gpt-5.1-codex-max
  • key wrapped aggregation by canonical model ID and render Sol, Terra, and Luna distinctly
  • bump the model canonicalization revision so cached source rows are rebuilt

Root cause

Factory stores the selected custom-entry ID in Droid session records, for example custom:gpt-5.6-sol-xhigh. Tokscale already removed the custom: prefix and recognized xhigh, but its OpenAI base-model predicate did not recognize the new Sol, Terra, and Luna family identities. The decorated ID therefore reached exact pricing unchanged and remained unpriced.

OpenAI also defines gpt-5.6 as an alias that routes to gpt-5.6-sol. Leaving the alias as a separate canonical ID would split grouping, exact pricing, and wrapped rankings from the explicit Sol model.

Global free-channel and release suffixes were removed only after source-specific alias resolution. Inputs such as gpt-5.6-free, gpt-5.6-2607, and gpt-5.6-high-free therefore needed a second canonicalization pass to reach Sol. The pipeline now removes lexical decorations before semantic alias and reasoning-effort resolution.

Wrapped reporting also used formatted display text as its aggregation key. Because the GPT-5 formatter did not render the three GPT-5.6 family names, their canonical IDs could collapse into one displayed model.

Impact

Droid and other local-client sessions using GPT-5.6 family entries now group under gpt-5.6-sol, gpt-5.6-terra, or gpt-5.6-luna and resolve their catalog-backed token cost. The gpt-5.6 alias and its decorated forms share the Sol identity in one idempotent canonicalization pass. Wrapped output retains the three family tiers separately while merging the alias with explicit Sol. Reasoning token accounting remains unchanged.

Validation

  • cargo test — 2,117 passed, 5 ignored
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo build --release -p tokscale-cli
  • public canonicalization tests cover -free, :free, (free), short release, effort-plus-free, and idempotence
  • end-to-end Droid fixtures cover the reported explicit Sol-xhigh entry and the official alias across discovery, parsing, cold and warm cache paths, canonicalization, and exact pricing
  • isolated source-built CLI verification resolved custom:gpt-5.6-high-free to gpt-5.6-sol and matched an exact Sol-only custom price at $0.000024
  • source-built and installed CLI scans produced the canonical GPT-5.6 Sol model with non-zero pricing

References

Recognize Sol, Terra, and Luna as GPT-5.6 model identities so Factory custom-entry effort suffixes are removed before grouping and pricing. Handle max only for the GPT-5.6 family to preserve model identities such as gpt-5.1-codex-max, and bump the canonicalization revision so cached source rows are rebuilt.
@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

本次变更新增 GPT-5.6 变体的 canonicalization 与 reasoning effort 识别,更新解析修订号,补充解析和定价测试,并调整 wrapped 数据的模型聚合及显示名称生成。

Changes

GPT-5.6 规范化与解析

Layer / File(s) Summary
Canonicalization、解析与定价验证
crates/tokscale-core/src/model_aliases.rs, crates/tokscale-core/src/adapters/mod.rs, crates/tokscale-core/src/lib_tests.rs, crates/tokscale-core/src/sessions/droid.rs
模型 canonicalization 先移除全局后缀,再处理来源特定别名;GPT-5.6 变体和 max effort 统一解析,并更新修订号及相关解析、分组、定价测试。

Wrapped 模型聚合与显示

Layer / File(s) Summary
模型聚合与 GPT-5.6 显示名称
crates/tokscale-cli/src/commands/wrapped.rs
wrapped 聚合改用原始 model_id 作为 key,通过辅助函数累计 cost 与 tokens,并为 solterraluna 生成显示名称;测试覆盖独立条目和归并结果。

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related issues

Possibly related PRs

Poem

小兔蹦过模型田,
GPT-5.6 排成线。
Sol、Terra、Luna 闪,
token 聚成金苹果甜。
canonical 月光照,
账单清清到终点。

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 标题准确概括了本次变更的核心:GPT-5.6 系列推理档位与别名规范化。
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/fix-gpt-5-6-model-canonicalization

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@makoMakoGo
makoMakoGo marked this pull request as ready for review July 11, 2026 20:30
@codspeed-hq

codspeed-hq Bot commented Jul 11, 2026

Copy link
Copy Markdown

Merging this PR will degrade performance by 16.56%

❌ 1 regressed benchmark
✅ 26 untouched benchmarks

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
canonical_model_id_cleanup[gpt4o_mini_date] 6.2 µs 7.4 µs -16.56%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing agent/fix-gpt-5-6-model-canonicalization (7c9f20c) with personal/local-clients (4a33b52)

Open in CodSpeed

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 4 files

Re-trigger cubic

Exercise Droid discovery, parsing, cache-version selection, model canonicalization, and exact pricing from a Factory session fixture instead of testing the finalizer in isolation.
Key wrapped model aggregation by canonical model ID instead of formatted display text, and render Sol, Terra, and Luna names explicitly so their usage and cost remain separate.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 2 files (changes from recent commits).

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread crates/tokscale-core/src/lib_tests.rs
Parse the same Factory session twice through one cache home and require the warm result to retain the same canonical model, provider, reasoning tokens, and exact price as the cold result.
Resolve the official gpt-5.6 alias to gpt-5.6-sol before stripping reasoning effort, so bare, dashed, parenthesized, and Factory custom-entry forms share one grouping and exact-pricing identity. Cover end-to-end pricing and wrapped aggregation while preserving gpt-5.1-codex-max.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 3 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread crates/tokscale-core/src/lib_tests.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
crates/tokscale-cli/src/commands/wrapped.rs (1)

381-407: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

避免对已存在的模型条目重复计算 format_model_name/get_provider_from_model

model_id 已存在于 model_map 中时,format_model_name(model_id)get_provider_from_model(model_id) 仍会被无条件计算,仅在 or_insert_with 闭包内才实际使用;同时 if model_entry.provider.is_none() 回填分支因两函数均为关于 model_id 的纯函数、且 key 不变而永远是空操作,属死代码。建议把这两次计算下沉到 or_insert_with 闭包内,仅在首次插入时执行。

♻️ 建议的重构
 fn accumulate_wrapped_model(
     model_map: &mut HashMap<String, WrappedRankedEntry>,
     model_id: &str,
     cost: f64,
     tokens: i64,
 ) {
-    let model_name = format_model_name(model_id);
-    let provider = get_provider_from_model(model_id);
     let model_entry = model_map
         .entry(model_id.to_string())
         .or_insert_with(|| WrappedRankedEntry {
-            name: model_name,
+            name: format_model_name(model_id),
             client_id: None,
-            provider,
+            provider: get_provider_from_model(model_id),
             cost: 0.0,
             tokens: 0,
         });
-    if model_entry.provider.is_none() {
-        model_entry.provider = provider;
-    }
     model_entry.cost += cost;
     model_entry.tokens = model_entry
         .tokens
         .checked_add(tokens)
         .expect("wrapped model token total exceeds i64::MAX");
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/tokscale-cli/src/commands/wrapped.rs` around lines 381 - 407, Update
accumulate_wrapped_model so format_model_name and get_provider_from_model are
evaluated only inside the or_insert_with initializer for newly inserted entries.
Remove the provider-is-none backfill branch, since existing entries should
retain their initialized provider; leave the cost and checked token accumulation
unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@crates/tokscale-cli/src/commands/wrapped.rs`:
- Around line 381-407: Update accumulate_wrapped_model so format_model_name and
get_provider_from_model are evaluated only inside the or_insert_with initializer
for newly inserted entries. Remove the provider-is-none backfill branch, since
existing entries should retain their initialized provider; leave the cost and
checked token accumulation unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f3555c4c-5244-4a93-a499-b3198e8c74ea

📥 Commits

Reviewing files that changed from the base of the PR and between 4a33b52 and 503bbf1.

📒 Files selected for processing (5)
  • crates/tokscale-cli/src/commands/wrapped.rs
  • crates/tokscale-core/src/adapters/mod.rs
  • crates/tokscale-core/src/lib_tests.rs
  • crates/tokscale-core/src/model_aliases.rs
  • crates/tokscale-core/src/sessions/droid.rs

Keep the reported custom:gpt-5.6-sol-xhigh Factory session alongside the official alias fixture so cold and warm end-to-end parsing and exact pricing cover both source identities.
Strip global free-channel and release decorations before source-specific semantic canonicalization so decorated GPT-5.6 aliases reach gpt-5.6-sol in one pass. Keep combined GLM tiers canonical and lock the affected identities to an idempotent public normalization result.
@makoMakoGo
makoMakoGo merged commit ab00841 into personal/local-clients Jul 12, 2026
9 of 10 checks passed
@makoMakoGo
makoMakoGo deleted the agent/fix-gpt-5-6-model-canonicalization branch July 12, 2026 09:43
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant