jeo-code 0.8.2 → 0.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -6,6 +6,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  The README mirrors the latest 5 entries — regenerate with `bun run changelog:sync`.
8
8
 
9
+ ## [0.8.3] - 2026-07-08
10
+ _"잘못된 모델 설정하는 경우가 있는데" — the static Antigravity catalog had drifted badly from the LIVE Cloud Code Assist agent backend, and several current wire ids actively LIE about their tier: `gemini-3-flash-agent` is really "Gemini 3.5 Flash (High)" (the flagship agent model, which the name-suffix heuristic filed under the SMALL flash tier), `gemini-pro-agent` is really "Gemini 3.1 Pro (High)" (the code-agent model), and `gemini-3.1-pro-high` is DEPRECATED by the backend in favor of `gemini-pro-agent`. Probed the real `fetchAvailableModels` response (displayNames + agentModelSorts + deprecatedModelIds) and made it the single source of truth._
11
+
12
+ ### Fixed
13
+ - **Antigravity catalog rebuilt from the live agent set** (`src/ai/model-catalog.ts`) — the 17 stale tuple rows (`antigravity/gpt-5.5`, `claude-opus-4-8*`, `gemini-3-pro-*`, `gemini-2.5-*`, deprecated `gemini-3.1-pro-high`, …) are replaced by the 8 rows the backend actually serves today, each pinned to its displayName truth with a new explicit `CatalogModel.sizeClass`: `gemini-3-flash-agent` ("Gemini 3.5 Flash (High)") = **large/high**, `gemini-3.5-flash-low` (Medium) = mid, `gemini-3.5-flash-extra-low` (Low) = small, `gemini-pro-agent` ("Gemini 3.1 Pro (High)", the **code-agent** model) = mid + RECOMMENDED badge (replaces `antigravity/gpt-5.5`), `gemini-3.1-pro-low` = **small/low**, plus selectable `claude-sonnet-4-6` (Thinking) = mid and `claude-opus-4-6-thinking` = large.
14
+ - **`sizeClassFor` honors the explicit `sizeClass`** (`src/agent/prompt-router.ts`) — the suffix heuristic misfiled every "agent" wire id (flash⇒small even when the model is the flagship; pro⇒mid even for the Low tier). Routing pools now place each Antigravity model in the tier its displayName declares: trivial→{3.1-pro-low, 3.5-flash-extra-low}, standard/high→{gemini-pro-agent, claude-sonnet-4-6, …}, complex→{gemini-3-flash-agent, claude-opus-4-6-thinking}. The now-meaningless `isAntigravityGeminiBelow31` version floor (wire ids no longer encode versions honestly) is deleted — the catalog rows themselves are the floor.
15
+ - **`cheapestCredentialed` prefers the smaller size class on a flat-price tie** — inside one subscription family every row shares the same family price (e.g. all Antigravity Gemini rows), so the old newest-first tiebreak picked the FLAGSHIP (`gemini-3-flash-agent`) as "cheapest". Trivial-tier auto-select now lands on the actual Low tier (`gemini-3.5-flash-extra-low`).
16
+ - **Deprecated wire id keeps working** (`src/ai/model-registry.ts`) — `antigravity/gemini-3.1-pro-high` → `antigravity/gemini-pro-agent` added to `BUILTIN_ALIASES`, mirroring the backend's own `deprecatedModelIds.newModelId` mapping, so existing configs/roles pinned to the old id resolve to the successor instead of erroring. `model-manager.ts`'s stale duplicate `ALIAS_DEFAULTS` table is deleted in favor of the single `BUILTIN_ALIASES` source (the call path now also expands the `kimi` alias, previously missing there).
17
+
9
18
  ## [0.8.2] - 2026-07-08
10
19
  _"프롬프트라우팅이 api 입력을 요구하면서 동작안해" — prompt routing kept demanding an API key even when the user was already logged in via OAuth (GPT showed the same symptom). Root cause: every routing gate was PROVIDER-level ("any stored credential exists") while OAuth credentials are MODEL-level (ChatGPT OAuth serves only Codex ids, Kimi OAuth only the Kimi Code catalog, gemini OAuth nothing at all since the Cloud Code Assist masquerade was removed) — so routing happily picked models the stored login could never serve, and the turn then failed at call time asking for `<PROVIDER>_API_KEY`. Also restored a missing export that had broken `bun run typecheck` on HEAD._
11
20
 
package/README.ja.md CHANGED
@@ -38,7 +38,7 @@
38
38
 
39
39
  ## ハイライト
40
40
 
41
- - **マルチプロバイダ・単一ループ** — Anthropic / OpenAI(+Codex) / Gemini / Antigravity / Ollama / LM Studio に加え、OpenAI・Anthropic 互換クラウド20以上(Groq、DeepSeek、Mistral、OpenRouter、xAI、Kimi、z.ai など)を均一な JSON ツールループで。入力欄から OAuth ログイン(`/provider login`)、モデル選択は即座にデフォルトとして永続化。プロンプトルーティングは実際に使える認証済み経路だけを自動選択します: Gemini OAuth は provider-qualified な `antigravity/gemini-3.1+` モデルへ向かい、`GEMINI_API_KEY` が必要な public `google/gemini-*` 行は選びません。
41
+ - **マルチプロバイダ・単一ループ** — Anthropic / OpenAI(+Codex) / Gemini / Antigravity / Ollama / LM Studio に加え、OpenAI・Anthropic 互換クラウド20以上(Groq、DeepSeek、Mistral、OpenRouter、xAI、Kimi、z.ai など)を均一な JSON ツールループで。入力欄から OAuth ログイン(`/provider login`)、モデル選択は即座にデフォルトとして永続化。プロンプトルーティングは実際に使える認証済み経路だけを自動選択します: Gemini OAuth は provider-qualified な `antigravity/*` エージェントセット(Gemini 3.5 Flash 各ティア、Gemini 3.1 Pro、Claude Sonnet/Opus 4.6)へ向かい、`GEMINI_API_KEY` が必要な public `google/gemini-*` 行は選びません。
42
42
  - **編集の完全性** — read 出力にコンテンツアンカー(`42ab|`)が付き、アンカー付き編集は現在のファイルと照合・行移動時は自動再マッピング・不一致時は最新内容と共に拒否されます。
43
43
  - **自己修正の検証ループ** — post-edit フック(tsc / eslint / テスト)を設定すると、エージェントが診断を*自ら読み*ループ内で修正します。フックが赤のままだと `done` はブロックされます。
44
44
  - **芝居なしの本物のゲート** — `ralplan` の合議はリポジトリを実際に読む critic サブエージェントで、`[OKAY]` 評決が永続化され `jeo approve` がそれを*要求*します。`ultragoal` は誠実に報告します(スイート1回実行はグローバル信号であり、基準ごとの合格を捏造しません)。
