Skip to content

Plugin-Architektur-Übersicht: Verstehen des internen Designs von OpenCode Antigravity Auth ​

Was Sie nach dem Lernen tun können ​

Dieser Kurs führt Sie tief in das Architekturdesign und die internen Arbeitsprinzipien des Antigravity Auth Plugins ein. Nach Abschluss des Lernens können Sie:

  • Die Modulstruktur des Plugins und die Verantwortlichkeiten jedes Moduls verstehen
  • Den vollständigen Verarbeitungsfluss von Anfragen von OpenCode bis zur Antigravity API beherrschen
  • Das Lastausgleichsmechanismus des Multi-Konto-Managements verstehen
  • Die Arbeitsprinzipien der Sitzungswiederherstellung verstehen
  • Die technischen Details der Anfrageformatkonvertierung beherrschen

Der Kernwert des Plugins ​

Die Kernfunktion des Antigravity Auth Plugins besteht darin, eine "Übersetzungsbrücke" zwischen OpenCode und der Antigravity API aufzubauen:

  1. Protokollkonvertierung - Konvertierung des OpenCode-Anfrageformats in das von der Antigravity API geforderte Format
  2. Authentifizierungsmanagement - Sichere Beschaffung und Aktualisierung von Zugriffstoken über Google OAuth 2.0 PKCE
  3. Lastausgleich - Pooling mehrerer Konten, automatische Rotation zur Vermeidung von Ratenbegrenzungen
  4. Fehlerwiederherstellung - Automatische Erkennung und Reparatur von Sitzungsunterbrechungsproblemen

Warum ist Architekturverständnis wichtig?

Das Verständnis der Plugin-Architektur hilft Ihnen:

  • Schnell das Modul mit dem Problem zu lokalisieren
  • Die Wirkungsbereiche von Konfigurationsoptionen zu verstehen
  • Multi-Konto-Nutzungsstrategien zu optimieren
  • An der Plugin-Entwicklung und Fehlersuche teilzunehmen

Modulstruktur-Übersicht ​

Das Plugin verwendet eine geschichtete Architektur mit klaren Verantwortlichkeiten für jedes Modul:

mermaid
graph TD
    subgraph Präsentationsschicht
        A[OpenCode Client]
    end

    subgraph Pluginschicht
        B[plugin.ts - Haupteinstieg]
        C[accounts.ts - AccountManager]
        D[request.ts - Transform]
        E[recovery - Sitzungswiederherstellung]
        F[config - Konfiguration]
    end

    subgraph Authentifizierungsschicht
        G[oauth.ts - OAuth]
        H[auth.ts - Token-Verwaltung]
        I[server.ts - Callback-Server]
    end

    subgraph Transformationsschicht
        J[claude.ts - Claude]
        K[gemini.ts - Gemini]
        L[model-resolver - Modellerkennung]
        M[request-helpers - Schema-Cleanup]
    end

    subgraph Persistenzschicht
        N[storage.ts - Datenspeicherung]
        O[cache.ts - Signatur-Cache]
    end

    subgraph Externe Dienste
        P[Google OAuth]
        Q[Antigravity API]
        R[Gemini CLI API]
    end

    A -->|fetch intercept| B
    B -->|load| C
    B -->|transform| D
    B -->|handle error| E
    B -->|load| F

    B -->|authorize| G
    B -->|refresh| H
    B -->|start| I

    D -->|detect model| L
    D -->|claude| J
    D -->|gemini| K
    D -->|clean| M
    E -->|inject result| D

    C -->|save/load| N
    D -->|get/set| O
    G -->|exchange token| P
    H -->|refresh token| P
    D -->|send request| Q
    D -->|send request| R

Verantwortlichkeiten der Module ​

