feat(antigravity): initial steps for Antigravity anti-ban alignment
Cherry-picked from decolua/9router#141 (author: LinearSakana / zx <me@char.moe>) - Implement client identity spoofing with numeric enums (ideType: 9, pluginType: 2) - Add runtime platform detection for User-Agent and metadata - Implement per-connection session ID caching (binary-compatible format) - Add ANTIGRAVITY_HEADERS (X-Client-Name, X-Client-Version, x-goog-api-client) - Add X-Machine-Session-Id header injection - Align metadata/mode parameters across all Antigravity API calls - Implement double injection for system prompt (raw + [ignore] wrapped) - Rename internal anti-loop header to x-request-source for anonymity Skipped: commit 6 (signature side-channel caching) — kept DEFAULT_THINKING_GEMINI_SIGNATURE Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
9fbd6e619d
commit
a229d79158
11 files changed
+309
-121
No files matched your search
@@ -1,4 +1,5 @@
|
||||
import crypto from "crypto";
|
||||
import { platform, arch } from "os";
|
||||
import open from "open";
|
||||
import { ANTIGRAVITY_CONFIG } from "../constants/oauth.js";
|
||||
import { getServerCredentials } from "../config/index.js";
|
||||
@@ -92,12 +93,20 @@ export class AntigravityService {
|
||||
|
||||
/**
|
||||
* Get metadata object for API calls
|
||||
* Uses numeric enum values matching Antigravity binary specifications
|
||||
*/
|
||||
getMetadata() {
|
||||
const os = platform();
|
||||
const architecture = arch();
|
||||
let platformEnum = 0; // UNSPECIFIED
|
||||
if (os === "darwin") platformEnum = architecture === "arm64" ? 2 : 1;
|
||||
else if (os === "linux") platformEnum = architecture === "arm64" ? 4 : 3;
|
||||
else if (os === "win32") platformEnum = 5;
|
||||
|
||||
return {
|
||||
ideType: "IDE_UNSPECIFIED",
|
||||
platform: "PLATFORM_UNSPECIFIED",
|
||||
pluginType: "GEMINI",
|
||||
ideType: 9, // ANTIGRAVITY
|
||||
platform: platformEnum,
|
||||
pluginType: 2, // GEMINI
|
||||
};
|
||||
}
|
||||
|
||||
@@ -108,7 +117,7 @@ export class AntigravityService {
|
||||
const response = await fetch(this.config.loadCodeAssistEndpoint, {
|
||||
method: "POST",
|
||||
headers: this.getApiHeaders(accessToken),
|
||||
body: JSON.stringify({ metadata: this.getMetadata() }),
|
||||
body: JSON.stringify({ metadata: this.getMetadata(), mode: 1 }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
@@ -117,7 +126,7 @@ export class AntigravityService {
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
|
||||
// Extract project ID
|
||||
let projectId = data.cloudaicompanionProject;
|
||||
if (typeof projectId === 'object' && projectId !== null && projectId.id) {
|
||||
@@ -149,6 +158,7 @@ export class AntigravityService {
|
||||
tierId,
|
||||
metadata: this.getMetadata(),
|
||||
cloudaicompanionProject: projectId,
|
||||
mode: 1,
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -166,7 +176,7 @@ export class AntigravityService {
|
||||
async completeOnboarding(accessToken, projectId, tierId, maxRetries = 10) {
|
||||
for (let i = 0; i < maxRetries; i++) {
|
||||
const result = await this.onboardUser(accessToken, projectId, tierId);
|
||||
|
||||
|
||||
if (result.done === true) {
|
||||
// Extract final project ID from response
|
||||
let finalProjectId = projectId;
|
||||
@@ -301,7 +311,7 @@ export class AntigravityService {
|
||||
|
||||
// Load Code Assist to get project ID and tier
|
||||
const { projectId, tierId } = await this.loadCodeAssist(tokens.access_token);
|
||||
|
||||
|
||||
if (!projectId) {
|
||||
throw new Error("No Google Cloud Project found. Please ensure you have a GCP project with Gemini Code Assist enabled.");
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user