feat(ai,coding-agent): Google fingerprint hardening

providers/google-gemini-cli:
- parseGeminiCliCredentials() handles legacy, alias (project_id/refresh/expires),
  and enriched credential JSON formats
- shouldRefreshGeminiCliCredentials() + refreshGeminiCliCredentialsIfNeeded()
  proactively refresh OAuth tokens 60s before expiry for both providers
- normalizeAntigravityTools() converts parametersJsonSchema -> parameters
  in function declarations for Antigravity compatibility
- VALIDATED tool calling config applied for Antigravity + Claude model combos
- maxOutputTokens removed from generation config for Antigravity non-Claude models
- Antigravity system instruction injection scoped to Claude + gemini-3-pro-high models
- Antigravity session ID: signed decimal int63 derived from SHA-256 of first user
  message (or random bounded int63), replacing truncated hex hash
- Antigravity requestId uses agent-{uuid}; non-Antigravity requests omit
  requestId/userAgent/requestType from payload
- ANTIGRAVITY_DAILY_ENDPOINT corrected to daily-cloudcode-pa.googleapis.com;
  sandbox kept as fallback
- ANTIGRAVITY_SYSTEM_INSTRUCTION exported

oauth/google-antigravity:
- PKCE removed from OAuth flow (no code_challenge)
- loadCodeAssist metadata ideType changed to ANTIGRAVITY
- discoverProject uses single production endpoint; falls back to onboardUser LRO
  (up to 5 retries, 2s interval) instead of hardcoded default project ID
- ANTIGRAVITY_LOAD_CODE_ASSIST_METADATA exported

oauth/google-gemini-cli:
- PKCE removed from OAuth flow

oauth/index:
- getOAuthApiKey includes refreshToken, expiresAt, email, accountId in
  Gemini/Antigravity JSON payload for proactive refresh support

discovery/antigravity:
- Tries production daily endpoint first, sandbox as fallback
- Removed recommended/agentModelSorts filter; applies denylist instead
- ANTIGRAVITY_DISCOVERY_DENYLIST filters low-quality/internal models
- Request body no longer includes project field

coding-agent:
- gemini_image: corrected responseModalities to uppercase IMAGE/TEXT
- Gemini web search: endpoint fallback (daily->sandbox) with retry on 429/5xx,
  aligned Antigravity request metadata, ANTIGRAVITY_SYSTEM_INSTRUCTION injection
- buildGeminiRequestTools() helper for composable googleSearch/codeExecution/urlContext
- Web search schema: expose max_tokens, temperature, num_search_results params
- Web search: explicit provider falls back to auto chain when unavailable

Tests: google-antigravity-auth, google-gemini-cli-alignment, web-search-gemini
This commit is contained in:
can1357
2026-02-28 21:17:57 +01:00
parent e7daffdda7
commit 7d0807ec36
15 changed files with 829 additions and 211 deletions
@@ -27,7 +27,7 @@ interface ImageApiKey {
projectId?: string;
}
const responseModalitySchema = StringEnum(["Image", "Text"]);
const responseModalitySchema = StringEnum(["IMAGE", "TEXT"]);
const aspectRatioSchema = StringEnum(["1:1", "3:4", "4:3", "9:16", "16:9"], {
description: "Aspect ratio (1:1, 3:4, 4:3, 9:16, 16:9).",
});
@@ -536,7 +536,7 @@ function buildAntigravityRequest(
contents: [{ role: "user", parts }],
systemInstruction: { parts: [{ text: IMAGE_SYSTEM_INSTRUCTION }] },
generationConfig: {
responseModalities: ["Image"],
responseModalities: ["IMAGE"],
imageConfig,
candidateCount: 1,
},
@@ -788,7 +788,7 @@ export const geminiImageTool: CustomTool<typeof geminiImageSchema, GeminiImageTo
responseModalities: GeminiResponseModality[];
imageConfig?: { aspectRatio?: string; imageSize?: string };
} = {
responseModalities: ["Image"],
responseModalities: ["IMAGE"],
};
if (params.aspect_ratio || params.image_size) {