ModulDateiVerantwortlichkeit
Haupteinstiegplugin.tsfetch-Interceptor, Plugin-Initialisierung, Event-Handling
Kontenverwaltungaccounts.tsMulti-Konto-Pool, Lastausgleichsstrategie, Ratenbegrenzungs-Tracking
Anfragenkonvertierungrequest.tsAnfrageformatkonvertierung, Antwort-Streaming-Verarbeitung
Modellkonvertierungtransform/Claude/Gemini-spezifische Konvertierungslogik
OAuth-Authentifizierungantigravity/oauth.tsPKCE-Authentifizierungsablauf, Token-Austausch
Sitzungswiederherstellungrecovery/Fehlererkennung, automatische Reparatur unterbrochener Sitzungen
Konfigurationsmanagementconfig/Konfigurationsladen, Schema-Validierung
Speicherschichtstorage.tsKontenpersistierung (JSON-Datei)
Cache-Schichtcache.tsSignatur-Cache, Reduzierung wiederholter Berechnungen
Debug-Protokolldebug.tsStrukturierte Protokolle, Fehlersuche

Anfrageverarbeitungsablauf ​

Wenn eine Modellanfrage von OpenCode gesendet wird, durchläuft das Plugin einen vollständigen Verarbeitungslink:

mermaid
sequenceDiagram
    participant OC as OpenCode Client
    participant PL as plugin.ts
    participant AM as AccountManager
    participant RT as Request Transform
    participant AA as Antigravity API

    OC->>PL: fetch(generativeLanguage.googleapis.com)
    PL->>PL: isGenerativeLanguageRequest()
    PL->>AM: getCurrentOrNextForFamily()
    AM-->>PL: { account, token }

    PL->>PL: accessTokenExpired()?
    alt Token Ablaufen
        PL->>PL: refreshAccessToken()
        PL->>AM: updateFromAuth()
    end

    PL->>RT: prepareAntigravityRequest()
    RT->>RT: Modelltyp erkennen
    RT->>RT: Anfrageformat konvertieren
    RT->>RT: Schema bereinigen
    RT->>RT: Thinking-Konfiguration injizieren
    RT-->>PL: { request, init, streaming }

    PL->>AA: POST {request} + Bearer Token
    AA-->>PL: SSE Stream
    PL->>PL: transformAntigravityResponse()
    PL-->>OC: Transformierter Stream

Schritt-für-Schritt-Erklärung ​

Schritt 1: Anfragen-Abfangen

  • Das Plugin fängt alle Anfragen an generativelanguage.googleapis.com über den fetch-Interceptor ab
  • Verwendet isGenerativeLanguageRequest() zur Bestimmung, ob es eine Antigravity-bezogene Anfrage ist
  • Nicht-Ziel-Anfragen werden direkt durchgeleitet, um andere Funktionen nicht zu beeinträchtigen

Schritt 2: Kontenauswahl

  • Wählt ein verfügbares Konto aus dem Kontenpool (basierend auf der konfigurierten Strategie: sticky/round-robin/hybrid)
  • Überprüft, ob das Token abgelaufen ist, und aktualisiert es automatisch, falls erforderlich
  • Wendet PID-Offset an (falls aktiviert), um gleichmäßige Kontenverteilung in Multi-Agent-Szenarien zu gewährleisten

Schritt 3: Anfragenkonvertierung (request.ts)

  • Modellerkennung: Identifiziert, ob es ein Claude- oder Gemini-Modell ist
  • Thinking-Verarbeitung:
    • Claude: Entfernt alle historischen Thinking-Blöcke, um Signaturkonflikte zu vermeiden
    • Gemini: Fügt thinkingConfig-Konfiguration hinzu
  • Tool-Konvertierung: Konvertiert OpenCode-Tools in das functionDeclarations-Format
  • Schema-Bereinigung: Entfernt nicht unterstützte JSON-Schema-Felder (const, $ref, $defs, usw.)
  • Anfragenkapselung: Verpackt in das Format { project, model, request: {...} }

Schritt 4: Anfrage senden

  • Fügt Antigravity-spezifische Headers hinzu (User-Agent, Client-Metadata)
  • Verwendet Bearer Token zur Authentifizierung
  • Unterstützt Endpoint-Fallback (daily → autopush → prod)

