feat: Add Antigravity provider integration + fix native mode startup
Some checks failed
Release Binaries / release (push) Has been cancelled

- Added Antigravity AI provider with Google OAuth authentication
- New integration client (antigravity.ts) with automatic endpoint fallback
- API routes for /api/antigravity/* (models, auth-status, test, chat)
- AntigravitySettings.tsx for Advanced Settings panel
- Updated session-api.ts and session-actions.ts for provider routing
- Updated opencode.jsonc with Antigravity plugin and 11 models:
  - Gemini 3 Pro Low/High, Gemini 3 Flash
  - Claude Sonnet 4.5 (+ thinking variants)
  - Claude Opus 4.5 (+ thinking variants)
  - GPT-OSS 120B Medium

- Fixed native mode startup error (was trying to launch __nomadarch_native__ as binary)
- Native mode workspaces now skip binary launch and are immediately ready
This commit is contained in:
Gemini AI
2025-12-27 04:01:38 +04:00
Unverified
parent 4aa4795d4b
commit bb1c0d81f2
10 changed files with 1747 additions and 9 deletions

View File

@@ -249,14 +249,83 @@ async function fetchZAIProvider(): Promise<Provider | null> {
}
}
function getStoredAntigravityToken():
| { access_token: string; expires_in: number; created_at: number }
| null {
if (typeof window === "undefined") return null
try {
const raw = window.localStorage.getItem(getUserScopedKey("antigravity_oauth_token"))
if (!raw) return null
return JSON.parse(raw)
} catch {
return null
}
}
function isAntigravityTokenValid(token: { expires_in: number; created_at: number } | null): boolean {
if (!token) return false
const createdAt = token.created_at > 1e12 ? Math.floor(token.created_at / 1000) : token.created_at
const expiresAt = (createdAt + token.expires_in) * 1000 - 300000
return Date.now() < expiresAt
}
async function fetchAntigravityProvider(): Promise<Provider | null> {
// Check if user is authenticated with Antigravity (Google OAuth)
const token = getStoredAntigravityToken()
if (!isAntigravityTokenValid(token)) {
// Not authenticated - try to fetch models anyway (they show as available but require auth)
try {
const data = await fetchJson<{ models?: Array<{ id: string; name: string; limit?: Model["limit"] }> }>(
"/api/antigravity/models",
)
const models = Array.isArray(data?.models) ? data?.models ?? [] : []
if (models.length === 0) return null
return {
id: "antigravity",
name: "Antigravity (Google OAuth)",
models: models.map((model) => ({
id: model.id,
name: model.name,
providerId: "antigravity",
limit: model.limit,
})),
defaultModelId: "gemini-3-pro-high",
}
} catch {
return null
}
}
// User is authenticated - fetch full model list
const data = await fetchJson<{ models?: Array<{ id: string; name: string; limit?: Model["limit"] }> }>(
"/api/antigravity/models",
)
const models = Array.isArray(data?.models) ? data?.models ?? [] : []
if (models.length === 0) return null
return {
id: "antigravity",
name: "Antigravity (Google OAuth)",
models: models.map((model) => ({
id: model.id,
name: model.name,
providerId: "antigravity",
limit: model.limit,
})),
defaultModelId: "gemini-3-pro-high",
}
}
async function fetchExtraProviders(): Promise<Provider[]> {
const [ollama, zen, qwen, zai] = await Promise.all([
const [ollama, zen, qwen, zai, antigravity] = await Promise.all([
fetchOllamaCloudProvider(),
fetchOpenCodeZenProvider(),
fetchQwenOAuthProvider(),
fetchZAIProvider(),
fetchAntigravityProvider(),
])
return [ollama, zen, qwen, zai].filter((provider): provider is Provider => Boolean(provider))
return [ollama, zen, qwen, zai, antigravity].filter((provider): provider is Provider => Boolean(provider))
}
function removeDuplicateProviders(base: Provider[], extras: Provider[]): Provider[] {