@@ -262,11 +262,11 @@ CI は `.github/workflows/npm-publish.yml` で公開します — GitHub リリ
262
262
  ## 変更履歴 (Changelog)
263
263
 
264
264
  <!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
265
+ - **[0.8.3]** (2026-07-08) — "잘못된 모델 설정하는 경우가 있는데" — the static Antigravity catalog had drifted badly from the LIVE Cloud Code Assist agent backend, and several current wire ids actively LIE about their tier: `gemini-3-flash-agent` is really "Gemini 3.5 Flash (High)" (the flagship agent model, which the name-suffix heuristic filed under the SMALL flash tier), `gemini-pro-agent` is really "Gemini 3.1 Pro (High)" (the code-agent model), and `gemini-3.1-pro-high` is DEPRECATED by the backend in favor of `gemini-pro-agent`. Probed the real `fetchAvailableModels` response (displayNames + agentModelSorts + deprecatedModelIds) and made it the single source of truth.
265
266
  - **[0.8.2]** (2026-07-08) — "프롬프트라우팅이 api 입력을 요구하면서 동작안해" — prompt routing kept demanding an API key even when the user was already logged in via OAuth (GPT showed the same symptom). Root cause: every routing gate was PROVIDER-level ("any stored credential exists") while OAuth credentials are MODEL-level (ChatGPT OAuth serves only Codex ids, Kimi OAuth only the Kimi Code catalog, gemini OAuth nothing at all since the Cloud Code Assist masquerade was removed) — so routing happily picked models the stored login could never serve, and the turn then failed at call time asking for `<PROVIDER>_API_KEY`. Also restored a missing export that had broken `bun run typecheck` on HEAD.
266
267
  - **[0.8.1]** (2026-07-08) — Fix-forward for a functional regression this same session shipped in v0.8.0. This repo's working tree is shared with a concurrent interactive session; `git add`-ing `src/ai/provider-status.ts` for v0.8.0's routing-veto-gate fix also swept up that session's already-modified, uncommitted copy of the SAME file (containing an unrelated design change: gemini OAuth alone no longer serving `google/gemini-*` models) without its companion piece in `src/auth/flows/index.ts` — so v0.8.0 shipped with a test suite (`provider-status.test.ts`) asserting behavior whose supporting data flag never landed. CI caught this immediately post-release: 2 failing tests on the exact tagged commit. Investigated, confirmed the missing piece was real (and independently observable live via `jeo doctor` before this session had made ANY of its own edits — not a stray/speculative change), and completed it.
267
268
  - **[0.8.0]** (2026-07-08) — Root-caused a genuine reliability bug in the routing veto gate ("라우트가 동작후 api 키인증오류가나오는데 근본적인 원인 개선해"), then regenerated the animated README mascot to visualize the smart cross-provider routing this release cycle has been building: prompt routing that finds the cheapest usable path, with a "money saver" visual motif.
268
269
  - **[0.7.58]** (2026-07-07) — Applied the previous entry's `routing.crossProviderPool` to the real live session config, then deep-researched every catalogued model's actual public release date (2026-07 sourced, per-provider parallel research with citations) to answer "모델 설정은 2026년도 기준으로 딥서치해서 모델리스트 최신순으로 정렬" — while researching, found and fixed a genuine ranking bug this surfaced: `strongestCredentialed`'s tiebreak on a full capability tie (identical thinking/output/context) fell through to a raw alphabetical canonical-id compare, which silently picked the OLDEST model in a same-spec family (`claude-opus-4-6` over `claude-opus-4-7`/`4-8`, purely because `"4-6" < "4-8"` as a string) — confirmed reproducible before the fix, confirmed corrected after.
269
- - **[0.7.57]** (2026-07-07) — "동급모델간 크로스 프로바이더 라우팅이 동작하게 개선" — v0.7.56's tier auto-select was single-winner by design (always the one cheapest/strongest model), so a user with `roles.smol` pinned (or simply multiple credentialed providers) never saw actual distribution across equivalent-class models. Deep-research-informed redesign: production LLM routers (LiteLLM, Bifrost/VoidLLM) model this as a named "model group" spanning provider deployments with a distribution strategy, not a single deterministic pick — jeo now supports both, opt-in.
270
270
 
271
271
  See [CHANGELOG.md](CHANGELOG.md) for the full history.
272
272
  <!-- CHANGELOG:END -->
package/README.ko.md CHANGED
@@ -38,7 +38,7 @@
38
38
 
39
39
  ## 하이라이트
40
40
 
41
- - **멀티 프로바이더, 단일 루프** — Anthropic / OpenAI(+Codex) / Gemini / Antigravity / Ollama / LM Studio, 그리고 OpenAI·Anthropic 호환 클라우드 20종 이상(Groq, DeepSeek, Mistral, OpenRouter, xAI, Kimi, z.ai 등)까지 균일한 JSON 도구 루프로. 입력창에서 바로 OAuth 로그인(`/provider login`), 모델 선택은 즉시 기본값으로 영속됩니다. 프롬프트 라우팅은 실제 사용 가능한 인증 경로만 자동 선택합니다: Gemini OAuth는 provider-qualified `antigravity/gemini-3.1+` 모델로만 가고, `GEMINI_API_KEY`가 필요한 public `google/gemini-*` 행은 고르지 않습니다.
41
+ - **멀티 프로바이더, 단일 루프** — Anthropic / OpenAI(+Codex) / Gemini / Antigravity / Ollama / LM Studio, 그리고 OpenAI·Anthropic 호환 클라우드 20종 이상(Groq, DeepSeek, Mistral, OpenRouter, xAI, Kimi, z.ai 등)까지 균일한 JSON 도구 루프로. 입력창에서 바로 OAuth 로그인(`/provider login`), 모델 선택은 즉시 기본값으로 영속됩니다. 프롬프트 라우팅은 실제 사용 가능한 인증 경로만 자동 선택합니다: Gemini OAuth는 provider-qualified `antigravity/*` 에이전트 세트(Gemini 3.5 Flash 등급, Gemini 3.1 Pro, Claude Sonnet/Opus 4.6)로만 가고, `GEMINI_API_KEY`가 필요한 public `google/gemini-*` 행은 고르지 않습니다.
42
42
  - **편집 무결성** — read 출력에 콘텐츠 앵커(`42ab|`)가 붙고, 앵커 편집은 현재 파일과 대조 검증·줄 이동 시 자동 재매핑·불일치 시 최신 내용과 함께 거부 — 파일을 오염시키지 않습니다.