Schritt 5: Antwortkonvertierung

  • Empfängt SSE-Stream, zeilenweise Konvertierung
  • Konvertiert thought: true zu type: "reasoning"
  • Cacht Thinking-Signaturen für nachfolgende Anfragen
  • Entpackt inneres response-Objekt, behält Formatkonsistenz bei

Antwortverarbeitungsablauf ​

Die Antwortverarbeitung umfasst hauptsächlich Stream-Konvertierung und Sitzungswiederherstellung:

mermaid
flowchart TD
    A[SSE Stream Empfangen] --> B[SSE Zeilen Parsen]
    B --> C{Ist Thinking Block?}
    C -->|Ja| D[thought: true → type: reasoning]
    C -->|Nein| E[Durchleiten]
    D --> F[thoughtSignature Cachen]
    E --> F
    F --> G{Verschachteltes response?}
    G -->|Ja| H[Inneres Objekt Entpacken]
    G -->|Nein| I[An Client Weiterleiten]
    H --> I
    I --> J{Sitzungsfehler?}
    J -->|Ja| K[Wiederherstellung Auslösen]
    J -->|Nein| L[Abschließen]
    K --> M[detectErrorType]
    M --> N{Wiederherstellbar?}
    N -->|Ja| O[Synthetic Nachrichten Injizieren]
    N -->|Nein| P[Fehler Melden]
    O --> Q[Continue Senden]
    Q --> L

Schlüsselverarbeitungsmechanismen ​

1. Thinking Block Konvertierung

Das Thinking Block Format, das von der Antigravity API zurückgegeben wird, ist:

json
{ "thought": true, "text": "Thinking-Inhalt" }

Das Plugin konvertiert es in das OpenCode-kompatible Format:

json
{ "type": "reasoning", "reasoning": "Thinking-Inhalt" }

2. Signatur-Caching

Claude- und Gemini 3 Modelle erfordern übereinstimmende Thinking Block Signaturen in Mehrfachdialogen:

  • Extrahiert thoughtSignature aus der Antwort
  • Speichert mit cacheSignature() im Speicher und auf Festplatte
  • Ruft beim nächsten Request mit getCachedSignature() ab und injiziert

Warum ist Signatur-Caching erforderlich?

Die Claude- und Gemini 3 APIs erfordern, dass Thinking-Blöcke vor Tool-Aufrufen korrekte Signaturen haben. Signatur-Caching kann:

  • Anfragefehler durch Signaturfehler vermeiden
  • Wiederholte Generierung desselben Thinking-Inhalts reduzieren
  • Kontinuität in Mehrfachdialogen verbessern

3. Sitzungswiederherstellung

Wenn ein Sitzungsfehler erkannt wird:

  1. Fehler wird durch das session.error Ereignis abgefangen
  2. Ruft detectErrorType() auf, um zu beurteilen, ob es wiederherstellbar ist
  3. Für tool_result_missing Fehler:
    • Extrahiert fehlgeschlagene tool_use IDs
    • Injiziert synthetic tool_result Nachrichten
    • Sendet automatisch "continue" (falls aktiviert)
  4. Für Thinking Block Reihenfolgefehler:
    • Analysiert Dialogzustand
    • Schließt beschädigten Turn
    • Startet neuen Turn, lässt Modell neu generieren

Detaillierte Erklärung der Kernmechanismen ​

OAuth-Authentifizierungsmechanismus ​

Das Plugin verwendet den OAuth 2.0 mit PKCE (Proof Key for Code Exchange) Ablauf:

mermaid
flowchart LR
    A[Benutzer führt opencode auth login aus] --> B[PKCE-Schlüsselpaar generieren]
    B --> C[Autorisierungs-URL erstellen]
    C --> D[Lokaler Server starten]
    D --> E[Browser-Autorisierungsseite öffnen]
    E --> F[Benutzer autorisiert]
    F --> G[Callback-Code empfangen]
    G --> H[Zugriffstoken austauschen]
    H --> I[Project ID abrufen]
    I --> J[In antigravity-accounts.json speichern]

PKCE-Sicherheit:

  • Generiert zufällige code_verifier und code_challenge
  • Autorisierungs-URL enthält code_challenge, verhindert Man-in-the-Middle-Angriffe
  • Beim Token-Austausch wird code_verifier verifiziert, stellt sicher, dass die Anfrage vom selben Client stammt

Token-Verwaltung:

  • Access Token: Standardmäßig 1 Stunde gültig, automatische Aktualisierung 30 Minuten vor Ablauf
  • Refresh Token: Langfristig gültig, zum Abrufen neuer Access Tokens
  • Persistiert in ~/.config/opencode/antigravity-accounts.json

Multi-Konto-Verwaltungsmechanismus ​

Multi-Konto-Verwaltung ist eine der Kernfunktionen des Plugins und umfasst folgende Schlüsselkomponenten:

1. Kontenpool-Struktur

typescript
interface AccountPool {
  version: 3;
  accounts: Account[];
  activeIndex: number;
  activeIndexByFamily: {
    claude: number;
    gemini: number;
  };
}

2. Kontenauswahlstrategie

StrategieBeschreibungAnwendungsszenario
stickyBeibehaltung des aktuellen Kontos bis zur RatenbegrenzungEinzelne Sitzungsnutzung, Beibehaltung des Prompt-Caches
round-robinJede Anfrage rotiert zum nächsten KontoMehrere Sitzungen parallel, Maximierung des Durchsatzes
hybridGesundheitsbewertung + Token-Bucket + LRU kombinierte EntscheidungStandardstrategie, Balance zwischen Leistung und Zuverlässigkeit

3. Ratenbegrenzungs-Tracking

Jedes Konto wird unabhängig nach Modellfamilie verfolgt:

  • claude: Claude-Modellkontingent
  • gemini-antigravity: Gemini Antigravity-Kontingent
  • gemini-cli: Gemini CLI-Kontingent

Ratenbegrenzungsstatus enthält:

  • rateLimitResetTimes: Zurücksetzungszeiten für jedes Kontingent
  • cooldownEndAt: Konto-Kühlungsendzeit
  • consecutiveFailures: Anzahl aufeinanderfolgender Fehler

4. Dual-Kontingent-Pool (Gemini-exklusiv)

Gemini-Modelle unterstützen zwei unabhängige Kontingentpools:

  • Antigravity-Kontingent: Tägliche Sandbox-Umgebung
  • Gemini CLI-Kontingent: Produktionsumgebung

Durch quota_fallback Konfiguration:

  • Bevorzugte Nutzung des bevorzugten Kontingents (durch Modellsuffix bestimmt)
  • Fallback auf Backup-Kontingent, wenn bevorzugtes erschöpft
  • Wechsel zum nächsten Konto, wenn beide Pools erschöpft

5. PID-Offset-Optimierung

Nach Aktivierung von pid_offset_enabled:

  • Verschiedene Prozesse (PIDs) starten mit unterschiedlichen Konten
  • Vermeidung, dass alle Agenten um dasselbe Konto konkurrieren
  • Geeignet für Multi-Agent-Parallelisierungsszenarien

Anfragenkonvertierungsmechanismus ​

Die Anfragenkonvertierung ist der komplexeste Teil des Plugins und erfordert die Handhabung von Protokolldifferenzen zwischen verschiedenen Modellen:

