Skip to content

Commit 3ffdb73

Browse files
committed
fix: プロバイダークールダウンの別名判定を修正
Codex CLI の利用可能モデルを再計測し、最小トークン消費だった gpt-5.2 を既定モデルに更新 状態ファイルと設定上のプロバイダー名を比較時に正規化し、gemini/agy と antigravity、apple-ai/apple_intelligence と apple-intelligence を同一プロバイダーとして降格 旧エイリアス経由でもクールダウン降格されることを確認する state テストを追加 README と AGENTS の既定モデル、測定結果、クールダウン別名挙動を更新
1 parent 63f9537 commit 3ffdb73

5 files changed

Lines changed: 79 additions & 11 deletions

File tree

‎AGENTS.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,13 +124,14 @@ Provider state file note:
124124
- `State::save()` writes to `~/.config/git-sc/.providers-state.tmp` first and then `rename(2)`s it onto the final path so concurrent `git-sc` invocations never read a half-written TOML file. On rename failure the temporary file is deleted before the error is returned.
125125
- The temporary file suffix combines PID, monotonic nanosecond timestamp, and a process-local `AtomicU64` counter, so multiple threads (or rapid consecutive saves) that happen to observe the same wall-clock nanosecond never share a tmp path. Without the counter, two concurrent threads could write to the same `*.tmp.PID.NANOS` file and the slower thread's `rename(2)` would fail with `ENOENT` after the faster thread already moved it.
126126
- `provider_cooldown_minutes` is converted to seconds with saturating arithmetic, so extremely large user-provided values do not panic in debug builds or wrap in release builds; they are treated as effectively indefinite cooldowns.
127+
- Cooldown reordering canonicalizes provider aliases before comparing state keys with configured providers, so `gemini`/`agy` remain tied to `antigravity` and legacy `apple-ai`/`apple_intelligence` keys remain tied to `apple-intelligence`.
127128

128129
### Agent Context
129130

130131
When invoked from a coding agent, `App::run()` reads the `CLAW_HOOKS_AGENT_MESSAGE` environment variable and passes it to `AiService::build_prompt()` as `agent_context`. This context is injected into the AI prompt before the diff section, guiding the AI to reflect the developer's high-level intent in the commit message. The context is applied across standard generation and `--amend` / `--reword` / `--squash` / `--generate-for` workflows.
131132

132133
Default Codex model note:
133-
- As of May 30, 2026 (JST), the default Codex model is `gpt-5.3-codex-spark` after re-running `codex debug models` and `echo "Hello" | codex exec -c model_reasoning_effort='medium' -m <model>` for each listed Codex model. Single-run token consumption (cold start): `gpt-5.3-codex-spark` (`8,737`), `gpt-5.5` (`11,798`), `codex-auto-review` (`11,942`), `gpt-5.3-codex` (`12,021`), `gpt-5.4-mini` (`12,136`), `gpt-5.4` (`15,533`), and `gpt-5.2` (`16,828`). `gpt-5.3-codex-spark` was selected because it had the lowest measured consumption among the currently available Codex models.
134+
- As of May 31, 2026 (JST), the default Codex model is `gpt-5.2` after re-running `codex debug models` and `echo "Hello" | codex exec -c model_reasoning_effort='medium' -m <model>` for each listed Codex model. Single-run token consumption: `gpt-5.2` (`11,668`), `gpt-5.5` (`11,799`), `gpt-5.4` (`11,950`), `codex-auto-review` (`11,950`), `gpt-5.3-codex` (`12,023`), `gpt-5.3-codex-spark` (`12,083`), and `gpt-5.4-mini` (`15,214`). `gpt-5.2` was selected because it had the lowest measured consumption among the currently available Codex models.
134135

135136
## Configuration Files
136137

‎README.ja.md‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ codex_reasoning_effort = "low"
265265
# 注: Antigravity CLI (`agy`) はモデル選択フラグを持たないため、`gemini` 行は不要
266266
# (旧 git-sc が生成した `gemini = "..."` 行は後方互換のためパースされるが実行時には無視されます)
267267
[models]
268-
codex = "gpt-5.3-codex-spark"
268+
codex = "gpt-5.2"
269269
claude = "haiku"
270270
opencode = ""
271271

