Skip to content

feat: dynamic model list via browser-captured ListModels RPC #249

Description

@CharoenwitKunna

Problem

The model list is hardcoded in \configs/models.json\ (currently 30 models). When Google adds new models (e.g. \gemini-3.7-flash,
obotics-er-2-preview), users must manually edit this file and restart the server.

Additionally, the \generativelanguage.googleapis.com/v1beta/models\ endpoint returns \403 API_KEY_SERVICE_BLOCKED\ when called from the browser context, making direct model discovery unreliable.

Proposed Solution

Auto-fetch the model list at runtime from the same \ListModels\ RPC endpoint that the AI Studio app calls on page load, via \page.on('response')\ capture in \BrowserManager.

Key changes:

  • \BrowserManager: hook \page.on('response')\ before \page.goto\ to capture the app's own \ListModels\ response + request headers (URL, API key)
  • \BrowserManager.fetchLiveModels(): return captured models (with configurable TTL), falling back to a manual RPC call using the captured URL/headers
  • \BrowserManager._parseListModelsResponse(): parse the [[ [...], ... ]]\ protobuf+JSON array into \models.json-compatible objects
  • \ConfigLoader: add \DYNAMIC_MODELS\ (default \ rue) and \DYNAMIC_MODELS_TTL\ (default \3600000\ ms) env vars
  • \ProxyServerSystem: make \GET /v1/models\ and \GET /v1beta/models\ async, call \ etchLiveModels()\ with static config as fallback
  • \ProxyServerSystem: add \POST /api/models/refresh?persist=true\ endpoint for manual refresh

Benefits

  • No hardcoded domain/key — auto-discovered from the browser's own captured request
  • Works even if Google rotates the \CoJqbf\ backend domain or API key
  • Zero-config — enabled by default, models update automatically on next request after TTL expires
  • Backward compatible — \DYNAMIC_MODELS=false\ reverts to static \configs/models.json\

Testing

With \DYNAMIC_MODELS=true\ and empty \configs/models.json\ ({"models":[]}):

  • Server fetches 36 live models via captured \ListModels\ RPC
  • \GET /v1beta/models\ returns all 36 models
  • Without capture fallback, auto-detects base URL from page config (\CoJqbf) and API key from page scripts

Environment

  • Node.js on Windows
  • Playwright with Camoufox (Firefox)
  • AI Studio Build App with Google account auth

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions