jeo-code 0.8.3 → 0.8.4
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 +10 -0
- package/README.ja.md +1 -1
- package/README.ko.md +1 -1
- package/README.md +1 -1
- package/README.zh.md +1 -1
- package/package.json +1 -1
- package/src/agent/state.ts +13 -0
- package/src/commands/launch/agents-slash.ts +5 -3
- package/src/commands/launch/model-slash.ts +5 -2
- package/src/commands/launch.ts +0 -2
- package/src/tui/components/config-panel.ts +8 -3
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,16 @@ 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.4] - 2026-07-08
|
|
10
|
+
_Follow-up to the 0.8.3 `jeo --tmux` E2E verification, which surfaced two real bugs: (1) the fake `test-anthropic-key` fixture found sitting in the user's REAL `~/.jeo/config.json` turned out to be reproducible — jeo's own test suite could silently write to the real config with no guard, and a prior session's routing tests had done exactly that; (2) the E2E run's TUI showed `'antigravity/gemini-pro-agent' is not in the live antigravity catalog` for a model that WAS live — traced to the note firing on a FAILED provider discovery (timeout/expired OAuth) rather than a genuinely absent model._
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- **Config writes are hermetic under `bun test`** (`src/agent/state.ts`) — `saveGlobalConfig` now throws if `NODE_ENV === "test"` and `JEO_CONFIG_DIR` is unset, refusing to touch the real `~/.jeo`. Root-caused three leaky subprocess spawns that inherited `process.env` without overriding `JEO_CONFIG_DIR` (`test/smoke.test.ts`, `test/launch-oneshot-slash.test.ts`, `test/mcp.test.ts`) — one of these (or an equivalent uncommitted test at the time) is how the real config's `providers.anthropic` got clobbered with the routing suite's `"test-anthropic-key"` fixture, silently breaking every real Anthropic call afterwards. All three spawns now sandbox `JEO_CONFIG_DIR` to a temp dir. The corrupted value has been removed from the live config (backed up).
|
|
14
|
+
- **"Not in the live catalog" note no longer fires on a FAILED discovery** (`src/tui/components/config-panel.ts`, `src/commands/launch/model-slash.ts`, `src/commands/launch/agents-slash.ts`) — `liveModelKnown(results, model)` treated "model absent from EVERY successful listing" and "that provider's listing itself failed" as the same case, so an expired/timed-out OAuth token flagged a perfectly valid, live-catalog model as invalid (reproduced live: `antigravity/gemini-pro-agent`, which the same session's `fetchAvailableModels` probe confirmed WAS live). Replaced with `liveModelMissing(results, provider, model)`, scoped to the pinned model's OWN provider and true only when that provider's listing `ok === true` with a non-empty list — a failed/absent/empty listing now correctly proves nothing and stays silent.
|
|
15
|
+
|
|
16
|
+
### Verified
|
|
17
|
+
Full suite 2743/2743 pass, typecheck clean. Live-verified both fixes: `saveGlobalConfig` throws the exact guard message under `NODE_ENV=test` without `JEO_CONFIG_DIR`; `liveModelMissing` returns `false` for a model present in a successful listing, `true` for one genuinely absent from a successful listing, and `false` (not a false positive) when the provider's own discovery failed — reproducing and closing the exact 0.8.3 E2E finding.
|
|
18
|
+
|
|
9
19
|
## [0.8.3] - 2026-07-08
|
|
10
20
|
_"잘못된 모델 설정하는 경우가 있는데" — 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
21
|
|
package/README.ja.md
CHANGED
|
@@ -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.4]** (2026-07-08) — Follow-up to the 0.8.3 `jeo --tmux` E2E verification, which surfaced two real bugs: (1) the fake `test-anthropic-key` fixture found sitting in the user's REAL `~/.jeo/config.json` turned out to be reproducible — jeo's own test suite could silently write to the real config with no guard, and a prior session's routing tests had done exactly that; (2) the E2E run's TUI showed `'antigravity/gemini-pro-agent' is not in the live antigravity catalog` for a model that WAS live — traced to the note firing on a FAILED provider discovery (timeout/expired OAuth) rather than a genuinely absent model.
|
|
265
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
|
-
- **[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
270
|
|
|
271
271
|
See [CHANGELOG.md](CHANGELOG.md) for the full history.
|
|
272
272
|
<!-- CHANGELOG:END -->
|
package/README.ko.md
CHANGED
|
@@ -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.4]** (2026-07-08) — Follow-up to the 0.8.3 `jeo --tmux` E2E verification, which surfaced two real bugs: (1) the fake `test-anthropic-key` fixture found sitting in the user's REAL `~/.jeo/config.json` turned out to be reproducible — jeo's own test suite could silently write to the real config with no guard, and a prior session's routing tests had done exactly that; (2) the E2E run's TUI showed `'antigravity/gemini-pro-agent' is not in the live antigravity catalog` for a model that WAS live — traced to the note firing on a FAILED provider discovery (timeout/expired OAuth) rather than a genuinely absent model.
|
|
266
267
|
- **[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.
|
|
267
268
|
- **[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.
|
|
268
269
|
- **[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.
|
|
269
270
|
- **[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.
|
|
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.
|
|
271
271
|
|
|
272
272
|
See [CHANGELOG.md](CHANGELOG.md) for the full history.
|
|
273
273
|
<!-- CHANGELOG:END -->
|
package/README.md
CHANGED
|
@@ -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.4]** (2026-07-08) — Follow-up to the 0.8.3 `jeo --tmux` E2E verification, which surfaced two real bugs: (1) the fake `test-anthropic-key` fixture found sitting in the user's REAL `~/.jeo/config.json` turned out to be reproducible — jeo's own test suite could silently write to the real config with no guard, and a prior session's routing tests had done exactly that; (2) the E2E run's TUI showed `'antigravity/gemini-pro-agent' is not in the live antigravity catalog` for a model that WAS live — traced to the note firing on a FAILED provider discovery (timeout/expired OAuth) rather than a genuinely absent model.
|
|
268
269
|
- **[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.
|
|
269
270
|
- **[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.
|
|
270
271
|
- **[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.
|
|
271
272
|
- **[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.
|
|
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.
|
|
273
273
|
|
|
274
274
|
See [CHANGELOG.md](CHANGELOG.md) for the full history.
|
|
275
275
|
<!-- CHANGELOG:END -->
|
package/README.zh.md
CHANGED
|
@@ -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.4]** (2026-07-08) — Follow-up to the 0.8.3 `jeo --tmux` E2E verification, which surfaced two real bugs: (1) the fake `test-anthropic-key` fixture found sitting in the user's REAL `~/.jeo/config.json` turned out to be reproducible — jeo's own test suite could silently write to the real config with no guard, and a prior session's routing tests had done exactly that; (2) the E2E run's TUI showed `'antigravity/gemini-pro-agent' is not in the live antigravity catalog` for a model that WAS live — traced to the note firing on a FAILED provider discovery (timeout/expired OAuth) rather than a genuinely absent model.
|
|
265
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
|
-
- **[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
270
|
|
|
271
271
|
See [CHANGELOG.md](CHANGELOG.md) for the full history.
|
|
272
272
|
<!-- CHANGELOG:END -->
|
package/package.json
CHANGED
package/src/agent/state.ts
CHANGED
|
@@ -410,6 +410,19 @@ export async function readGlobalConfig(): Promise<Config> {
|
|
|
410
410
|
|
|
411
411
|
export async function saveGlobalConfig(config: Config): Promise<void> {
|
|
412
412
|
const dir = globalConfigDir();
|
|
413
|
+
// Hermeticity guard: under `bun test` (Bun sets NODE_ENV=test, inherited by
|
|
414
|
+
// spawned CLI subprocesses via env spreads) a config WRITE may only target an
|
|
415
|
+
// explicitly sandboxed JEO_CONFIG_DIR — never the real ~/.jeo. A leaky test
|
|
416
|
+
// once overwrote the user's real providers.anthropic with the routing suite's
|
|
417
|
+
// "test-anthropic-key" fixture (~/.jeo/config.json.bak.test-clobber-20260702),
|
|
418
|
+
// silently killing every real Anthropic call afterwards. Reads stay unguarded
|
|
419
|
+
// (harmless); only the destructive path hard-fails, so a leak is caught in CI
|
|
420
|
+
// as a loud test error instead of corrupting the developer's machine.
|
|
421
|
+
if (process.env.NODE_ENV === "test" && !jeoEnv("CONFIG_DIR")) {
|
|
422
|
+
throw new Error(
|
|
423
|
+
"saveGlobalConfig: refusing to write the real ~/.jeo config under bun test — set JEO_CONFIG_DIR to a temp dir in the test (see test/config-save.test.ts's pattern).",
|
|
424
|
+
);
|
|
425
|
+
}
|
|
413
426
|
await fs.mkdir(dir, { recursive: true, mode: 0o700 });
|
|
414
427
|
const target = globalConfigPath();
|
|
415
428
|
const tmpPath = `${target}.${Math.random().toString(36).slice(2)}.tmp`;
|
|
@@ -35,7 +35,7 @@ import {
|
|
|
35
35
|
} from "../../agent/subagents";
|
|
36
36
|
import {
|
|
37
37
|
formatModelLine,
|
|
38
|
-
|
|
38
|
+
liveModelMissing,
|
|
39
39
|
formatPickListWithCapabilities,
|
|
40
40
|
formatAgentsPanel,
|
|
41
41
|
formatAgentDetail,
|
|
@@ -324,8 +324,10 @@ export async function runAgentsSlash(input: string, ctx: AgentsSlashCtx): Promis
|
|
|
324
324
|
const { provider } = await describeModel(chosenModel);
|
|
325
325
|
console.log(`${role.title} model set to ${chosenModel} (${provider}) — saved to ~/.jeo/config.json`);
|
|
326
326
|
const live = await getLiveModels();
|
|
327
|
-
|
|
328
|
-
|
|
327
|
+
// Honest-note gate: only flag the id when ITS provider's live listing
|
|
328
|
+
// succeeded without it (see liveModelMissing) — never on discovery failure.
|
|
329
|
+
if (liveModelMissing(live, provider, chosenModel)) {
|
|
330
|
+
console.log(` (note: '${chosenModel}' is not in the live ${provider} model list — verify it is valid)`);
|
|
329
331
|
}
|
|
330
332
|
return result();
|
|
331
333
|
}
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
} from "../../ai";
|
|
25
25
|
import type { ProviderModelsResult, PickEntry, ProviderName, ThinkLevel } from "../../ai";
|
|
26
26
|
import { getSubagentRole, resolveSubagentModel, withSubagentSetting } from "../../agent/subagents";
|
|
27
|
-
import { formatModelLine,
|
|
27
|
+
import { formatModelLine, liveModelMissing, formatPickListWithCapabilities, formatCapabilityLine } from "../../tui/components/config-panel";
|
|
28
28
|
import { isThinkingLevel } from "./flags";
|
|
29
29
|
|
|
30
30
|
// Antigravity with ANY Google OAuth (own login or the gemini-cli fallback) stays
|
|
@@ -268,7 +268,10 @@ export async function runModelSlash(input: string, ctx: ModelSlashCtx): Promise<
|
|
|
268
268
|
console.log(` ! ChatGPT OAuth serves only Codex models (${CODEX_MODELS.join(", ")}); '${resolved}' will be rejected at runtime — pick one of those, or set OPENAI_API_KEY / OPENAI_BASE_URL.`);
|
|
269
269
|
}
|
|
270
270
|
}
|
|
271
|
-
|
|
271
|
+
// Only claim "not in the live catalog" when that provider's live listing
|
|
272
|
+
// actually SUCCEEDED and the id is absent — a failed/timed-out discovery
|
|
273
|
+
// (expired OAuth, network) must not smear a perfectly valid pick.
|
|
274
|
+
if (arg && liveModelsCache && resolved === label && liveModelMissing(liveModelsCache, provider, resolved)) {
|
|
272
275
|
console.log(` (note: '${resolved}' is not in the live ${provider} catalog — use /model to pick a valid id)`);
|
|
273
276
|
}
|
|
274
277
|
const meta = catalogMetadata(resolved);
|
package/src/commands/launch.ts
CHANGED
|
@@ -11,6 +11,7 @@ import type { ProviderModelsResult } from "../../ai/model-discovery";
|
|
|
11
11
|
import type { PickEntry } from "../../ai/model-picker";
|
|
12
12
|
import type { CatalogModel } from "../../ai/model-catalog";
|
|
13
13
|
import type { EnrichedModel } from "../../ai/model-enrich";
|
|
14
|
+
import type { ProviderName } from "../../ai/types";
|
|
14
15
|
import { catalogMetadata, formatTokens, companyLabel } from "../../ai/model-catalog";
|
|
15
16
|
|
|
16
17
|
/** A single "Model: alias → resolved (provider)" status line. */
|
|
@@ -155,9 +156,13 @@ export function formatLiveModels(
|
|
|
155
156
|
return lines;
|
|
156
157
|
}
|
|
157
158
|
|
|
158
|
-
/** True when `
|
|
159
|
-
|
|
160
|
-
|
|
159
|
+
/** True ONLY when `provider`'s live listing SUCCEEDED and `model` is absent from
|
|
160
|
+
* it — the one state where "not in the live catalog" is an honest claim. A
|
|
161
|
+
* failed/timed-out/absent listing proves nothing about the model (the note it
|
|
162
|
+
* gates was firing on discovery failures, flagging perfectly valid ids). */
|
|
163
|
+
export function liveModelMissing(results: ProviderModelsResult[], provider: ProviderName, model: string): boolean {
|
|
164
|
+
const r = results.find(x => x.provider === provider);
|
|
165
|
+
return !!r && r.ok && r.models.length > 0 && !r.models.includes(model);
|
|
161
166
|
}
|
|
162
167
|
|
|
163
168
|
/**
|