@@ -291,7 +291,9 @@ provider_timeout_seconds = 60
291291
| `prefix_rules` | URLベースのプレフィックス形式 | `[]` |
292292
| `prefix_scripts` | 外部プレフィックススクリプト | `[]` |
293293

294-
既存のグローバル設定ファイルは自動では書き換えられません。現在の Codex 既定モデルは `gpt-5.3-codex-spark` です。既存設定で使うには、`~/.config/git-sc/config.toml` の `models.codex` を更新してください。この既定値は 2026年5月30日 (JST) 時点の Codex モデル一覧で再検証済みです。
294+
既存のグローバル設定ファイルは自動では書き換えられません。現在の Codex 既定モデルは `gpt-5.2` です。既存設定で使うには、`~/.config/git-sc/config.toml` の `models.codex` を更新してください。この既定値は 2026年5月31日 (JST) 時点の Codex モデル一覧で再検証済みです。
295+
296+
プロバイダーのクールダウン状態は、並び替え前に旧エイリアスを正規化します。そのため `gemini`/`agy` のクールダウンは `antigravity` に、旧 `apple-ai` / `apple_intelligence` キーは `apple-intelligence` に引き続き適用されます。
295297

296298
### prefix_type の値
297299

‎README.md‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ codex_reasoning_effort = "low"
266266
# Note: Antigravity CLI (`agy`) does not accept a model flag, so no `gemini` line is needed here.
267267
# A legacy `gemini = "..."` value is parsed for backward compatibility but ignored at runtime.
268268
[models]
269-
codex = "gpt-5.3-codex-spark"
269+
codex = "gpt-5.2"
270270
claude = "haiku"
271271
opencode = ""
272272

@@ -292,7 +292,9 @@ provider_timeout_seconds = 60
292292
| `prefix_rules` | URL-based prefix format | `[]` |
293293
| `prefix_scripts` | External prefix scripts | `[]` |
294294

295-
Existing global config files are not rewritten automatically. The current Codex default is `gpt-5.3-codex-spark`; to use it in an existing setup, update `models.codex` in `~/.config/git-sc/config.toml`. This default was revalidated against the available Codex model list on May 30, 2026 (JST).
295+
Existing global config files are not rewritten automatically. The current Codex default is `gpt-5.2`; to use it in an existing setup, update `models.codex` in `~/.config/git-sc/config.toml`. This default was revalidated against the available Codex model list on May 31, 2026 (JST).
296+
297+
Provider cooldown state normalizes legacy aliases before reordering providers, so `gemini`/`agy` cooldown entries still apply to `antigravity`, and legacy `apple-ai` / `apple_intelligence` entries still apply to `apple-intelligence`.
296298

297299
### prefix_type Values
298300

‎src/config.rs‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ fn default_gemini_model() -> String {
3030
}
3131

3232
fn default_codex_model() -> String {
33-
"gpt-5.3-codex-spark".to_string()
33+
"gpt-5.2".to_string()
3434
}
3535

