webai-to-api

repository·master·Indexed 23 days ago

https://github.com/amm1rr/webai-to-api

A modular web server built with FastAPI and version 0.5.0 that exposes browser-native AI services, such as Google Gemini, through OpenAI-compatible APIs. It features a two-tier abstraction of Providers and Backend Adapters (including WebAPI and Playwright), supporting multimodal file inputs for Gemini WebAPI and a visual dashboard for runtime status and authentication management.

Tokens
29.1K
Snippets
23
Records
173
Agent score
78%

What's inside webai-to-api

  1. How provider routing works

    master

    The system uses a "Thin Gateway" pattern to route requests through three layers:

    1. ProviderFactory: Resolves the logical identity (e.g., gemini, atlas) from the /v1/chat/completions endpoint.
    2. Provider: Represents the logical LLM vendor (e.g., GeminiProvider). It handles vendor-specific logic like tool parsing and prompt transformation.
    3. Adapter: The execution strategy (e.g., Playwright or WebAPI). It handles the technical implementation of driving a browser or calling a REST API.

    Routing via Model Namespaces: To select a browser-native provider, use provider-aware model namespaces in the format: playwright/<provider>/<model>. Example: playwright/gemini/gemini-1.5-pro

  2. Understand the ConversationSnapshot schema

    master

    The system uses a provider-agnostic ConversationSnapshot schema to manage conversation persistence. This schema separates generic conversation metadata from provider-specific internal states to ensure the storage layer remains decoupled from specific AI providers.

    Schema Structure: When a snapshot is serialized, it must contain exactly these fields:

    • conversation_id (primary key)
    • provider_name (string)
    • session_state (dictionary): This field encapsulates all provider-specific internal session states (e.g., Gemini's rid, gem_id, or context_str).
    • schema_version (integer)
    • updated_at (timestamp)
  3. Understand the Streaming Pipeline Event Flow

    master

    The streaming pipeline bridges browser-side DOM events to server-side HTTP streams using a provider-owned binding (e.g., __gemini_bridge).

    Bridge Lifecycle:

    1. Exposure: The binding is exposed on the page.
    2. Registration: Each request registers a unique callback in the provider's registry using its request_id.
    3. Dispatch: The browser script calls the bridge with the request_id and an event type.

    Event Types:

    • ready: Browser-side observer is initialized.
    • started: Authoritative signal that generation has begun.
    • chunk: A new text delta is available.
    • rewrite: Authoritative full-text replacement. Used when the browser renderer updates a previously emitted block.
    • done: Generation is complete.
  4. How the GeminiAuthStateLoader manages authentication state

    master

    The GeminiAuthStateLoader is a dedicated authentication state loader layer responsible for managing the lifecycle of authentication data. It performs three primary functions:

    1. Loading: It reads the canonical state JSON payload from runtime/auth/gemini.json.
    2. Validation: It validates the structure of the JSON file. If the file is syntactically correct, it logs a successful validation. If the file is corrupted or invalid, it catches the parsing exception, logs an invalid state warning, and propagates an error to trigger legacy fallbacks or guest mode.
    3. Translation: It translates the validated canonical state into provider-specific formats, such as:
      • CurlCffi cookie dictionaries for HTTP wrappers.
      • Playwright storageState objects.

    The loader is designed to be stateless and decoupled from specific storage backends to support future extensibility.

  5. Handle Queue Overflow and Request Termination

    master
    When the event buffer reaches its saturation limit, the system treats queue saturation as a terminal request-scoped failure. The active request stream will deterministically transition to a failed state and terminate. This ensures that the request is invalidated rather than silently dropping events, though the broader session liveness is left to be validated by runtime integrity checks.
  6. Apply Pre-Submission Retry Policy and Lease Preservation

    master

    The system uses an exponential backoff retry policy, but its application is strictly governed by the submission boundary:

    Pre-Submission Phase

    (Includes: page acquisition, page readiness checks, authentication verification, and observer preparation)

    • Retries are allowed for transient failures.
    • Lease Preservation: Before initiating a retry, the system MUST fully release the active ManagedPage lease and decrement the active lease count to prevent stale lease holding and lock contention. A fresh lease must be acquired for the next attempt.

    Post-Submission Phase

    (Includes: prompt filling, clicking submit, or active streaming)

    • Once the submission boundary is crossed, the request is considered non-idempotent.
    • Any exception (e.g., page crash, timeout) MUST bypass retry logic entirely and fail-fast immediately to prevent duplicate submissions or inconsistent bridge state.
  7. Understand the WebAI-to-API Endpoint Classification

    master

    WebAI-to-API categorizes its endpoints into several tiers to help you choose the right surface for your integration:

    • Primary APIs: The authoritative surface (OpenAI-compatible) intended for all new integrations. Use /v1/chat/completions.
    • Compatibility APIs: Bridges designed to emulate specific third-party protocols, such as the Google Generative AI bridge at /v1beta/models/{model}.
    • Specialized APIs: Target-specific endpoints like /v1/temporary/chat/completions (Gemini-only temporary endpoint) or /translate (for the 'Translate It!' extension).
    • Legacy APIs: Deprecated endpoints like /gemini and /gemini-chat maintained for backward compatibility. You should migrate to /v1/chat/completions.
    • Utilities: Endpoints like /v1/gems for enumerating Gemini "Gems".
  8. Manage Gemini WebAPI conversation snapshots

    master

    The /ui/conversations page allows for managing locally persisted Gemini WebAPI conversation snapshots.

    Important constraints on conversation actions:

    • Scope: Actions (single delete and bulk delete) apply only to locally persisted Gemini WebAPI snapshots.
    • Exclusions: Playwright and Atlas conversations are not affected by these actions.
    • Bulk Delete Behavior: The bulk delete operation is 'best-effort' and may partially succeed.
  9. Understand the WebAI-to-API Error Classification Model

    master

    The runtime classifies failures into four distinct levels of impact to determine how the system should respond and escalate. Understanding these scopes is critical for implementing providers or debugging runtime behavior:

    1. Recoverable Errors (Transient): Minor instabilities like selector failures or navigation timeouts where the browser is healthy. Protocol: Providers escalate to ProviderSession.ensure_healthy() for authoritative recovery.
    2. Request-Scoped Terminal Errors: Failures that invalidate a specific request but leave the session/tab intact (e.g., QueueOverflowError, lease invalidation). Protocol: The request fails immediately; ManagedPage performs cleanup.
    3. Session-Scoped Failures: Structural failures within a ProviderSession (e.g., keepalive_page loss, context corruption). Protocol: The session is marked degraded, all active leases are invalidated, and the session executes recovery.
    4. Engine-Scoped Fatal Errors: Irreversible loss of the global browser process (e.g., manual window closure, process disconnect). Protocol: The runtime enters an irreversible Terminal Shutdown state; all new requests and recovery attempts fail fast.
  10. Manage Gemini conversation sessions and serialization

    master

    The system uses SessionManager.lock (an internal asyncio.Lock) to serialize all stateful completion and streaming operations for a specific conversation_id.

    Concurrency Constraints:

    • Serialization: Concurrent requests for the same conversation_id are strictly serialized. One request must fully complete (or its stream must close) before the next can acquire the lock.
    • Gemini Safety: This serialization is required because Google's ChatSession maintains mutable internal state (history, sequence markers). Concurrent execution on the same session causes state corruption and protocol failures.
    • Multi-Agent Limitation: The system enforces a 1-to-1 relationship between an active conversation_id and a single logical client. It does not support multiple independent actors interacting with the same thread.
    • Corruption Risk: Attempting to use the same conversation_id across multiple clients will result in interleaved messages, poisoning the conversation context as there is no server-side branching support.
  11. How configuration and authentication persistence works

    master

    WebAI-to-API uses bind mounts to ensure settings and authentication survive container restarts, recreations, or image rebuilds.

    Bind Mounts

    • ./config.conf:/app/config.conf:ro: The config.conf file is mounted read-only. This keeps secrets on your host machine and allows you to update settings without rebuilding the image (requires a container restart).
    • ./runtime:/app/runtime: The runtime/ directory stores persistent state, including authentication (runtime/auth/gemini.json), session persistence, and runtime cache data.

    Refreshing Authentication

    If authentication expires, you must:

    1. Generate a new state on the host: poetry run python verify_login.py.
    2. Restart the container: make stop && make up.

    Note: Updating runtime/auth/gemini.json while the container is running will not update existing browser contexts.

  12. Identify and Handle Poisoned Pages

    master

    A page is considered Poisoned if its integrity is compromised, making future requests unreliable.

    Criteria for Poisoning:

    • page.on("crash") fires.
    • The page closes unexpectedly during an active request.
    • Bridge integrity is lost (e.g., failed to expose binding or callback registry corruption).
    • Stream ordering becomes corrupted (e.g., queue overflow or out-of-order chunks).

    Handling Requirements:

    • Irreversibility: Poisoned state is terminal. A poisoned page/tab can NEVER transition back to a healthy or IDLE state.
    • No Reuse: Poisoned pages must NEVER be returned to the idle pool or reused.
    • Immediate Invalidation: Providers MUST mark the associated PersistentTab as DEAD immediately upon detection.