43
43
  - **자기수정 검증 루프** — post-edit 훅(tsc / eslint / 테스트)을 설정하면 에이전트가 진단을 *직접 읽고* 루프 안에서 수정합니다. 훅이 빨간 상태면 `done`이 차단됩니다.
44
44
  - **연극 없는 진짜 게이트** — `ralplan` 합의는 실제 저장소를 읽는 critic 서브에이전트이며 `[OKAY]` 평결이 영속되고 `jeo approve`가 이를 *요구*합니다. `ultragoal`은 정직하게 보고합니다(스위트 1회 실행은 전역 신호일 뿐, 기준별 통과를 조작하지 않음).
@@ -263,11 +263,11 @@ CI는 `.github/workflows/npm-publish.yml`로 배포합니다 — GitHub 릴리
263
263
  ## 변경 이력 (Changelog)
264
264
 
265
265
  <!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
266
+ - **[0.8.3]** (2026-07-08) — "잘못된 모델 설정하는 경우가 있는데" — the static Antigravity catalog had drifted badly from the LIVE Cloud Code Assist agent backend, and several current wire ids actively LIE about their tier: `gemini-3-flash-agent` is really "Gemini 3.5 Flash (High)" (the flagship agent model, which the name-suffix heuristic filed under the SMALL flash tier), `gemini-pro-agent` is really "Gemini 3.1 Pro (High)" (the code-agent model), and `gemini-3.1-pro-high` is DEPRECATED by the backend in favor of `gemini-pro-agent`. Probed the real `fetchAvailableModels` response (displayNames + agentModelSorts + deprecatedModelIds) and made it the single source of truth.
266
267
  - **[0.8.2]** (2026-07-08) — "프롬프트라우팅이 api 입력을 요구하면서 동작안해" — prompt routing kept demanding an API key even when the user was already logged in via OAuth (GPT showed the same symptom). Root cause: every routing gate was PROVIDER-level ("any stored credential exists") while OAuth credentials are MODEL-level (ChatGPT OAuth serves only Codex ids, Kimi OAuth only the Kimi Code catalog, gemini OAuth nothing at all since the Cloud Code Assist masquerade was removed) — so routing happily picked models the stored login could never serve, and the turn then failed at call time asking for `<PROVIDER>_API_KEY`. Also restored a missing export that had broken `bun run typecheck` on HEAD.
267
268
  - **[0.8.1]** (2026-07-08) — Fix-forward for a functional regression this same session shipped in v0.8.0. This repo's working tree is shared with a concurrent interactive session; `git add`-ing `src/ai/provider-status.ts` for v0.8.0's routing-veto-gate fix also swept up that session's already-modified, uncommitted copy of the SAME file (containing an unrelated design change: gemini OAuth alone no longer serving `google/gemini-*` models) without its companion piece in `src/auth/flows/index.ts` — so v0.8.0 shipped with a test suite (`provider-status.test.ts`) asserting behavior whose supporting data flag never landed. CI caught this immediately post-release: 2 failing tests on the exact tagged commit. Investigated, confirmed the missing piece was real (and independently observable live via `jeo doctor` before this session had made ANY of its own edits — not a stray/speculative change), and completed it.
268
269
  - **[0.8.0]** (2026-07-08) — Root-caused a genuine reliability bug in the routing veto gate ("라우트가 동작후 api 키인증오류가나오는데 근본적인 원인 개선해"), then regenerated the animated README mascot to visualize the smart cross-provider routing this release cycle has been building: prompt routing that finds the cheapest usable path, with a "money saver" visual motif.
269
270
  - **[0.7.58]** (2026-07-07) — Applied the previous entry's `routing.crossProviderPool` to the real live session config, then deep-researched every catalogued model's actual public release date (2026-07 sourced, per-provider parallel research with citations) to answer "모델 설정은 2026년도 기준으로 딥서치해서 모델리스트 최신순으로 정렬" — while researching, found and fixed a genuine ranking bug this surfaced: `strongestCredentialed`'s tiebreak on a full capability tie (identical thinking/output/context) fell through to a raw alphabetical canonical-id compare, which silently picked the OLDEST model in a same-spec family (`claude-opus-4-6` over `claude-opus-4-7`/`4-8`, purely because `"4-6" < "4-8"` as a string) — confirmed reproducible before the fix, confirmed corrected after.
270
- - **[0.7.57]** (2026-07-07) — "동급모델간 크로스 프로바이더 라우팅이 동작하게 개선" — v0.7.56's tier auto-select was single-winner by design (always the one cheapest/strongest model), so a user with `roles.smol` pinned (or simply multiple credentialed providers) never saw actual distribution across equivalent-class models. Deep-research-informed redesign: production LLM routers (LiteLLM, Bifrost/VoidLLM) model this as a named "model group" spanning provider deployments with a distribution strategy, not a single deterministic pick — jeo now supports both, opt-in.
271
271
 
272
272
  See [CHANGELOG.md](CHANGELOG.md) for the full history.
273
273
  <!-- CHANGELOG:END -->
package/README.md CHANGED
@@ -38,7 +38,7 @@ Run `jeo` inside a repository and it reads files, edits them, runs commands, and
38
38
 
39
39
  ## Highlights
40
40
 
41
- - **Multi-provider, one loop** — Anthropic / OpenAI (+Codex) / Gemini / Antigravity / Ollama / LM Studio, plus 20+ OpenAI- and Anthropic-compatible clouds (Groq, DeepSeek, Mistral, OpenRouter, xAI, Kimi, z.ai, …), all behind one uniform JSON tool loop. OAuth login happens from the input box (`/provider login`), every model pick persists as the new default, and prompt routing only auto-selects usable credentialed paths: Gemini OAuth goes through provider-qualified `antigravity/gemini-3.1+` models, never public `google/gemini-*` rows that require `GEMINI_API_KEY`.
41
+ - **Multi-provider, one loop** — Anthropic / OpenAI (+Codex) / Gemini / Antigravity / Ollama / LM Studio, plus 20+ OpenAI- and Anthropic-compatible clouds (Groq, DeepSeek, Mistral, OpenRouter, xAI, Kimi, z.ai, …), all behind one uniform JSON tool loop. OAuth login happens from the input box (`/provider login`), every model pick persists as the new default, and prompt routing only auto-selects usable credentialed paths: Gemini OAuth goes through the provider-qualified `antigravity/*` agent set (Gemini 3.5 Flash tiers, Gemini 3.1 Pro, Claude Sonnet/Opus 4.6), never public `google/gemini-*` rows that require `GEMINI_API_KEY`.
42
42
  - **Edit integrity** — read output carries content anchors (`42ab|`); anchored edits are verified against the current file, re-mapped when lines shifted, and rejected with fresh content instead of corrupting.