3636
fn default_claude_model() -> String {
@@ -604,8 +604,8 @@ codex_reasoning_effort = "high"
604604
#[test]
605605
fn test_default_codex_model_uses_latest_lowest_token_model() {
606606
// codex debug models の単発計測結果に基づく現在の既定モデルを固定する。
607-
assert_eq!(default_codex_model(), "gpt-5.3-codex-spark");
608-
assert_eq!(Config::default().models.codex, "gpt-5.3-codex-spark");
607+
assert_eq!(default_codex_model(), "gpt-5.2");
608+
assert_eq!(Config::default().models.codex, "gpt-5.2");
609609
}
610610

611611
#[test]
@@ -1917,7 +1917,7 @@ gemini = "gemini-2.5-pro"
19171917

19181918
assert_eq!(config.models.gemini, default_gemini_model());
19191919
assert_eq!(config.models.codex, default_codex_model());
1920-
assert!(content.contains(r#"codex = "gpt-5.3-codex-spark""#));
1920+
assert!(content.contains(r#"codex = "gpt-5.2""#));
19211921
assert_eq!(config.models.claude, default_claude_model());
19221922
assert_eq!(config.models.opencode, default_opencode_model());
19231923
}

‎src/state.rs‎

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,21 @@ impl State {
131131
cooldown_minutes.saturating_mul(60)
132132
}
133133

134+
/// 状態ファイルと設定ファイルのプロバイダー名を比較用の正規名にそろえる。
135+
///
136+
/// 設定ファイルには後方互換エイリアスが残ることがあるため、保存済みの失敗キーと
137+
/// 現在の provider 配列を同じプロバイダーとして扱えるようにする。
138+
fn canonical_provider_key(provider: &str) -> String {
139+
let lower = provider.to_lowercase();
140+
match lower.as_str() {
141+
"agy" | "gemini" | "antigravity" => "antigravity".to_string(),
142+
"apple-ai" | "apple_intelligence" | "apple-intelligence" => {
143+
"apple-intelligence".to_string()
144+
}
145+
_ => lower,
146+
}
147+
}
148+
134149
/// プロバイダーの失敗を記録
135150
pub fn record_failure(&mut self, provider: &str) {
136151
self.provider_failures.insert(
@@ -171,16 +186,20 @@ impl State {
171186
/// 降格されたプロバイダーは末尾に移動
172187
pub fn reorder_providers(&self, providers: Vec<String>, cooldown_minutes: u64) -> Vec<String> {
173188
let demoted = self.get_demoted_providers(cooldown_minutes);
189+
let demoted: Vec<String> = demoted
190+
.iter()
191+
.map(|p| Self::canonical_provider_key(p))
192+
.collect();
174193

175194
let mut normal: Vec<String> = providers
176195
.iter()
177-
.filter(|p| !demoted.contains(&p.to_lowercase()))
196+
.filter(|p| !demoted.contains(&Self::canonical_provider_key(p)))
178197
.cloned()
179198
.collect();
180199

181200
let mut demoted_providers: Vec<String> = providers
182201
.iter()
183-
.filter(|p| demoted.contains(&p.to_lowercase()))
202+
.filter(|p| demoted.contains(&Self::canonical_provider_key(p)))
184203
.cloned()
185204
.collect();
186205

@@ -284,6 +303,50 @@ mod tests {
284303
);
285304
}
286305

306+
#[test]
307+
fn test_reorder_providers_demotes_antigravity_when_config_uses_gemini_alias() {
308+
let mut state = State::default();
309+
state.record_failure("antigravity");
310+
311+
let providers = vec![
312+
"gemini".to_string(),
313+
"codex".to_string(),
314+
"claude".to_string(),
315+
];
316+
317+
let reordered = state.reorder_providers(providers, 60);
318+
assert_eq!(
319+
reordered,
320+
vec![
321+
"codex".to_string(),
322+
"claude".to_string(),
323+
"gemini".to_string(),
324+
]
325+
);
326+
}
327+
328+
#[test]
329+
fn test_reorder_providers_demotes_apple_intelligence_from_legacy_state_key() {
330+
let mut state = State::default();
331+
state.record_failure("apple-ai");
332+
333+
let providers = vec![
334+
"opencode".to_string(),
335+
"apple-intelligence".to_string(),
336+
"codex".to_string(),
337+
];
338+
339+
let reordered = state.reorder_providers(providers, 60);
340+
assert_eq!(
341+
reordered,
342+
vec![
343+
"opencode".to_string(),
344+
"codex".to_string(),
345+
"apple-intelligence".to_string(),
346+
]
347+
);
348+
}
349+
287350
#[test]
288351
fn test_reorder_providers_multiple_demoted() {
289352
let mut state = State::default();

0 commit comments

Comments
 (0)