Claude-Modell-Konvertierungspunkte:

  1. Thinking-Block-Verarbeitung

    typescript
    // Entfernen aller historischen Thinking-Blöcke (Vermeidung von Signaturkonflikten)
    const filteredContents = deepFilterThinkingBlocks(contents);
    
    // Aufbau einer neuen thinkingConfig
    const thinkingConfig = {
      budgetTokens: variantThinkingConfig?.budget || DEFAULT_THINKING_BUDGET,
    };
  2. Tool-Schema-Bereinigung

    • Whitelist-Beibehaltung: type, properties, required, description, enum, items
    • Entfernte Felder: const, $ref, $defs, default, examples, additionalProperties, $schema, title
    • Spezielle Konvertierung: const: "value" → enum: ["value"]
  3. Tool-Injektionsparameter-Signatur

    typescript
    injectParameterSignatures(tool, signature) {
      tool.description += `\n\nParameters: ${signature}`;
    }

Gemini-Modell-Konvertierungspunkte:

  1. Thinking-Konfiguration

    typescript
    // Gemini 3 Pro/Flash
    if (isGemini3Model(model)) {
      request.thinkingConfig = {
        thinkingLevel: "high" | "medium" | "low" | "minimal",
      };
    }
    
    // Gemini 2.5
    else if (isGemini2Model(model)) {
      request.thinkingConfig = {
        thinkingLevel: "high" | "medium" | "low",
      };
    }
  2. Google Search Grounding

    typescript
    if (webSearchConfig) {
      request.generationConfig = {
        ...request.generationConfig,
        dynamicRetrievalConfig: {
          mode: webSearchConfig.mode, // "auto" | "off"
          dynamicRetrievalConfig: {
            scoreThreshold: webSearchConfig.threshold, // 0.0 - 1.0
          },
        },
      };
    }
  3. Bildgenerierungskonfiguration

    typescript
    if (isImageGenerationModel(model)) {
      request.generationConfig = {
        ...request.generationConfig,
        responseModalities: ["IMAGE", "TEXT"],
      };
    }

Sitzungswiederherstellungsmechanismus ​

Der Sitzungswiederherstellungsmechanismus stellt sicher, dass Konversationen nach unerwarteten Unterbrechungen fortgesetzt werden können:

1. Fehlererkennung

typescript
function detectErrorType(error: unknown): RecoverableError | null {
  if (errorString.includes("tool_use ids were found without tool_result")) {
    return { type: "tool_result_missing" };
  }
  if (errorString.includes("Expected thinking but found text")) {
    return { type: "thinking_order_error" };
  }
  return null;
}

2. Turn-Grenzerkennung

typescript
// Turn-Grenze = erste Assistant-Nachricht nach User-Nachricht
function analyzeConversationState(messages: Message[]): ConversationState {
  const lastUserMessage = findLastMessageByRole(messages, "user");
  const firstAssistantAfterUser = messages.find(m =>
    m.role === "assistant" && m.timestamp > lastUserMessage.timestamp
  );

  return {
    isTurnStart: true,
    turnAssistantMessage: firstAssistantAfterUser,
  };
}

3. Synthetic-Nachrichten-Injektion

typescript
// Synthetic tool_result injizieren
function createSyntheticErrorResponse(toolUseIds: string[]): Message[] {
  return toolUseIds.map(id => ({
    type: "tool_result",
    tool_use_id: id,
    content: "Operation cancelled",
    isSynthetic: true,
  }));
}

// Beschädigten Turn schließen
function closeToolLoopForThinking(sessionId: string): Message[] {
  return [
    {
      type: "text",
      text: "[Conversation turn closed due to error]",
      isSynthetic: true,
    },
  ];
}

4. Auto-Resume

Nach Aktivierung von auto_resume wird der Wiederherstellungsablauf automatisch den Fortsetzungsbefehl senden:

typescript
await client.session.prompt({
  path: { id: sessionID },
  body: { parts: [{ type: "text", text: config.resume_text }] },
  query: { directory },
});

Lektionszusammenfassung ​

Dieser Kurs analysiert im Detail das Architekturdesign des Antigravity Auth Plugins:

