Providers and Channels
A provider is one named upstream endpoint. It binds a stable name to a channel adapter, provider settings, credential pool, model catalogue, routing rules, and optional process rule sets.
Provider|-- channel openai, claudeapi, aistudio, codex, ...|-- settings_json base_url and channel-specific knobs|-- credentials sealed API keys, OAuth tokens, service accounts|-- provider_models local model catalogue and pricing|-- routing_rules Operation + OperationKind dispatch table`-- provider_rule_sets attached request mutation rule setsThe hot path reads providers from ControlPlaneSnapshot. Admin changes are
written to persistence, then the snapshot is rebuilt and invalidated so the next
request sees the new control plane without restarting the process.
Built-in Channels
Section titled “Built-in Channels”The native and edge runtimes build the same channel registry. Current built-in channel ids are:
| Channel id | Typical use |
|---|---|
openai, custom | OpenAI API or OpenAI-compatible gateways. |
openrouter, deepseek, groq, nvidia, vercel | API-key providers with OpenAI-like surfaces. |
claudeapi | Anthropic Claude Messages API. |
aistudio, vertex, vertexexpress | Gemini / Vertex upstreams. |
codex, claudecode, geminicli, antigravity, kiro, copilotcli | OAuth, device-code, cookie, or envelope-style agent channels. |
chatgpt | ChatGPT consumer web backend via a chatgpt.com session cookie. |
Every channel declares a routing surface as (Operation, OperationKind) -> RoutingDecision. That is the source for the provider’s default
routing_rules rows. Request behavior is therefore described by operation
capability, not by provider-family buckets.
ChatGPT channel (cookie session)
Section titled “ChatGPT channel (cookie session)”The chatgpt channel proxies the chatgpt.com consumer web backend using a
browser session cookie — no API key or OAuth. It supports normal chat,
thinking / pro / deep-research (streamed chain-of-thought + report), web search,
and image generation/edit.
Getting the credential. Sign in to https://chatgpt.com in a browser, open
DevTools → Network, click any chatgpt.com request, and copy its full Cookie
request header. In the console, add a chatgpt provider with Cookie login and
paste that cookie string. gproxy exchanges it at /api/auth/session to mint the
access token and warms the Cloudflare / sentinel anti-bot state into the sealed
secret. gproxy then auto-refreshes the access token from the stored cookie as it
nears expiry (the JWT lasts ~10 days; the session cookie far longer), so the
credential lives as long as the browser session — re-paste only when the session
cookie itself lapses.
Session mode. A per-provider setting (provider_settings.mode), surfaced in
the provider form as a three-way selector, controls where conversations land:
| Mode | Behavior |
|---|---|
| Normal | Persistent conversations in your normal chat history. |
| Temporary (default) | Temporary chat — excluded from history and model training. |
| Project | Conversations open inside a ChatGPT project, auto-created/found by name (default gproxy), so they stay grouped for easy review. Set the project name in the form. |
Project and Temporary are mutually exclusive (a project conversation is always
persistent). The legacy temporary_chat: true\|false boolean is still honored
when mode is absent.
Provider Fields
Section titled “Provider Fields”The provider record carries:
| Field | Meaning |
|---|---|
name | Unique provider name. Scoped routes use this in the URL. |
channel | Channel registry id, such as openai or claudeapi. |
settings_json | Free-form channel settings. Common keys include base_url and channel toggles. |
credential_strategy | Credential-pool strategy, currently round_robin or sticky. |
proxy_url | Native outbound proxy fallback for the provider. Edge ignores native proxy settings. |
tls_fingerprint | Optional provider-level TLS/HTTP2 emulation profile. Credential settings can override it. |
enabled | Disabled providers disappear from routing. |
Credential rows belong to a provider. They carry kind, sealed secret_json,
weight, optional rpm_limit / tpm_limit, optional proxy and TLS overrides,
and an enabled flag. Secrets are redacted in debug output and sealed when a
master key is configured.
Aggregated and Scoped Access
Section titled “Aggregated and Scoped Access”GPROXY v2 supports two ways to reach an upstream:
| Mode | URL shape | Resolution |
|---|---|---|
| Aggregated | /v1/*, /v1beta/* | The request model resolves through alias / route tables, then to a route member and credential. |
| Scoped | /{provider}/v1/*, /{provider}/v1beta/* | The provider name comes from the path; the model goes directly to that provider. |
Both modes use the same classifier, auth, transform, process, channel, and settle layers after resolution. Aggregated mode is the normal multi-provider gateway path. Scoped mode is useful for debugging or exposing one provider without creating a route.
Routing Rules
Section titled “Routing Rules”Routing rules are provider-local. Each row names:
operation: for examplegenerate_content,stream_generate_content,count_tokens, orcreate_embedding.kind: one of the content-generation wire kindsopen_ai_responses,open_ai_chat_completions,claude_messages,gemini_generate_content, or provider kindsopen_ai,claude,gemini.implementation:passthrough,transform_to,local, orunsupported.- optional
dest_operationanddest_kindfortransform_to.
No matching routing rule means unsupported. Defaults are materialized into
stored rows when a provider is created, and the console can reset them from the
channel defaults.
Provider Rule Sets
Section titled “Provider Rule Sets”Reusable rule sets attach to providers through provider_rule_sets. Attached
sets are flattened in attachment order, compiled once during snapshot rebuild,
then applied after protocol transform and before channel preparation. This is
where system-text injection, cache breakpoints, field rewrites, sanitization,
and header rules currently run.
The current backend is intentionally permissive: invalid rules warn and skip, and provider-specific policy should live in console/config presets unless the runtime needs a genuinely new primitive.