43
43
  - **Self-correcting verification loop** — configure a post-edit hook (tsc / eslint / tests) and the agent *sees* the diagnostics and fixes them in-loop; a red hook blocks `done` until resolved.
44
44
  - **Real gates, no theater** — `ralplan` consensus is a repo-grounded critic subagent whose `[OKAY]` verdict is persisted and *required* by `jeo approve`; `ultragoal` reports honestly (a suite run is a global signal, never fabricated per-criterion passes).
@@ -265,11 +265,11 @@ Huge thanks to [gajae-code](https://github.com/Yeachan-Heo/gajae-code) for the i
265
265
  ## Changelog
266
266
 
267
267
  <!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
268
+ - **[0.8.3]** (2026-07-08) — "잘못된 모델 설정하는 경우가 있는데" — the static Antigravity catalog had drifted badly from the LIVE Cloud Code Assist agent backend, and several current wire ids actively LIE about their tier: `gemini-3-flash-agent` is really "Gemini 3.5 Flash (High)" (the flagship agent model, which the name-suffix heuristic filed under the SMALL flash tier), `gemini-pro-agent` is really "Gemini 3.1 Pro (High)" (the code-agent model), and `gemini-3.1-pro-high` is DEPRECATED by the backend in favor of `gemini-pro-agent`. Probed the real `fetchAvailableModels` response (displayNames + agentModelSorts + deprecatedModelIds) and made it the single source of truth.
268
269
  - **[0.8.2]** (2026-07-08) — "프롬프트라우팅이 api 입력을 요구하면서 동작안해" — prompt routing kept demanding an API key even when the user was already logged in via OAuth (GPT showed the same symptom). Root cause: every routing gate was PROVIDER-level ("any stored credential exists") while OAuth credentials are MODEL-level (ChatGPT OAuth serves only Codex ids, Kimi OAuth only the Kimi Code catalog, gemini OAuth nothing at all since the Cloud Code Assist masquerade was removed) — so routing happily picked models the stored login could never serve, and the turn then failed at call time asking for `<PROVIDER>_API_KEY`. Also restored a missing export that had broken `bun run typecheck` on HEAD.
269
270
  - **[0.8.1]** (2026-07-08) — Fix-forward for a functional regression this same session shipped in v0.8.0. This repo's working tree is shared with a concurrent interactive session; `git add`-ing `src/ai/provider-status.ts` for v0.8.0's routing-veto-gate fix also swept up that session's already-modified, uncommitted copy of the SAME file (containing an unrelated design change: gemini OAuth alone no longer serving `google/gemini-*` models) without its companion piece in `src/auth/flows/index.ts` — so v0.8.0 shipped with a test suite (`provider-status.test.ts`) asserting behavior whose supporting data flag never landed. CI caught this immediately post-release: 2 failing tests on the exact tagged commit. Investigated, confirmed the missing piece was real (and independently observable live via `jeo doctor` before this session had made ANY of its own edits — not a stray/speculative change), and completed it.
270
271
  - **[0.8.0]** (2026-07-08) — Root-caused a genuine reliability bug in the routing veto gate ("라우트가 동작후 api 키인증오류가나오는데 근본적인 원인 개선해"), then regenerated the animated README mascot to visualize the smart cross-provider routing this release cycle has been building: prompt routing that finds the cheapest usable path, with a "money saver" visual motif.
271
272
  - **[0.7.58]** (2026-07-07) — Applied the previous entry's `routing.crossProviderPool` to the real live session config, then deep-researched every catalogued model's actual public release date (2026-07 sourced, per-provider parallel research with citations) to answer "모델 설정은 2026년도 기준으로 딥서치해서 모델리스트 최신순으로 정렬" — while researching, found and fixed a genuine ranking bug this surfaced: `strongestCredentialed`'s tiebreak on a full capability tie (identical thinking/output/context) fell through to a raw alphabetical canonical-id compare, which silently picked the OLDEST model in a same-spec family (`claude-opus-4-6` over `claude-opus-4-7`/`4-8`, purely because `"4-6" < "4-8"` as a string) — confirmed reproducible before the fix, confirmed corrected after.
272
- - **[0.7.57]** (2026-07-07) — "동급모델간 크로스 프로바이더 라우팅이 동작하게 개선" — v0.7.56's tier auto-select was single-winner by design (always the one cheapest/strongest model), so a user with `roles.smol` pinned (or simply multiple credentialed providers) never saw actual distribution across equivalent-class models. Deep-research-informed redesign: production LLM routers (LiteLLM, Bifrost/VoidLLM) model this as a named "model group" spanning provider deployments with a distribution strategy, not a single deterministic pick — jeo now supports both, opt-in.
273
273
 
274
274
  See [CHANGELOG.md](CHANGELOG.md) for the full history.
275
275
  <!-- CHANGELOG:END -->
package/README.zh.md CHANGED
@@ -38,7 +38,7 @@
38
38
 
39
39
  ## 亮点
40
40
 
41
- - **多提供商、单一循环** — Anthropic / OpenAI(+Codex) / Gemini / Antigravity / Ollama / LM Studio,以及 20+ 个 OpenAI、Anthropic 兼容云服务(Groq、DeepSeek、Mistral、OpenRouter、xAI、Kimi、z.ai 等),统一在一个 JSON 工具循环中。输入框内直接 OAuth 登录(`/provider login`),模型选择即刻持久化为默认值。Prompt routing 只会自动选择真实可用的凭据路径: Gemini OAuth 会走 provider-qualified `antigravity/gemini-3.1+` 模型,绝不选择需要 `GEMINI_API_KEY` 的 public `google/gemini-*` 行。
41
+ - **多提供商、单一循环** — Anthropic / OpenAI(+Codex) / Gemini / Antigravity / Ollama / LM Studio,以及 20+ 个 OpenAI、Anthropic 兼容云服务(Groq、DeepSeek、Mistral、OpenRouter、xAI、Kimi、z.ai 等),统一在一个 JSON 工具循环中。输入框内直接 OAuth 登录(`/provider login`),模型选择即刻持久化为默认值。Prompt routing 只会自动选择真实可用的凭据路径: Gemini OAuth 会走 provider-qualified 的 `antigravity/*` 代理模型集(Gemini 3.5 Flash 各档、Gemini 3.1 Pro、Claude Sonnet/Opus 4.6),绝不选择需要 `GEMINI_API_KEY` 的 public `google/gemini-*` 行。
42
42
  - **编辑完整性** — read 输出携带内容锚点(`42ab|`);带锚点的编辑会与当前文件校验、行移动时自动重映射、不匹配时连同最新内容一起拒绝 — 绝不污染文件。
43
43
  - **自我修正的验证循环** — 配置 post-edit 钩子(tsc / eslint / 测试),代理会*亲自读取*诊断并在循环内修复;钩子未通过时 `done` 会被阻断。
44
44
  - **没有表演的真实门禁** — `ralplan` 共识由真正读取仓库的 critic 子代理执行,`[OKAY]` 裁决被持久化且 `jeo approve` *强制要求*它;`ultragoal` 诚实报告(套件运行只是全局信号,绝不伪造逐条通过)。
@@ -262,11 +262,11 @@ CI 通过 `.github/workflows/npm-publish.yml` 发布 — GitHub 发布 release
262
262
  ## 更新日志 (Changelog)
263
263
 
264
264
  <!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
265
+ - **[0.8.3]** (2026-07-08) — "잘못된 모델 설정하는 경우가 있는데" — the static Antigravity catalog had drifted badly from the LIVE Cloud Code Assist agent backend, and several current wire ids actively LIE about their tier: `gemini-3-flash-agent` is really "Gemini 3.5 Flash (High)" (the flagship agent model, which the name-suffix heuristic filed under the SMALL flash tier), `gemini-pro-agent` is really "Gemini 3.1 Pro (High)" (the code-agent model), and `gemini-3.1-pro-high` is DEPRECATED by the backend in favor of `gemini-pro-agent`. Probed the real `fetchAvailableModels` response (displayNames + agentModelSorts + deprecatedModelIds) and made it the single source of truth.
265
266
  - **[0.8.2]** (2026-07-08) — "프롬프트라우팅이 api 입력을 요구하면서 동작안해" — prompt routing kept demanding an API key even when the user was already logged in via OAuth (GPT showed the same symptom). Root cause: every routing gate was PROVIDER-level ("any stored credential exists") while OAuth credentials are MODEL-level (ChatGPT OAuth serves only Codex ids, Kimi OAuth only the Kimi Code catalog, gemini OAuth nothing at all since the Cloud Code Assist masquerade was removed) — so routing happily picked models the stored login could never serve, and the turn then failed at call time asking for `<PROVIDER>_API_KEY`. Also restored a missing export that had broken `bun run typecheck` on HEAD.
266
267
  - **[0.8.1]** (2026-07-08) — Fix-forward for a functional regression this same session shipped in v0.8.0. This repo's working tree is shared with a concurrent interactive session; `git add`-ing `src/ai/provider-status.ts` for v0.8.0's routing-veto-gate fix also swept up that session's already-modified, uncommitted copy of the SAME file (containing an unrelated design change: gemini OAuth alone no longer serving `google/gemini-*` models) without its companion piece in `src/auth/flows/index.ts` — so v0.8.0 shipped with a test suite (`provider-status.test.ts`) asserting behavior whose supporting data flag never landed. CI caught this immediately post-release: 2 failing tests on the exact tagged commit. Investigated, confirmed the missing piece was real (and independently observable live via `jeo doctor` before this session had made ANY of its own edits — not a stray/speculative change), and completed it.
267
268
  - **[0.8.0]** (2026-07-08) — Root-caused a genuine reliability bug in the routing veto gate ("라우트가 동작후 api 키인증오류가나오는데 근본적인 원인 개선해"), then regenerated the animated README mascot to visualize the smart cross-provider routing this release cycle has been building: prompt routing that finds the cheapest usable path, with a "money saver" visual motif.
268
269
  - **[0.7.58]** (2026-07-07) — Applied the previous entry's `routing.crossProviderPool` to the real live session config, then deep-researched every catalogued model's actual public release date (2026-07 sourced, per-provider parallel research with citations) to answer "모델 설정은 2026년도 기준으로 딥서치해서 모델리스트 최신순으로 정렬" — while researching, found and fixed a genuine ranking bug this surfaced: `strongestCredentialed`'s tiebreak on a full capability tie (identical thinking/output/context) fell through to a raw alphabetical canonical-id compare, which silently picked the OLDEST model in a same-spec family (`claude-opus-4-6` over `claude-opus-4-7`/`4-8`, purely because `"4-6" < "4-8"` as a string) — confirmed reproducible before the fix, confirmed corrected after.
269
- - **[0.7.57]** (2026-07-07) — "동급모델간 크로스 프로바이더 라우팅이 동작하게 개선" — v0.7.56's tier auto-select was single-winner by design (always the one cheapest/strongest model), so a user with `roles.smol` pinned (or simply multiple credentialed providers) never saw actual distribution across equivalent-class models. Deep-research-informed redesign: production LLM routers (LiteLLM, Bifrost/VoidLLM) model this as a named "model group" spanning provider deployments with a distribution strategy, not a single deterministic pick — jeo now supports both, opt-in.
270
270
 
271
271
  See [CHANGELOG.md](CHANGELOG.md) for the full history.
272
272
  <!-- CHANGELOG:END -->
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jeo-code",
3
- "version": "0.8.2",
3
+ "version": "0.8.3",
4
4
  "description": "Clean, highly optimized AI coding agent using spec-first loop",
5
5
  "type": "module",
6
6
  "main": "src/cli.ts",
@@ -221,24 +221,11 @@ function hasAntigravityOauth(config: RoutingConfig): boolean {
221
221
  return !!(config.oauth?.antigravity || config.oauth?.gemini);
222
222
  }
223
223
 
224
- /** Cloud Code Assist's current agent-quality floor for OAuth-routed Gemini models:
225
- * keep auto-routing on Gemini 3.1+ instead of cheaper/older Antigravity Gemini 2.5
226
- * or 3.0 rows. Non-Gemini Antigravity rows (Claude/GPT) are not version-comparable
227
- * to Gemini and are left to the normal strength/price ranking. */
228
- function isAntigravityGeminiBelow31(canonical: string): boolean {
229
- const m = /^antigravity\/gemini-(\d+)(?:\.(\d+))?(?:-|$)/.exec(canonical.toLowerCase());
230
- if (!m) return false;
231
- const major = Number(m[1]);
232
- const minor = Number(m[2] ?? "0");
233
- return major < 3 || (major === 3 && minor < 1);
234
- }
235
-
236
224
  function isAutoSelectCandidate(m: CatalogModel, config: RoutingConfig): boolean {
237
225
  // Shared model-LEVEL credential gate (the full auth matrix is documented on
238
226
  // modelServableWithConfig; keep aligned with resolveCall).
239
227
  if (!isCloudProvider(m.provider) || m.limitedAvailability || !modelServableWithConfig(m.provider, m.canonical, config)) return false;
240
228
  if (hasAntigravityOauth(config) && m.provider === "gemini") return false;
241
- if (hasAntigravityOauth(config) && m.provider === "antigravity" && isAntigravityGeminiBelow31(m.canonical)) return false;
242
229
  return true;
243
230
  }
244
231
 
@@ -246,15 +233,19 @@ function isAutoSelectCandidate(m: CatalogModel, config: RoutingConfig): boolean
246
233
  /** Size class jeo infers for a catalog model, used to group EQUIVALENT models
247
234
  * across DIFFERENT providers for pool-based routing (see `tierModelPool`) — the
248
235
  * cross-provider counterpart to `cheapestCredentialed`/`strongestCredentialed`'s
249
- * single-winner selection. Matches PROVIDER-DECLARED size-tier suffixes
250
- * (Anthropic's haiku/sonnet/opus, Google's flash/pro, OpenAI's mini) against
236
+ * single-winner selection. An explicit catalog `sizeClass` wins outright — the
237
+ * authoritative tier for ids whose NAME misleads the suffix heuristic (e.g.
238
+ * Antigravity's `gemini-3-flash-agent` is "Gemini 3.5 Flash (High)", a flagship).
239
+ * Otherwise matches PROVIDER-DECLARED size-tier suffixes (Anthropic's
240
+ * haiku/sonnet/opus, Google's flash/pro, OpenAI's mini) against
251
241
  * hyphen/dot-delimited SEGMENTS of the canonical id — NOT a raw substring match,
252
242
  * which would false-positive on "gemini" containing "mini" as a substring.
253
243
  * `null` for ids with no size-tier suffix at all (gpt-5.5, o3, grok-4.3, kimi-*,
254
244
  * glm-*, deepseek-*, minimax-* — providers whose naming doesn't encode size);
255
245
  * `tierModelPool` falls those back to a strength-tercile split instead. */
256
- function sizeClassFor(canonical: string): "small" | "mid" | "large" | null {
257
- const id = canonical.toLowerCase();
246
+ function sizeClassFor(model: CatalogModel): "small" | "mid" | "large" | null {
247
+ if (model.sizeClass) return model.sizeClass;
248
+ const id = model.canonical.toLowerCase();
258
249
  const bare = id.includes("/") ? id.slice(id.indexOf("/") + 1) : id;
259
250
  const segments = bare.split(/[-.]/);
260
251
  if (segments.includes("haiku") || segments.includes("flash") || segments.includes("mini") || segments.includes("nano")) return "small";
@@ -291,9 +282,9 @@ export function tierModelPool(tier: PromptTier, config: RoutingConfig): string[]
291
282
  const targetClass = TIER_TO_SIZE_CLASS[tier];
292
283
  const credentialed = MODEL_CATALOG.filter(m => isAutoSelectCandidate(m, config));
293
284
 
294
- const suffixPool = credentialed.filter(m => sizeClassFor(m.canonical) === targetClass);
285
+ const suffixPool = credentialed.filter(m => sizeClassFor(m) === targetClass);
295
286
 
296
- const unclassified = credentialed.filter(m => sizeClassFor(m.canonical) === null).sort(compareStrengthAscending);
287
+ const unclassified = credentialed.filter(m => sizeClassFor(m) === null).sort(compareStrengthAscending);
297
288
  const third = Math.ceil(unclassified.length / 3);
298
289
  // "high" shares "standard"'s unclassified-model tercile share: the catalog's
299
290
  // size-suffix classification only has 3 real buckets (small/mid/large — see
@@ -352,8 +343,18 @@ export function cheapestCredentialed(config: RoutingConfig): string | null {
352
343
  best = m;
353
344
  bestCost = cost;
354
345
  } else if (cost === bestCost && best) {
346
+ // Same price (common inside one subscription family, e.g. every Antigravity
347
+ // Gemini row shares the flat "gemini" price): prefer the SMALLER declared
348
+ // size class first — "cheapest" is the trivial tier's pick, and a family's
349
+ // Low/(High) variants are priced identically while consuming very different
350
+ // quota — then NEWER release, then canonical id (deterministic).
351
+ const sizeRank = (m2: CatalogModel): number => {
352
+ const cls = sizeClassFor(m2);
353
+ return cls === "small" ? 0 : cls === "mid" ? 1 : cls === "large" ? 2 : 3;
354
+ };
355
+ const bySize = sizeRank(m) - sizeRank(best);
355
356
  const recency = compareReleaseDate(m.releaseDate, best.releaseDate);
356
- if (recency > 0 || (recency === 0 && m.canonical < best.canonical)) best = m;
357
+ if (bySize < 0 || (bySize === 0 && (recency > 0 || (recency === 0 && m.canonical < best.canonical)))) best = m;
357
358
  }
358
359
  }
359
360
  return best?.canonical ?? null;
@@ -406,7 +407,7 @@ export function strongestCredentialed(
406
407
  * `roles.medium`/`defaultModel` — never to `complex`'s flagship pick). */
407
408
  function strongestMidTierCredentialed(config: RoutingConfig): string | null {
408
409
  const midClass = MODEL_CATALOG.filter(
409
- m => isAutoSelectCandidate(m, config) && sizeClassFor(m.canonical) === "mid",
410
+ m => isAutoSelectCandidate(m, config) && sizeClassFor(m) === "mid",
410
411
  );
411
412
  if (midClass.length === 0) return null;
412
413
  return midClass.sort(compareStrengthAscending).at(-1)!.canonical;
@@ -30,7 +30,7 @@ export interface ModelCatalogEntry {
30
30
  * actual top tier, claude-fable-5, is pricier than the "recommended" sonnet-5 —
31
31
  * recommended means "solid everyday default", not "strongest"). Re-verify and
32
32
  * update whenever a provider ships a new default-tier release. */
33
- const RECOMMENDED: Record<string, true> = { "claude-sonnet-5": true, "gpt-5.5": true, "gemini-3-flash": true, "antigravity/gpt-5.5": true, "qwen2.5": true };
33
+ const RECOMMENDED: Record<string, true> = { "claude-sonnet-5": true, "gpt-5.5": true, "gemini-3-flash": true, "antigravity/gemini-pro-agent": true, "qwen2.5": true };
34
34
 
35
35
  export function normalizeModelId(id: string): string {
36
36
  return (id ?? "").trim().toLowerCase();
@@ -45,34 +45,31 @@ export interface CatalogModel {
45
45
  * date — these sort AFTER every dated entry within their block, never before,
46
46
  * so an unconfirmed date can never silently outrank a verified-newer model. */
47
47
  releaseDate?: string;
48
+ /** Explicit routing size class, for ids whose NAME misleads the suffix
49
+ * heuristic in prompt-router.ts's `sizeClassFor` (e.g. Antigravity's wire id
50
+ * `gemini-3-flash-agent` is actually "Gemini 3.5 Flash (High)" — a flagship,
51
+ * not a small flash tier). Unset = derive from the name suffix as before. */
52
+ sizeClass?: "small" | "mid" | "large";
48
53
  }
49
54
 
50
55
  const FULL: ThinkLevel[] = ["low", "medium", "high", "xhigh"];
51
56
  const STD: ThinkLevel[] = ["low", "medium", "high"];
52
57
 
53
- // [canonical model id, release YYYY-MM] tuples, deep-research sourced (Anthropic/
54
- // OpenAI/Google base-model announcement dates — antigravity is a hosting layer over
55
- // the SAME underlying models, not a separate release). Newest-first per family below;
56
- // -thinking/-high/-low suffixes are reasoning-effort variants of the SAME release.
57
- export const ANTIGRAVITY_MODELS = [
58
- ["gpt-5.5", "2026-04"],
59
- ["gemini-3.1-pro-high", "2026-02"],
60
- ["gemini-3.1-pro-low", "2026-02"],
61
- ["claude-opus-4-8", "2026-05"],
62
- ["claude-opus-4-8-thinking", "2026-05"],
63
- ["claude-opus-4-7", "2026-04"],
64
- ["claude-opus-4-7-thinking", "2026-04"],
65
- ["claude-sonnet-4-6", "2026-02"],
66
- ["claude-sonnet-4-6-thinking", "2026-02"],
67
- ["claude-opus-4-6-thinking", "2026-02"],
68
- ["gemini-3-flash", "2025-12"],
69
- ["gemini-3-pro-high", "2025-11"],
70
- ["gemini-3-pro-low", "2025-11"],
71
- ["gpt-oss-120b-medium", "2025-08"],
72
- ["gemini-2.5-flash", "2025-06"],
73
- ["gemini-2.5-flash-thinking", "2025-06"],
74
- ["gemini-2.5-pro", "2025-03"],
75
- ] as const;
58
+ // Antigravity (Cloud Code Assist) agent-mode model rows, verified against the
59
+ // LIVE fetchAvailableModels response (agentModelSorts "Recommended" group +
60
+ // per-id displayName, probed 2026-07-08). CRITICAL: several wire ids do NOT
61
+ // mean what their name suggests — the displayName is the truth:
62
+ // gemini-3-flash-agent → "Gemini 3.5 Flash (High)" (flagship agent tier)
63
+ // gemini-3.5-flash-low → "Gemini 3.5 Flash (Medium)"
64
+ // gemini-3.5-flash-extra-low→ "Gemini 3.5 Flash (Low)"
65
+ // gemini-pro-agent → "Gemini 3.1 Pro (High)" (the code-agent model;
66
+ // replaces DEPRECATED gemini-3.1-pro-high, per the
67
+ // backend's deprecatedModelIds.newModelId mapping —
68
+ // BUILTIN_ALIASES keeps the old id working)
69
+ // claude-sonnet-4-6 → "Claude Sonnet 4.6 (Thinking)"
70
+ // `sizeClass` pins each row's routing tier to that display truth so the name
71
+ // suffix heuristic can't misfile them (releaseDate = the underlying base-model
72
+ // announcement; Antigravity is a hosting layer, not a separate release).
76
73
 
77
74
  /** A curated set of common public models with their documented capabilities.
78
75
  * Ordered NEWEST-FIRST within each provider block per `releaseDate`
@@ -139,21 +136,22 @@ export const MODEL_CATALOG: readonly CatalogModel[] = [
139
136
  { canonical: "gemini-2.5-pro", provider: "gemini", providerModel: "gemini-2.5-pro", contextTokens: 1_000_000, maxOutputTokens: 65_536, thinking: STD, images: true, releaseDate: "2025-03" },
140
137
  { canonical: "gemini-2.0-flash", provider: "gemini", providerModel: "gemini-2.0-flash", contextTokens: 1_000_000, maxOutputTokens: 8_192, thinking: [], images: true, releaseDate: "2025-02" },
141
138
  { canonical: "gemini-1.5-pro", provider: "gemini", providerModel: "gemini-1.5-pro", contextTokens: 1_000_000, maxOutputTokens: 8_192, thinking: [], images: true, releaseDate: "2024-02" },
142
- // Google Antigravity / Gemini CLI (Cloud Code Assist) — provider-qualified to avoid
143
- // collisions with public Gemini, Anthropic, and OpenAI/Codex ids. A hosting layer
144
- // over the SAME underlying models researched above, not a separate release —
145
- // releaseDate comes from the [id, date] tuple, not re-derived.
146
- ...ANTIGRAVITY_MODELS.map(([id, releaseDate]): CatalogModel => ({
147
- canonical: `antigravity/${id}`,
148
- provider: "antigravity",
149
- providerModel: id,
150
- contextTokens: id.includes("claude") ? 200_000 : id.startsWith("gpt-5") ? 400_000 : id.includes("gemini-3") ? 1_000_000 : 1_000_000,
151
- maxOutputTokens: id.includes("claude") ? 64_000 : id.startsWith("gpt-5") ? 128_000 : 65_536,
152
- thinking: id.includes("thinking") || id.includes("-high") || id.includes("-low") || id.includes("gemini-3") || id.startsWith("gpt-5") ? FULL : STD,
153
- images: !id.includes("gpt-oss"),
154
- company: id.includes("claude") ? "Anthropic via Antigravity" : id.includes("gpt") ? "OpenAI via Antigravity" : "Google Antigravity",
155
- releaseDate,
156
- })),
139
+ // Google Antigravity / Cloud Code Assist agent set — provider-qualified to avoid
140
+ // collisions with public Gemini/Anthropic ids. Rows mirror the LIVE
141
+ // fetchAvailableModels agent list (see the block comment above ANTIGRAVITY rows'
142
+ // sizeClass rationale near the top of this file). Newest first.
143
+ // Gemini 3.5 Flash tiers (base model released 2026-05, Google I/O):
144
+ { canonical: "antigravity/gemini-3-flash-agent", provider: "antigravity", providerModel: "gemini-3-flash-agent", contextTokens: 1_000_000, maxOutputTokens: 65_536, thinking: FULL, images: true, company: "Google Antigravity", releaseDate: "2026-05", sizeClass: "large" }, // "Gemini 3.5 Flash (High)" — the HIGH agent model
145
+ { canonical: "antigravity/gemini-3.5-flash-low", provider: "antigravity", providerModel: "gemini-3.5-flash-low", contextTokens: 1_000_000, maxOutputTokens: 65_536, thinking: FULL, images: true, company: "Google Antigravity", releaseDate: "2026-05", sizeClass: "mid" }, // "Gemini 3.5 Flash (Medium)"
146
+ { canonical: "antigravity/gemini-3.5-flash-extra-low", provider: "antigravity", providerModel: "gemini-3.5-flash-extra-low", contextTokens: 1_000_000, maxOutputTokens: 65_536, thinking: FULL, images: true, company: "Google Antigravity", releaseDate: "2026-05", sizeClass: "small" }, // "Gemini 3.5 Flash (Low)"
147
+ // Gemini 3.1 Pro tiers (base model released 2026-02):
148
+ { canonical: "antigravity/gemini-pro-agent", provider: "antigravity", providerModel: "gemini-pro-agent", contextTokens: 1_000_000, maxOutputTokens: 65_536, thinking: FULL, images: true, company: "Google Antigravity", releaseDate: "2026-02", sizeClass: "mid" }, // "Gemini 3.1 Pro (High)" — the CODE-AGENT model (replaces deprecated gemini-3.1-pro-high)
149
+ { canonical: "antigravity/gemini-3.1-pro-low", provider: "antigravity", providerModel: "gemini-3.1-pro-low", contextTokens: 1_000_000, maxOutputTokens: 65_536, thinking: FULL, images: true, company: "Google Antigravity", releaseDate: "2026-02", sizeClass: "small" }, // "Gemini 3.1 Pro (Low)" — the LOW agent model
150
+ // Anthropic via Antigravity (wire id claude-sonnet-4-6 IS the thinking variant per its displayName):
151
+ { canonical: "antigravity/claude-sonnet-4-6", provider: "antigravity", providerModel: "claude-sonnet-4-6", contextTokens: 200_000, maxOutputTokens: 64_000, thinking: FULL, images: true, company: "Anthropic via Antigravity", releaseDate: "2026-02", sizeClass: "mid" }, // "Claude Sonnet 4.6 (Thinking)"
152
+ { canonical: "antigravity/claude-opus-4-6-thinking", provider: "antigravity", providerModel: "claude-opus-4-6-thinking", contextTokens: 200_000, maxOutputTokens: 64_000, thinking: FULL, images: true, company: "Anthropic via Antigravity", releaseDate: "2026-02", sizeClass: "large" }, // "Claude Opus 4.6 (Thinking)"
153
+ // OpenAI OSS via Antigravity:
154
+ { canonical: "antigravity/gpt-oss-120b-medium", provider: "antigravity", providerModel: "gpt-oss-120b-medium", contextTokens: 1_000_000, maxOutputTokens: 65_536, thinking: FULL, images: false, company: "OpenAI via Antigravity", releaseDate: "2025-08", sizeClass: "mid" }, // "GPT-OSS 120B (Medium)"
157
155
  // Tencent — hosts the same underlying models under its own cloud brand; dates
158
156
  // below are the ORIGINAL developer's release (DeepSeek/MiniMax/Zhipu/Moonshot),
159
157
  // not Tencent's hosting-catalog appearance date, except where the id itself pins
@@ -4,7 +4,7 @@ import { readGlobalConfig } from "../agent/state";
4
4
  import { resolveCredential, isOAuthProvider, type AuthProvider, type Credential } from "../auth";
5
5
  import "./register-providers"; // side-effect: registers built-in adapters into providerRegistry
6
6
  import type { CallOptions, Message, ProviderAdapter, ProviderName } from "./types";
7
- import { expandAlias, resolveModelId, effectiveAliasesFor } from "./model-registry";
7
+ import { expandAlias, resolveModelId, effectiveAliasesFor, BUILTIN_ALIASES } from "./model-registry";
8
8
  import { findCatalogEntry, type ModelCatalogEntry } from "./model-catalog-compat";
9
9
  import { toProviderModel, CODEX_MODELS, KIMI_CODE_MODELS, findCatalogModel } from "./model-catalog";
10
10
  import { xaiCredential } from "./providers/xai";
@@ -118,7 +118,7 @@ export function resolveMaxOutputTokens(
118
118
  model?: string,
119
119
  level?: "low" | "medium" | "high" | "xhigh",
120
120
  ): number {
121
- const meta = model ? findCatalogEntry(expandAlias(model, ALIAS_DEFAULTS)) : undefined;
121
+ const meta = model ? findCatalogEntry(expandAlias(model, BUILTIN_ALIASES)) : undefined;
122
122
  if (!meta) return thinkingMaxTokens(level);
123
123
  const envCap = Number(jeoEnv("MAX_OUTPUT_TOKENS"));
124
124
  const cap = Number.isFinite(envCap) && envCap > 0 ? envCap : DEFAULT_MAX_OUTPUT_CAP;
@@ -198,7 +198,6 @@ export interface ModelManager {
198
198
  resolveProvider: typeof resolveProvider;
199
199
  }
200
200
 
201
- const ALIAS_DEFAULTS = { fast: "ollama/qwen2.5:0.5b", local: "ollama/qwen2.5:0.5b", sonnet: "claude-sonnet-4-6", opus: "claude-opus-4-6", haiku: "claude-haiku-4-5", gpt: "gpt-5.5", flash: "gemini-2.5-flash", grok: "grok-4.3" };
202
201
 
203
202
  /**
204
203
  * Build retry options from a config `retry` budget (gjc parity). `requestMaxRetries`
@@ -408,7 +407,7 @@ export function credentialForCall(
408
407
  async function resolveCall(options: Partial<CallOptions>, kind: "request" | "stream" = "request"): Promise<Resolved> {
409
408
  const config = await readGlobalConfig();
410
409
  const aliases = { ...((config as { modelAliases?: Record<string, string> }).modelAliases ?? {}) };
411
- const model = expandAlias(options.model ?? config.defaultModel, { ...ALIAS_DEFAULTS, ...aliases });
410
+ const model = expandAlias(options.model ?? config.defaultModel, { ...BUILTIN_ALIASES, ...aliases });
412
411
  const provider = resolveProvider(model);
413
412
  const adapter = providerRegistry.get(provider)!;
414
413
 
@@ -16,6 +16,10 @@ export const BUILTIN_ALIASES: ModelAliases = {
16
16
  flash: "gemini-2.5-flash",
17
17
  grok: "grok-4.3",
18
18
  kimi: "kimi-k2-0711-preview",
19
+ // Antigravity's backend DEPRECATED this wire id (deprecatedModelIds:
20
+ // { "gemini-3.1-pro-high": { newModelId: "gemini-pro-agent" } }) — keep
21
+ // existing configs/roles pinned to the old id working on the successor.
22
+ "antigravity/gemini-3.1-pro-high": "antigravity/gemini-pro-agent",
19
23
  };
20
24
 
21
25
  // Expand an alias to a concrete model id. Unknown input passes through unchanged.