jeo-code 0.12.3 → 0.12.5
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 +24 -0
- package/README.ja.md +2 -2
- package/README.ko.md +2 -2
- package/README.md +2 -2
- package/README.zh.md +2 -2
- package/package.json +1 -1
- package/src/ai/model-cache.ts +7 -3
- package/src/ai/model-catalog.ts +39 -1
- package/src/ai/model-discovery.ts +31 -7
- package/src/ai/model-manager.ts +2 -3
- package/src/ai/providers/antigravity.ts +2 -2
- package/src/ai/providers/gemini.ts +1 -0
- package/src/commands/auth.ts +12 -3
- package/src/commands/provider.ts +2 -0
- package/src/commands/setup-helpers.ts +1 -0
- package/src/commands/setup.ts +16 -11
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,30 @@ The README mirrors the latest 5 entries — regenerate with `bun run changelog:s
|
|
|
9
9
|
|
|
10
10
|
## [Unreleased]
|
|
11
11
|
|
|
12
|
+
## [0.12.5] - 2026-10-17
|
|
13
|
+
_Antigravity and Kimi provider support in interactive setup, Kimi live model cache rehydration, immediate discovery caching on provider probing._
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
- **Interactive Setup Provider Options** (`src/commands/setup.ts`, `src/commands/setup-helpers.ts`) — added `antigravity` (Google Cloud Code Assist OAuth) and `kimi` (Moonshot API key / Kimi Code OAuth) to interactive setup provider selection, enabling browser OAuth, bearer token paste, or API key configuration with default models (`antigravity/gemini-3-flash`, `kimi-k2.5`). Updated `buildEnabledProviders` to recognize configured `kimi` credentials.
|
|
17
|
+
- **Kimi Live Model Cache Rehydration** (`src/ai/model-cache.ts`) — cache hits for Kimi OAuth (`provider === 'kimi' && source === 'oauth'`) now rehydrate `recordLiveKimiCodeModels(entry.models)` alongside OpenAI Codex models.
|
|
18
|
+
- **Immediate Model Cache on Provider Probe** (`src/commands/provider.ts`) — successful `jeo provider test <id>` and `jeo provider add` probing now immediately writes discovered custom/compatible models to the disk cache (`writeModelCache([result])`).
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
- **Model Cache Key Scoping** (`src/ai/model-cache.ts`) — fixed `keyOf` helper scoping and included `kimi` in source distinction so OAuth and API key catalogs do not clobber each other.
|
|
22
|
+
- **OAuth Token Preservation in Setup** (`src/commands/setup.ts`) — fixed `delete next.oauth` condition to check `Object.keys(next.oauth).length === 0` so non-Anthropic/OpenAI/Gemini OAuth credentials (such as `antigravity` or `kimi`) are not inadvertently dropped on save.
|
|
23
|
+
- **Auth Import Model Reporting** (`src/commands/auth.ts`) — added `antigravity` reporting to `reportLiveModels` following Gemini OAuth import.
|
|
24
|
+
|
|
25
|
+
## [0.12.4] - 2026-10-17
|
|
26
|
+
_Refresh Antigravity provider (`antigravity/*`) account catalogs with `antigravity/hub/2.23.1` so entitled Gemini 4 Argon and Gemini 3.8 Flash tiers appear directly in `/model provider antigravity`._
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
- **Antigravity provider client identity & Argon catalog visibility** (`src/ai/providers/antigravity.ts`, `src/ai/model-discovery.ts`) — updated `getAntigravityUserAgent()` from `antigravity/1.104.0` to `antigravity/hub/2.23.1` (`jeopi` v16.6.3 parity) so `daily-cloudcode-pa.googleapis.com/v1internal:fetchAvailableModels` returns entitled `gemini-4-argon-{low,medium,high}` and `gemini-3.8-flash-*` tiers. Preserved named non-recommended chat models (`displayName`) alongside `agentModelSorts`/`tieredModelIds`/`defaultAgentModelId` while excluding explicit non-chat (`tabModelIds`, `imageGenerationModelIds`, `audioTranscriptionModelIds`, `deprecatedModelIds`), internal, and unnamed rows.
|
|
30
|
+
- **Client-UA-scoped Antigravity model cache invalidation** (`src/ai/model-cache.ts`) — included `getAntigravityUserAgent()` in `antigravityAccountScope` so client User-Agent updates immediately invalidate stale cached model lists without waiting for the 6-hour TTL.
|
|
31
|
+
- **In-name `-medium` thinking depth recognition** (`src/ai/providers/gemini.ts`, `src/ai/model-catalog.ts`) — `geminiNamedEffort` and `inferCatalogMetadata` now recognize `-medium` model suffixes (`gemini-4-argon-medium`, `gemini-3.8-flash-medium`) so unset `reasoningEffort` defaults to `medium` thinking depth.
|
|
32
|
+
|
|
33
|
+
### Verified
|
|
34
|
+
- Focused Antigravity/Gemini/discovery/catalog regression suites (`175 pass, 0 fail`), `bun run typecheck`, `bun run build`, `bun run pack:check`, and live `antigravity/gemini-4-argon-{low,medium,high}` discovery + `antigravity/gemini-4-argon-medium` inference (`HTTP 200`).
|
|
35
|
+
|
|
12
36
|
## [0.12.3] - 2026-10-17
|
|
13
37
|
_Anthropic static model catalog trimmed to claude-5.x with live API discovery, and `/route off` strictly fixes the active model with no failover._
|
|
14
38
|
|
package/README.ja.md
CHANGED
|
@@ -416,10 +416,10 @@ CI は `.github/workflows/npm-publish.yml` で公開します — GitHub リリ
|
|
|
416
416
|
|
|
417
417
|
<!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
|
|
418
418
|
- **[Unreleased]**
|
|
419
|
+
- **[0.12.5]** (2026-10-17) — Antigravity and Kimi provider support in interactive setup, Kimi live model cache rehydration, immediate discovery caching on provider probing.
|
|
420
|
+
- **[0.12.4]** (2026-10-17) — Refresh Antigravity provider (`antigravity/*`) account catalogs with `antigravity/hub/2.23.1` so entitled Gemini 4 Argon and Gemini 3.8 Flash tiers appear directly in `/model provider antigravity`.
|
|
419
421
|
- **[0.12.3]** (2026-10-17) — Anthropic static model catalog trimmed to claude-5.x with live API discovery, and `/route off` strictly fixes the active model with no failover.
|
|
420
422
|
- **[0.12.2]** (2026-10-16) — Select Argon through the official agy full agent, with its own live catalog and session, separately from jeo's Cloud Code Assist backend.
|
|
421
|
-
- **[0.12.1]** (2026-10-16) — Logged-in OpenAI subscription models were invisible on proxy-configured machines.
|
|
422
|
-
- **[0.12.0]** (2026-10-16) — Karpathy behavioral guardrails become always-on discipline, and skill routing gains an ECC single-harness inventory plus a Jev-style advisory router.
|
|
423
423
|
|
|
424
424
|
See [CHANGELOG.md](CHANGELOG.md) for the full history.
|
|
425
425
|
<!-- CHANGELOG:END -->
|
package/README.ko.md
CHANGED
|
@@ -417,10 +417,10 @@ CI는 `.github/workflows/npm-publish.yml`로 배포합니다 — GitHub 릴리
|
|
|
417
417
|
|
|
418
418
|
<!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
|
|
419
419
|
- **[Unreleased]**
|
|
420
|
+
- **[0.12.5]** (2026-10-17) — Antigravity and Kimi provider support in interactive setup, Kimi live model cache rehydration, immediate discovery caching on provider probing.
|
|
421
|
+
- **[0.12.4]** (2026-10-17) — Refresh Antigravity provider (`antigravity/*`) account catalogs with `antigravity/hub/2.23.1` so entitled Gemini 4 Argon and Gemini 3.8 Flash tiers appear directly in `/model provider antigravity`.
|
|
420
422
|
- **[0.12.3]** (2026-10-17) — Anthropic static model catalog trimmed to claude-5.x with live API discovery, and `/route off` strictly fixes the active model with no failover.
|
|
421
423
|
- **[0.12.2]** (2026-10-16) — Select Argon through the official agy full agent, with its own live catalog and session, separately from jeo's Cloud Code Assist backend.
|
|
422
|
-
- **[0.12.1]** (2026-10-16) — Logged-in OpenAI subscription models were invisible on proxy-configured machines.
|
|
423
|
-
- **[0.12.0]** (2026-10-16) — Karpathy behavioral guardrails become always-on discipline, and skill routing gains an ECC single-harness inventory plus a Jev-style advisory router.
|
|
424
424
|
|
|
425
425
|
See [CHANGELOG.md](CHANGELOG.md) for the full history.
|
|
426
426
|
<!-- CHANGELOG:END -->
|
package/README.md
CHANGED
|
@@ -409,10 +409,10 @@ Huge thanks to [gajae-code](https://github.com/Yeachan-Heo/gajae-code) for the i
|
|
|
409
409
|
|
|
410
410
|
<!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
|
|
411
411
|
- **[Unreleased]**
|
|
412
|
+
- **[0.12.5]** (2026-10-17) — Antigravity and Kimi provider support in interactive setup, Kimi live model cache rehydration, immediate discovery caching on provider probing.
|
|
413
|
+
- **[0.12.4]** (2026-10-17) — Refresh Antigravity provider (`antigravity/*`) account catalogs with `antigravity/hub/2.23.1` so entitled Gemini 4 Argon and Gemini 3.8 Flash tiers appear directly in `/model provider antigravity`.
|
|
412
414
|
- **[0.12.3]** (2026-10-17) — Anthropic static model catalog trimmed to claude-5.x with live API discovery, and `/route off` strictly fixes the active model with no failover.
|
|
413
415
|
- **[0.12.2]** (2026-10-16) — Select Argon through the official agy full agent, with its own live catalog and session, separately from jeo's Cloud Code Assist backend.
|
|
414
|
-
- **[0.12.1]** (2026-10-16) — Logged-in OpenAI subscription models were invisible on proxy-configured machines.
|
|
415
|
-
- **[0.12.0]** (2026-10-16) — Karpathy behavioral guardrails become always-on discipline, and skill routing gains an ECC single-harness inventory plus a Jev-style advisory router.
|
|
416
416
|
|
|
417
417
|
See [CHANGELOG.md](CHANGELOG.md) for the full history.
|
|
418
418
|
<!-- CHANGELOG:END -->
|
package/README.zh.md
CHANGED
|
@@ -414,10 +414,10 @@ CI 通过 `.github/workflows/npm-publish.yml` 发布 — GitHub 发布 release
|
|
|
414
414
|
|
|
415
415
|
<!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
|
|
416
416
|
- **[Unreleased]**
|
|
417
|
+
- **[0.12.5]** (2026-10-17) — Antigravity and Kimi provider support in interactive setup, Kimi live model cache rehydration, immediate discovery caching on provider probing.
|
|
418
|
+
- **[0.12.4]** (2026-10-17) — Refresh Antigravity provider (`antigravity/*`) account catalogs with `antigravity/hub/2.23.1` so entitled Gemini 4 Argon and Gemini 3.8 Flash tiers appear directly in `/model provider antigravity`.
|
|
417
419
|
- **[0.12.3]** (2026-10-17) — Anthropic static model catalog trimmed to claude-5.x with live API discovery, and `/route off` strictly fixes the active model with no failover.
|
|
418
420
|
- **[0.12.2]** (2026-10-16) — Select Argon through the official agy full agent, with its own live catalog and session, separately from jeo's Cloud Code Assist backend.
|
|
419
|
-
- **[0.12.1]** (2026-10-16) — Logged-in OpenAI subscription models were invisible on proxy-configured machines.
|
|
420
|
-
- **[0.12.0]** (2026-10-16) — Karpathy behavioral guardrails become always-on discipline, and skill routing gains an ECC single-harness inventory plus a Jev-style advisory router.
|
|
421
421
|
|
|
422
422
|
See [CHANGELOG.md](CHANGELOG.md) for the full history.
|
|
423
423
|
<!-- CHANGELOG:END -->
|
package/package.json
CHANGED
package/src/ai/model-cache.ts
CHANGED
|
@@ -19,9 +19,10 @@ import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
|
19
19
|
import * as os from "node:os";
|
|
20
20
|
import * as path from "node:path";
|
|
21
21
|
import { jeoEnv } from "../util/env";
|
|
22
|
-
import { recordLiveCodexModels, recordLiveProviderModels, setAntigravityAccountScope, setOpenAIOauthAccountScope } from "./model-catalog";
|
|
22
|
+
import { recordLiveCodexModels, recordLiveKimiCodeModels, recordLiveProviderModels, setAntigravityAccountScope, setOpenAIOauthAccountScope } from "./model-catalog";
|
|
23
23
|
import type { Credential } from "../auth";
|
|
24
24
|
import { getStoredOAuth, snapshotProvider } from "../auth/storage";
|
|
25
|
+
import { getAntigravityUserAgent } from "./providers/antigravity";
|
|
25
26
|
import { extractChatgptAccountId } from "./providers/openai-responses";
|
|
26
27
|
import type { ProviderName } from "./types";
|
|
27
28
|
|
|
@@ -87,7 +88,7 @@ export async function antigravityAccountScope(credential?: Credential): Promise<
|
|
|
87
88
|
|| process.env.GOOGLE_CLOUD_PROJECT?.trim()
|
|
88
89
|
|| process.env.GOOGLE_CLOUD_PROJECT_ID?.trim()
|
|
89
90
|
|| "";
|
|
90
|
-
return createHash("sha256").update(`${providerSlot}\u0000${identity}\u0000${projectId}`, "utf8").digest("hex");
|
|
91
|
+
return createHash("sha256").update(`${providerSlot}\u0000${identity}\u0000${projectId}\u0000${getAntigravityUserAgent()}`, "utf8").digest("hex");
|
|
91
92
|
} catch {
|
|
92
93
|
return undefined;
|
|
93
94
|
}
|
|
@@ -157,7 +158,7 @@ export function mergeCacheEntries(
|
|
|
157
158
|
const isScopedOAuth = (provider: ProviderName, source: ModelCacheSource): boolean =>
|
|
158
159
|
(provider === "openai" || provider === "antigravity") && source === "oauth";
|
|
159
160
|
const keyOf = (provider: ProviderName, baseUrl?: string, accountId?: string, source?: ModelCacheSource) =>
|
|
160
|
-
`${provider}\u0000${baseUrl?.replace(/\/+$/, "") ?? ""}\u0000${isScopedOAuth(provider, source ?? "none") ? accountId ?? "" : ""}\u0000${provider === "openai" || provider === "antigravity" ? source ?? "none" : ""}`;
|
|
161
|
+
`${provider}\u0000${baseUrl?.replace(/\/+$/, "") ?? ""}\u0000${isScopedOAuth(provider, source ?? "none") ? accountId ?? "" : ""}\u0000${provider === "openai" || provider === "antigravity" || provider === "kimi" ? source ?? "none" : ""}`;
|
|
161
162
|
for (const entry of previous) {
|
|
162
163
|
const scoped = isScopedOAuth(entry.provider, entry.source);
|
|
163
164
|
if (entry.provider === "agy") continue;
|
|
@@ -239,6 +240,9 @@ export function applyCachedModels(cache: ModelCacheFile | null, openAIOauthAccou
|
|
|
239
240
|
if (isOpenAIOAuth && entry.accountId && !entry.baseUrl) {
|
|
240
241
|
recordLiveCodexModels(entry.models, entry.accountId);
|
|
241
242
|
}
|
|
243
|
+
if (entry.provider === "kimi" && entry.source === "oauth") {
|
|
244
|
+
recordLiveKimiCodeModels(entry.models);
|
|
245
|
+
}
|
|
242
246
|
applied += entry.models.length;
|
|
243
247
|
}
|
|
244
248
|
return applied;
|
package/src/ai/model-catalog.ts
CHANGED
|
@@ -501,6 +501,30 @@ export const KIMI_CODE_MODELS: readonly string[] = [
|
|
|
501
501
|
"kimi-k2",
|
|
502
502
|
];
|
|
503
503
|
|
|
504
|
+
const liveKimiCodeModels = new Set<string>();
|
|
505
|
+
|
|
506
|
+
/** Record ids confirmed by the Kimi Code OAuth `/v1/models` endpoint so brand-new
|
|
507
|
+
* subscription models work immediately without waiting for a static catalog release. */
|
|
508
|
+
export function recordLiveKimiCodeModels(ids: readonly string[]): void {
|
|
509
|
+
for (const id of ids) {
|
|
510
|
+
const trimmed = id.trim();
|
|
511
|
+
if (!trimmed) continue;
|
|
512
|
+
const wire = trimmed.startsWith("kimi/") ? trimmed.slice(5) : trimmed;
|
|
513
|
+
if (wire) liveKimiCodeModels.add(wire);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
/** Whether `model` is served by the Kimi Code OAuth subscription endpoint. */
|
|
518
|
+
export function isKimiCodeModel(model: string): boolean {
|
|
519
|
+
const wire = model.startsWith("kimi/") ? model.slice(5) : model;
|
|
520
|
+
return KIMI_CODE_MODELS.includes(wire) || liveKimiCodeModels.has(wire);
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/** Test-only reset for live Kimi Code observations. */
|
|
524
|
+
export function resetLiveKimiCodeModels(): void {
|
|
525
|
+
liveKimiCodeModels.clear();
|
|
526
|
+
}
|
|
527
|
+
|
|
504
528
|
/** Recency compare for `releaseDate` ("YYYY-MM"): `>0` when `a` is newer; a
|
|
505
529
|
* missing date sorts oldest, so an unconfirmed date never outranks a
|
|
506
530
|
* verified-newer model. */
|
|
@@ -618,7 +642,7 @@ export function inferCatalogMetadata(modelId: string): CatalogModel | undefined
|
|
|
618
642
|
providerModel: id,
|
|
619
643
|
contextTokens: 1_000_000,
|
|
620
644
|
maxOutputTokens: 65_536,
|
|
621
|
-
thinking: !reasons ? [] : big3 || id.includes("thinking") || id.includes("-high") || id.includes("-low") ? FULL : STD,
|
|
645
|
+
thinking: !reasons ? [] : big3 || id.includes("thinking") || id.includes("-high") || id.includes("-medium") || id.includes("-low") ? FULL : STD,
|
|
622
646
|
images: true,
|
|
623
647
|
company: antigravity ? "Google Antigravity" : "Google",
|
|
624
648
|
};
|
|
@@ -639,6 +663,20 @@ export function inferCatalogMetadata(modelId: string): CatalogModel | undefined
|
|
|
639
663
|
company: "xAI",
|
|
640
664
|
};
|
|
641
665
|
}
|
|
666
|
+
// Kimi / Moonshot
|
|
667
|
+
const kimi = id.match(/^kimi-(k\d+|latest|for-coding)/);
|
|
668
|
+
if (kimi) {
|
|
669
|
+
return {
|
|
670
|
+
canonical: raw,
|
|
671
|
+
provider: "kimi",
|
|
672
|
+
providerModel: id,
|
|
673
|
+
contextTokens: 256_000,
|
|
674
|
+
maxOutputTokens: 16_384,
|
|
675
|
+
thinking: FULL,
|
|
676
|
+
images: false,
|
|
677
|
+
company: "Moonshot",
|
|
678
|
+
};
|
|
679
|
+
}
|
|
642
680
|
|
|
643
681
|
return undefined;
|
|
644
682
|
}
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
catalogByProvider,
|
|
17
17
|
KIMI_CODE_MODELS,
|
|
18
18
|
recordLiveCodexModels,
|
|
19
|
+
recordLiveKimiCodeModels,
|
|
19
20
|
recordLiveProviderModels,
|
|
20
21
|
setOpenAIOauthAccountScope,
|
|
21
22
|
setAntigravityAccountScope,
|
|
@@ -26,7 +27,7 @@ import { openaiCompatDef } from "./providers/openai-compatible-catalog";
|
|
|
26
27
|
import { antigravityAccountScope } from "./model-cache";
|
|
27
28
|
import { getAntigravityUserAgent, resolveAntigravityProjectId } from "./providers/antigravity";
|
|
28
29
|
import { discoverGoogleProjectId, ANTIGRAVITY_DISCOVERY_METADATA } from "../auth/flows/google-project";
|
|
29
|
-
|
|
30
|
+
import { getKimiCommonHeaders } from "../auth/flows/kimi";
|
|
30
31
|
export interface ProviderModelsResult {
|
|
31
32
|
provider: ProviderName;
|
|
32
33
|
/** Discovered model ids (provider-qualified where the router expects it). */
|
|
@@ -185,6 +186,15 @@ export function discoveryRequest(
|
|
|
185
186
|
return { url: "https://api.x.ai/v1/models", headers: token ? { Authorization: `Bearer ${token}` } : {} };
|
|
186
187
|
}
|
|
187
188
|
case "kimi": {
|
|
189
|
+
if (cred?.kind === "oauth") {
|
|
190
|
+
return {
|
|
191
|
+
url: "https://api.kimi.com/coding/v1/models",
|
|
192
|
+
headers: {
|
|
193
|
+
...getKimiCommonHeaders(),
|
|
194
|
+
Authorization: `Bearer ${cred.token}`,
|
|
195
|
+
},
|
|
196
|
+
};
|
|
197
|
+
}
|
|
188
198
|
const token = cred?.kind === "api_key" ? cred.token : "";
|
|
189
199
|
return { url: "https://api.moonshot.ai/v1/models", headers: token ? { Authorization: `Bearer ${token}` } : {} };
|
|
190
200
|
}
|
|
@@ -212,7 +222,7 @@ function isGeminiChatModel(id: string): boolean {
|
|
|
212
222
|
}
|
|
213
223
|
|
|
214
224
|
type CodexModelRow = { slug?: string; id?: string; visibility?: string; supported_in_api?: boolean; priority?: number };
|
|
215
|
-
type AntigravityModelRow = { slug?: string; id?: string; name?: string; isInternal?: boolean; model?: string };
|
|
225
|
+
type AntigravityModelRow = { slug?: string; id?: string; name?: string; displayName?: string; isInternal?: boolean; model?: string };
|
|
216
226
|
|
|
217
227
|
function normalizeAntigravityModelId(id: string): string {
|
|
218
228
|
return id.replace(/^models\//, "").replace(/^antigravity\//, "");
|
|
@@ -250,8 +260,9 @@ export function parseModelsBody(provider: ProviderName, body: unknown, opts: { o
|
|
|
250
260
|
// (MODEL_PLACEHOLDER_*) and must never be surfaced. The response's OWN
|
|
251
261
|
// metadata decides what to show — no hard-coded model lists:
|
|
252
262
|
// Agent sorts and tiered model ids are complementary chat offerings, not
|
|
253
|
-
// interchangeable allowlists. Include both plus the declared default
|
|
254
|
-
//
|
|
263
|
+
// interchangeable allowlists. Include both plus the declared default and
|
|
264
|
+
// named non-recommended chat models; exclude explicit non-chat roles and
|
|
265
|
+
// unnamed unreferenced rows.
|
|
255
266
|
const payload = body as {
|
|
256
267
|
models?: Record<string, AntigravityModelRow> | AntigravityModelRow[];
|
|
257
268
|
agentModelSorts?: { groups?: { modelIds?: string[] }[] }[];
|
|
@@ -280,13 +291,16 @@ export function parseModelsBody(provider: ProviderName, body: unknown, opts: { o
|
|
|
280
291
|
if (typeof payload.defaultAgentModelId === "string") agentIds.add(normalizeAntigravityModelId(payload.defaultAgentModelId));
|
|
281
292
|
const hasChatModelMetadata = Array.isArray(payload.agentModelSorts)
|
|
282
293
|
|| payload.tieredModelIds !== undefined || payload.defaultAgentModelId !== undefined;
|
|
283
|
-
const
|
|
294
|
+
const explicitNonChat = new Set([
|
|
284
295
|
...roleIds(payload.tabModelIds),
|
|
285
296
|
...roleIds(payload.imageGenerationModelIds),
|
|
286
297
|
...roleIds(payload.audioTranscriptionModelIds),
|
|
298
|
+
...deprecated,
|
|
299
|
+
]);
|
|
300
|
+
const nonChat = new Set([
|
|
301
|
+
...explicitNonChat,
|
|
287
302
|
...roleIds(payload.commitMessageModelIds),
|
|
288
303
|
...roleIds(payload.mqueryModelIds),
|
|
289
|
-
...deprecated,
|
|
290
304
|
]);
|
|
291
305
|
const rawModels = payload.models;
|
|
292
306
|
const entries = Array.isArray(rawModels)
|
|
@@ -297,7 +311,10 @@ export function parseModelsBody(provider: ProviderName, body: unknown, opts: { o
|
|
|
297
311
|
.filter(([id, model]) =>
|
|
298
312
|
id.length > 0 &&
|
|
299
313
|
model?.isInternal !== true &&
|
|
300
|
-
|
|
314
|
+
!explicitNonChat.has(id) &&
|
|
315
|
+
(hasChatModelMetadata
|
|
316
|
+
? agentIds.size > 0 && (agentIds.has(id) || (!nonChat.has(id) && typeof model?.displayName === "string" && model.displayName.trim().length > 0))
|
|
317
|
+
: !nonChat.has(id)))
|
|
301
318
|
.map(([id]) => `antigravity/${id}`);
|
|
302
319
|
}
|
|
303
320
|
if (provider === "gemini") {
|
|
@@ -578,6 +595,7 @@ export async function listProviderModels(
|
|
|
578
595
|
...(source === "oauth" && scope.accountId ? { accountId: scope.accountId } : {}),
|
|
579
596
|
});
|
|
580
597
|
if (provider === "openai" && source === "oauth" && !baseUrl) recordLiveCodexModels(allModels, oauthAccountId);
|
|
598
|
+
if (provider === "kimi" && source === "oauth") recordLiveKimiCodeModels(allModels);
|
|
581
599
|
return {
|
|
582
600
|
provider,
|
|
583
601
|
models,
|
|
@@ -652,6 +670,12 @@ export async function discoverModels(
|
|
|
652
670
|
return [primary, await listProviderModels(p, { ...discoveryOpts, baseUrl: undefined, preferOAuth: true, codexCatalog: true })];
|
|
653
671
|
}
|
|
654
672
|
}
|
|
673
|
+
if (p === "kimi" && primary.source !== "oauth") {
|
|
674
|
+
const credential = await resolveCredential("kimi");
|
|
675
|
+
if (credential.kind === "oauth") {
|
|
676
|
+
return [primary, await listProviderModels(p, { ...discoveryOpts, preferOAuth: true })];
|
|
677
|
+
}
|
|
678
|
+
}
|
|
655
679
|
return [primary];
|
|
656
680
|
}),
|
|
657
681
|
);
|
package/src/ai/model-manager.ts
CHANGED
|
@@ -6,7 +6,7 @@ import "./register-providers"; // side-effect: registers built-in adapters into
|
|
|
6
6
|
import type { CallOptions, Message, ProviderAdapter, ProviderName } from "./types";
|
|
7
7
|
import { expandAlias, resolveModelId, effectiveAliasesFor, BUILTIN_ALIASES } from "./model-registry";
|
|
8
8
|
import { findCatalogEntry, type ModelCatalogEntry } from "./model-catalog-compat";
|
|
9
|
-
import { toProviderModel, CODEX_MODELS, KIMI_CODE_MODELS, findCatalogModel, isCodexModel, findLiveCatalogModel } from "./model-catalog";
|
|
9
|
+
import { toProviderModel, CODEX_MODELS, KIMI_CODE_MODELS, findCatalogModel, isCodexModel, isKimiCodeModel, findLiveCatalogModel } from "./model-catalog";
|
|
10
10
|
import { xaiCredential } from "./providers/xai";
|
|
11
11
|
import { allCompatNames, isOpenAICompatProvider } from "./providers/openai-compatible-catalog";
|
|
12
12
|
import { withRetry, defaultRetryable, withConnectionContext, isConnectionError, ConnectionContextError, type RetryOptions } from "../util/retry";
|
|
@@ -329,8 +329,7 @@ export function oauthServesModel(provider: AuthProvider, model: string): boolean
|
|
|
329
329
|
return isCodexModel(model);
|
|
330
330
|
}
|
|
331
331
|
if (provider === "kimi") {
|
|
332
|
-
|
|
333
|
-
return KIMI_CODE_MODELS.includes(wire);
|
|
332
|
+
return isKimiCodeModel(model);
|
|
334
333
|
}
|
|
335
334
|
if (isOAuthProvider(provider) && OAUTH_FLOW_REGISTRY[provider].verifiedEndToEnd === false) return false;
|
|
336
335
|
return true;
|
|
@@ -28,10 +28,10 @@ function antigravityClaudeThinkingBudget(effort: CallOptions["reasoningEffort"])
|
|
|
28
28
|
const ENDPOINTS = [ANTIGRAVITY_DAILY_ENDPOINT, ANTIGRAVITY_SANDBOX_ENDPOINT] as const;
|
|
29
29
|
|
|
30
30
|
export function getAntigravityUserAgent(): string {
|
|
31
|
-
const version = process.env.PI_AI_ANTIGRAVITY_VERSION || "
|
|
31
|
+
const version = process.env.PI_AI_ANTIGRAVITY_VERSION || "2.23.1";
|
|
32
32
|
const os = process.platform === "win32" ? "windows" : process.platform;
|
|
33
33
|
const arch = process.arch === "x64" ? "amd64" : process.arch === "ia32" ? "386" : process.arch;
|
|
34
|
-
return `antigravity/${version} ${os}/${arch}`;
|
|
34
|
+
return `antigravity/hub/${version} ${os}/${arch}`;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
function antigravityModelId(model: string): string {
|
|
@@ -48,6 +48,7 @@ export function geminiThinkingBudget(model: string, effort?: CallOptions["reason
|
|
|
48
48
|
* the documented thought-token burn protection). Expects a lowercased id. */
|
|
49
49
|
function geminiNamedEffort(m: string): CallOptions["reasoningEffort"] | undefined {
|
|
50
50
|
return m.includes("-high") ? "high"
|
|
51
|
+
: m.includes("-medium") ? "medium"
|
|
51
52
|
: m.includes("-low") ? "low"
|
|
52
53
|
: m.includes("thinking") ? "medium"
|
|
53
54
|
: undefined;
|
package/src/commands/auth.ts
CHANGED
|
@@ -152,7 +152,7 @@ async function runAuthLogin(rest: string[]): Promise<void> {
|
|
|
152
152
|
* already succeeded and is not rolled back by this check. Prints only model
|
|
153
153
|
* ids/count — no tokens/secrets.
|
|
154
154
|
*/
|
|
155
|
-
const LIVE_MODEL_REPORT_PROVIDERS = new Set<AuthProvider>(["openai", "anthropic", "antigravity"]);
|
|
155
|
+
const LIVE_MODEL_REPORT_PROVIDERS = new Set<AuthProvider>(["openai", "anthropic", "antigravity", "kimi"]);
|
|
156
156
|
|
|
157
157
|
async function reportLiveModels(provider: AuthProvider): Promise<void> {
|
|
158
158
|
try {
|
|
@@ -249,6 +249,7 @@ async function runAuthImport(rest: string[]): Promise<void> {
|
|
|
249
249
|
}
|
|
250
250
|
const expiryMsg = expires ? fmtExpiry(expires) : "";
|
|
251
251
|
console.log(`Expiry status:${expiryMsg || " valid"}`);
|
|
252
|
+
await reportLiveModels("antigravity");
|
|
252
253
|
} catch (err: any) {
|
|
253
254
|
console.log(`[FAILED] ${err.message}`);
|
|
254
255
|
process.exitCode = 1;
|
|
@@ -335,8 +336,16 @@ async function selectProvider(
|
|
|
335
336
|
console.log(" 1) anthropic (real PKCE OAuth, verified end-to-end)");
|
|
336
337
|
console.log(" 2) openai (real PKCE OAuth, Codex backend)");
|
|
337
338
|
console.log(" 3) gemini (real Google OAuth, Cloud Code Assist)");
|
|
338
|
-
|
|
339
|
-
|
|
339
|
+
console.log(" 4) antigravity (Google Cloud Code Assist OAuth)");
|
|
340
|
+
console.log(" 5) kimi (Kimi Code OAuth device authorization)");
|
|
341
|
+
const ans = (await rl.question("Choose [1-5]: ")).trim();
|
|
342
|
+
const map: Record<string, AuthProvider> = {
|
|
343
|
+
"1": "anthropic",
|
|
344
|
+
"2": "openai",
|
|
345
|
+
"3": "gemini",
|
|
346
|
+
"4": "antigravity",
|
|
347
|
+
"5": "kimi",
|
|
348
|
+
};
|
|
340
349
|
const p = map[ans];
|
|
341
350
|
if (!p) {
|
|
342
351
|
console.log("Invalid choice.");
|
package/src/commands/provider.ts
CHANGED
|
@@ -31,6 +31,7 @@ import {
|
|
|
31
31
|
normalizeProviderId,
|
|
32
32
|
} from "../ai/providers/custom-providers";
|
|
33
33
|
import { listProviderModels } from "../ai/model-discovery";
|
|
34
|
+
import { writeModelCache } from "../ai/model-cache";
|
|
34
35
|
import { describeProvider } from "../ai/provider-status";
|
|
35
36
|
|
|
36
37
|
const USAGE = [
|
|
@@ -186,6 +187,7 @@ async function probe(id: string, opts: { failOnError: boolean }): Promise<void>
|
|
|
186
187
|
if (shown.length) console.log(` ${shown.join(", ")}${result.models.length > shown.length ? ", …" : ""}`);
|
|
187
188
|
const first = result.models[0];
|
|
188
189
|
console.log(` status : OK — use it with 'jeo launch --model ${first ? qualify(first) : `${id}/<model>`}'`);
|
|
190
|
+
await writeModelCache([result]);
|
|
189
191
|
return;
|
|
190
192
|
}
|
|
191
193
|
|
|
@@ -76,6 +76,7 @@ export function buildEnabledProviders(config: Config): string[] {
|
|
|
76
76
|
if (cfg.providers?.anthropic || cfg.oauth?.anthropic) enabled.push("anthropic");
|
|
77
77
|
if (cfg.providers?.openai || cfg.oauth?.openai) enabled.push("openai");
|
|
78
78
|
if (cfg.providers?.gemini || cfg.oauth?.gemini || cfg.providers?.antigravity || cfg.oauth?.antigravity) enabled.push("google-oauth");
|
|
79
|
+
if (cfg.providers?.kimi || cfg.oauth?.kimi) enabled.push("kimi");
|
|
79
80
|
if (cfg.ollamaBaseUrl) enabled.push(`ollama(${cfg.ollamaBaseUrl})`);
|
|
80
81
|
if (cfg.openaiBaseUrl) enabled.push(`openai-compatible(${cfg.openaiBaseUrl})`);
|
|
81
82
|
return enabled;
|
package/src/commands/setup.ts
CHANGED
|
@@ -24,12 +24,14 @@ function reportModelChoice(r: { warning?: string; suggestions: string[] }): void
|
|
|
24
24
|
if (r.suggestions.length) console.log(` Did you mean: ${r.suggestions.join(", ")}?`);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
type ProviderChoice = "anthropic" | "openai" | "gemini" | "ollama" | "lmstudio" | "openai-compatible";
|
|
27
|
+
type ProviderChoice = "anthropic" | "openai" | "gemini" | "antigravity" | "kimi" | "ollama" | "lmstudio" | "openai-compatible";
|
|
28
28
|
|
|
29
29
|
const DEFAULT_MODELS: Record<ProviderChoice, string> = {
|
|
30
30
|
anthropic: "claude-sonnet-4-6",
|
|
31
31
|
openai: "gpt-4o",
|
|
32
32
|
gemini: "gemini-2.0-flash",
|
|
33
|
+
antigravity: "antigravity/gemini-3-flash",
|
|
34
|
+
kimi: "kimi-k2.5",
|
|
33
35
|
ollama: "ollama/llama3.1:8b",
|
|
34
36
|
lmstudio: "openai/local-model",
|
|
35
37
|
"openai-compatible": "openai/local-model",
|
|
@@ -87,16 +89,19 @@ export async function runSetupCommand(): Promise<void> {
|
|
|
87
89
|
console.log(" 1) anthropic — Claude (API key or OAuth bearer)");
|
|
88
90
|
console.log(" 2) openai — GPT (API key or OAuth bearer)");
|
|
89
91
|
console.log(" 3) gemini — Google AI Studio (API key or OAuth bearer)");
|
|
90
|
-
console.log(" 4)
|
|
91
|
-
console.log(" 5)
|
|
92
|
-
console.log(" 6)
|
|
93
|
-
console.log(" 7)
|
|
94
|
-
|
|
95
|
-
|
|
92
|
+
console.log(" 4) antigravity — Google Cloud Code Assist (OAuth)");
|
|
93
|
+
console.log(" 5) kimi — Kimi / Moonshot (API key or Kimi Code OAuth)");
|
|
94
|
+
console.log(" 6) ollama — local Ollama (no auth)");
|
|
95
|
+
console.log(" 7) lmstudio — local LM Studio (OpenAI-compatible)");
|
|
96
|
+
console.log(" 8) openai-compatible — custom OpenAI-compatible (vLLM, llama-cpp-server, ...)");
|
|
97
|
+
console.log(" 9) skip — keep existing values, just change defaults\n");
|
|
98
|
+
|
|
99
|
+
const sel = (await rl.question("Configure which provider? [1-9]: ")).trim();
|
|
96
100
|
const map: Record<string, ProviderChoice | "skip"> = {
|
|
97
101
|
"1": "anthropic", "2": "openai", "3": "gemini",
|
|
98
|
-
"4": "
|
|
99
|
-
"7": "
|
|
102
|
+
"4": "antigravity", "5": "kimi",
|
|
103
|
+
"6": "ollama", "7": "lmstudio", "8": "openai-compatible",
|
|
104
|
+
"9": "skip",
|
|
100
105
|
};
|
|
101
106
|
const choice = map[sel] ?? "skip";
|
|
102
107
|
|
|
@@ -108,7 +113,7 @@ export async function runSetupCommand(): Promise<void> {
|
|
|
108
113
|
next.providers = next.providers || {};
|
|
109
114
|
next.oauth = next.oauth || {};
|
|
110
115
|
|
|
111
|
-
if (choice === "anthropic" || choice === "openai" || choice === "gemini") {
|
|
116
|
+
if (choice === "anthropic" || choice === "openai" || choice === "gemini" || choice === "antigravity" || choice === "kimi") {
|
|
112
117
|
const authMode = (
|
|
113
118
|
await rl.question("Auth mode: (b)rowser OAuth login, (t)oken paste, or api (k)ey? [b]: ")
|
|
114
119
|
).trim().toLowerCase();
|
|
@@ -223,7 +228,7 @@ export async function runSetupCommand(): Promise<void> {
|
|
|
223
228
|
rl.close();
|
|
224
229
|
|
|
225
230
|
// Drop empty oauth/providers to keep config tidy.
|
|
226
|
-
if (next.oauth &&
|
|
231
|
+
if (next.oauth && Object.keys(next.oauth).length === 0) delete next.oauth;
|
|
227
232
|
|
|
228
233
|
await saveGlobalConfig(next);
|
|
229
234
|
console.log("\n[SUCCESS] Configuration saved to ~/.jeo/config.json");
|