Kernarchitektur:

  • Geschichtetes Moduldesign mit klaren Verantwortlichkeiten
  • Pluginschicht, Authentifizierungsschicht, Transformationsschicht, Persistenzschicht erfüllen jeweils ihre Aufgaben
  • plugin.ts als einheitlicher Einstieg koordiniert alle Module

Anfrageablauf:

  • Abfangen → Kontenauswahl → Token-Aktualisierung → Anfragenkonvertierung → Anfrage senden → Antwortkonvertierung
  • Jeder Schritt hat detaillierte Fehlerbehandlung und Retry-Mechanismen

Schlüsselmechanismen:

  • OAuth 2.0 PKCE: Sicherer Authentifizierungsablauf
  • Multi-Konto-Management: Lastausgleich, Ratenbegrenzungs-Tracking, Dual-Kontingent-Pool
  • Anfragenkonvertierung: Protokollkompatibilität, Schema-Bereinigung, Thinking-Verarbeitung
  • Sitzungswiederherstellung: Automatische Fehlererkennung, Synthetic-Nachrichten-Injektion, Auto-Resume

Das Verständnis dieser Mechanismen wird Ihnen helfen, die Plugin-Konfiguration besser zu nutzen und zu optimieren sowie an der Plugin-Entwicklung und Fehlersuche teilzunehmen.

Vorschau auf die nächste Lektion ​

In der nächsten Lektion lernen wir die Antigravity API interne Spezifikationen kennen.

Sie werden lernen:

  • Anfrage- und Antwortformate der Antigravity API
  • Funktionen und Parameter der einzelnen Endpunkte
  • Bedeutungen von Fehlercodes und Statuscodes
  • Erweiterte Funktionen und experimentelle Features

Anhang: Quellcode-Referenz ​

Klicken Sie zum Anzeigen der Quellcode-Positionen

Aktualisiert am: 2026-01-23

FunktionDateipfadZeilennummer
Plugin-Haupteinstieg, fetch-Interceptorsrc/plugin.ts654-1334
Konten-Manager, Lastausgleichsrc/plugin/accounts.ts1-715
Anfragenkonvertierung, Antwort-Streamingsrc/plugin/request.ts1-1664
Claude-Modellkonvertierungsrc/plugin/transform/claude.tsGesamt
Gemini-Modellkonvertierungsrc/plugin/transform/gemini.tsGesamt
Sitzungswiederherstellungsrc/plugin/recovery/index.tsGesamt
Thinking-Block-Wiederherstellungsrc/plugin/recovery/thinking-recovery.tsGesamt
OAuth-Authentifizierungsrc/antigravity/oauth.ts1-271
Token-Verwaltungsrc/plugin/token.tsGesamt
Konfigurationsschemasrc/plugin/config/schema.ts1-373
Kontenspeicherungsrc/plugin/storage.tsGesamt
Signatur-Cachesrc/plugin/cache.tsGesamt
Debug-Protokollsrc/plugin/debug.tsGesamt

Schlüsselkonstanten:

  • MAX_OAUTH_ACCOUNTS = 10: Maximale Kontenanzahl
  • RATE_LIMIT_DEDUP_WINDOW_MS = 2000: Ratenbegrenzungs-Deduplizierungsfenster (2 Sekunden)
  • RATE_LIMIT_STATE_RESET_MS = 120000: Ratenbegrenzungsstatus-Zurücksetzungszeit (2 Minuten)
  • FAILURE_COOLDOWN_MS = 30000: Konto-Kühlungszeit (30 Sekunden)

Schlüsselfunktionen:

  • createAntigravityPlugin(): Plugin-Haupteinstiegsfunktion
  • prepareAntigravityRequest(): Hauptfunktion zur Anfragenkonvertierung
  • transformAntigravityResponse(): Funktion zur Antwort-Stream-Konvertierung
  • AccountManager.getCurrentOrNextForFamily(): Kontenauswahlfunktion
  • handleSessionRecovery(): Funktion zur Sitzungswiederherstellungsverarbeitung
  • refreshAccessToken(): Token-Aktualisierungsfunktion