@jacobbd/relay-ai 0.7.6 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -21,13 +21,13 @@
21
21
  |:---:|:---:|:---:|:---:|:---:|
22
22
  | [![Claude Demo](https://img.youtube.com/vi/IvsUPHLhX0o/mqdefault.jpg)](https://youtu.be/IvsUPHLhX0o) | [![Codex Demo](https://img.youtube.com/vi/42oiOB8IAu4/mqdefault.jpg)](https://youtu.be/42oiOB8IAu4) | [![Gemini Demo](https://img.youtube.com/vi/g7JKvqOHJl4/mqdefault.jpg)](https://www.youtube.com/watch?v=g7JKvqOHJl4) | [![UI & Antigravity Demo](https://img.youtube.com/vi/8vXJ0LfpdoY/mqdefault.jpg)](https://www.youtube.com/watch?v=8vXJ0LfpdoY) | [![Server Gateway Demo](https://img.youtube.com/vi/4CEw0MQUE9I/mqdefault.jpg)](https://www.youtube.com/watch?v=4CEw0MQUE9I) |
23
23
 
24
- **relay-ai** is an interactive CLI — and now a **visual launcher** — that connects AI coding tools to any provider and runs local API gateways on your machine. It supports **Claude Code**, **Claude Desktop (Cowork + Code)**, the **OpenAI Codex CLI**, the **ChatGPT desktop app in Codex mode (macOS + Windows)**, **Google Gemini CLI**, and experimental **Antigravity CLI / IDE** support.
24
+ **relay-ai** is an interactive CLI — and now a **visual launcher** — that connects AI coding tools to any provider and runs local API gateways on your machine. It supports **Claude Code**, **Claude Desktop (Cowork + Code)**, the **OpenAI Codex CLI**, the **ChatGPT desktop app in Codex mode (macOS + Windows + Linux)**, **Google Gemini CLI**, and experimental **Antigravity CLI / IDE** support.
25
25
 
26
26
  > **Deploy with Docker / AI assistants:** To run an always-on **Server + Admin UI** from this repo (`docker compose up`), read **[docs/DOCKER.md](docs/DOCKER.md)** first — it includes questions to ask the user and an exact checklist. The container is **not** full desktop Relay AI (no Claude/Codex/Antigravity app launch inside Docker).
27
27
 
28
28
  Pick your backend:
29
29
 
30
- - **Your providers** — configure once with `relay-ai providers` (Groq, Mistral, Nvidia, DeepSeek, custom OpenAI/Anthropic endpoints, and more)
30
+ - **Your providers** — configure once with `relay-ai providers` (ClinePass, Groq, Mistral, Nvidia, DeepSeek, custom OpenAI/Anthropic endpoints, and more)
31
31
  - **OpenCode Zen / Go** — cloud models with your OpenCode API key (optional; add via `relay-ai providers`)
32
32
  - **One-time OpenCode import** — bring existing OpenCode provider settings into the registry (`relay-ai providers import`)
33
33
  - **Google Vertex AI** — Claude on Vertex via `relay-ai server --vertex` and local gcloud credentials (no OpenCode key required)
@@ -42,6 +42,7 @@ Pick your backend:
42
42
  | `relay-ai claude` | Pick a provider → launch Claude Code |
43
43
  | `relay-ai providers` | Add, import, list, remove, and refresh your AI providers |
44
44
  | `relay-ai models` | Manage favorite models for mid-session `/model` switching |
45
+ | `relay-ai subagents` | Manage the separate one-model Codex SubAgent catalog |
45
46
  | `relay-ai server` | Foreground API gateway (registry providers + optional Zen/Go) |
46
47
  | `relay-ai server --vertex` | Foreground Anthropic-compatible gateway to Claude on Vertex AI |
47
48
  | `relay-ai claude-app` | Launch Claude Desktop app with registry providers ([guide](docs/CLAUDE_DESKTOP_SETUP.md)) |
@@ -51,7 +52,7 @@ Pick your backend:
51
52
  | `relay-ai agy` | Launch Antigravity CLI with Relay models ([warning + guide](docs/ANTIGRAVITY.md)) |
52
53
  | `relay-ai antigravity` | Launch Antigravity app with Relay models, macOS ([warning + guide](docs/ANTIGRAVITY.md)) |
53
54
  | `relay-ai antigravity-ide` | Launch Antigravity IDE with Relay models, macOS ([warning + guide](docs/ANTIGRAVITY.md)) |
54
- | `relay-ai providers auth <id>` | Authenticate an OAuth provider (GitHub Copilot, xAI, OpenAI) |
55
+ | `relay-ai providers auth <id>` | Authenticate an OAuth provider (GitHub Copilot, xAI, OpenAI, ClinePass) |
55
56
  | `relay-ai --ai` | Full agent reference for scripts and alef-agent ([guide](docs/AI-AGENTS.md)) |
56
57
  | `@jacobbd/relay-ai/core` | Embed Relay AI in a Node app in-process — no CLI/UI/server ([guide](docs/CORE.md)) |
57
58
 
@@ -61,11 +62,12 @@ Pick your backend:
61
62
  - **Docker Server + Admin UI:** `docker compose up` (see **[docs/DOCKER.md](docs/DOCKER.md)**) runs an always-on admin UI + gateway for LAN/home-lab use — providers, favorites, and Start Server without a desktop keychain. Host CLI still launches Claude / Codex / Antigravity.
62
63
  - **Server tab in the UI:** Run the same API gateway as `relay-ai server` — favorites-only or specific providers, discovery id masking for Claude Desktop / Cowork, local or network listen mode — from a browser form instead of a terminal wizard. Shows live URLs, the API key, and the full model catalog once started, with a one-click Stop.
63
64
  - **Native provider registry:** `relay-ai providers` stores config in `~/.relay-ai/providers.json` and secrets in the OS keychain — no OpenCode binary required at launch. See **[docs/PROVIDERS.md](docs/PROVIDERS.md)** for a full list of providers and known issues.
64
- - **Provider templates:** Add Groq, Mistral, Together, OpenRouter, and 15+ SDK-backed providers, plus custom OpenAI/Anthropic-compatible endpoints
65
+ - **Provider templates:** Add ClinePass, Groq, Mistral, Together, OpenRouter, and 15+ SDK-backed providers, plus custom OpenAI/Anthropic-compatible endpoints
65
66
  - **OpenCode import:** One-time migration from OpenCode (`providers import`); validates API keys and skips placeholders like `anything`
66
67
  - **OpenCode Zen / Go:** Optional cloud backends when you have an OpenCode API key
67
68
  - **SDK adapter proxy:** Non-Anthropic providers route through the Vercel AI SDK (same packages OpenCode uses), so Claude Code still speaks Anthropic format. Labeled `(via proxy)` in the picker
68
69
  - **Favorite models:** Save up to 20 and switch mid-session with Claude Code's `/model` command
70
+ - **Codex SubAgent:** Build a separate, initially empty one-model catalog for Codex delegation; it never imports or synchronizes with General Favorites
69
71
  - **Smart model pickers:** Recent models per provider, search for large lists (>25), paginated browse (15 per page)
70
72
  - **Refresh model lists:** `relay-ai providers refresh-models` updates cached catalogs per provider
71
73
  - **API server:** Run a local gateway on port **17645** for Claude Code, Claude Desktop, or any Anthropic-compatible client
@@ -90,9 +92,9 @@ Pick your backend:
90
92
  | Favorite models | `relay-ai models` | ✅ Supported |
91
93
  | OpenCode API server | `relay-ai server` | ✅ Supported |
92
94
  | Vertex API gateway | `relay-ai server --vertex` | ✅ Supported |
93
- | Claude Desktop (Cowork + Code) | `relay-ai claude-app` | ✅ Supported macOS + Windows ([guide](docs/CLAUDE_DESKTOP_SETUP.md)) |
95
+ | Claude Desktop (Cowork + Code) | `relay-ai claude-app` | ✅ Supported macOS + Windows + Linux ([guide](docs/CLAUDE_DESKTOP_SETUP.md)) |
94
96
  | Codex CLI | `relay-ai codex` | ✅ Supported ([guide](docs/CODEX.md)) |
95
- | ChatGPT desktop app (Codex mode) | `relay-ai codex-app` (alias `chatgpt`) | ✅ Supported macOS + Windows ([guide](docs/CODEX.md)) |
97
+ | ChatGPT desktop app (Codex mode) | `relay-ai codex-app` (alias `chatgpt`) | ✅ Supported macOS + Windows + Linux ([guide](docs/CODEX.md)) |
96
98
  | Google Gemini CLI | `relay-ai gemini` | ⚠️ Experimental, model switching is done via .model prompt |
97
99
  | Antigravity CLI | `relay-ai agy` | ⚠️ Experimental, use a throwaway Google account ([guide](docs/ANTIGRAVITY.md)) |
98
100
  | Antigravity app | `relay-ai antigravity` | ⚠️ Experimental macOS + Windows support, use a throwaway Google account ([guide](docs/ANTIGRAVITY.md)) |
@@ -100,6 +102,7 @@ Pick your backend:
100
102
  | GitHub Copilot OAuth | `relay-ai providers auth github-copilot` | ✅ Device code flow ([guide](docs/SUBSCRIPTION-OAUTH.md)) |
101
103
  | xAI SuperGrok OAuth | `relay-ai providers auth xai-oauth` | ✅ Device code flow ([guide](docs/SUBSCRIPTION-OAUTH.md)) |
102
104
  | OpenAI ChatGPT OAuth | `relay-ai providers auth openai-oauth` | ✅ Device code flow ([guide](docs/SUBSCRIPTION-OAUTH.md)) |
105
+ | ClinePass OAuth | `relay-ai providers auth cline-pass` | ✅ Device code flow ([guide](docs/SUBSCRIPTION-OAUTH.md)) |
103
106
 
104
107
  ## Prerequisites
105
108
 
@@ -112,6 +115,8 @@ Pick your backend:
112
115
 
113
116
  **A note on providers:** relay-ai keeps your provider list in `~/.relay-ai/providers.json`. Add providers with API keys or device-code OAuth (`relay-ai providers add` / the UI). OpenCode Zen / Go are normal cloud providers (API key from [opencode.ai/auth](https://opencode.ai/auth)). Optional: `relay-ai providers import` once if you already use the OpenCode CLI — OpenCode is never required to run Relay.
114
117
 
118
+ **ClinePass:** The CLI and UI expose API-key and Cline account OAuth as two authentication choices for one `ClinePass` provider entry. Both use the ClinePass account's subscription limits.
119
+
115
120
  ## Installation
116
121
 
117
122
  To install the CLI globally:
@@ -195,7 +200,7 @@ Opens a browser-based dashboard on a random local port. From the UI you can:
195
200
  - **Keep Claude Code's Anthropic login** — on the Claude Code CLI card, check **Keep my Anthropic login and add Relay models** to keep your normal Claude models while adding the selected Relay model and compatible favorites. This option is not shown for Claude Desktop.
196
201
  - **Manage General Favorites** — the sidebar shows your saved favorite models with a slot indicator (Slots used X/20). Favorites launch through all supported agents.
197
202
  - **Manage Antigravity Favorites** — separate favorites panel for Antigravity sessions.
198
- - **Manage providers** — add providers from templates, delete providers, and refresh model lists inline, all without leaving the browser. For GitHub Copilot, ChatGPT, and xAI OAuth, the UI displays a one-time device code with **Copy code** and **Open sign-in page** buttons so you can complete sign-in without using the terminal. Connected Copilot cards also identify the account as Free, Paid, or Plan unverified so the visible model catalog is easier to understand.
203
+ - **Manage providers** — add providers from templates, delete providers, and refresh model lists inline, all without leaving the browser. For GitHub Copilot, ChatGPT, xAI, and ClinePass OAuth, the UI displays a one-time device code with **Copy code** and **Open sign-in page** buttons so you can complete sign-in without using the terminal. ClinePass can also be configured with an API key from the same provider card.
199
204
  - **Run the Server tab** — configure and start the same gateway as `relay-ai server` (favorites-only or specific providers, discovery id masking, local/network listen mode) and see the resulting URLs, API key, and model catalog right in the browser. Runs in the same process as the UI, so it stops when you close the dashboard. See [Registry gateway (`relay-ai server`)](#registry-gateway-relay-ai-server) below for what each option does.
200
205
 
201
206
  Press `Ctrl+C` in the terminal where `relay-ai ui` is running to shut down the dashboard server (this also stops the gateway if you started it from the Server tab).
@@ -292,7 +297,7 @@ Run relay-ai as a foreground API gateway on port **17645**:
292
297
  | **Vertex gateway** | `relay-ai server --vertex` | gcloud Application Default Credentials | Claude on Vertex AI |
293
298
  | **Docker Server + Admin UI** | `docker compose up --build` | `RELAY_AI_SERVER_PASSWORD` + UI / env keys | Same registry gateway, managed in the browser |
294
299
 
295
- > **Claude Desktop (Cowork + Code):** For the automated macOS/Windows setup, use `relay-ai claude-app`. For manual or network setups, see [docs/CLAUDE_DESKTOP_SETUP.md](docs/CLAUDE_DESKTOP_SETUP.md).
300
+ > **Claude Desktop (Cowork + Code):** For the automated macOS/Windows/Linux setup, use `relay-ai claude-app`. For manual or network setups, see [docs/CLAUDE_DESKTOP_SETUP.md](docs/CLAUDE_DESKTOP_SETUP.md).
296
301
  >
297
302
  > **Docker (recommended for always-on home lab / NAS):** clone this repo → `cp .env.docker.example .env` → set `RELAY_AI_SERVER_PASSWORD` → `docker compose up --build` → open **http://127.0.0.1:8787**. Full playbook for humans and AI assistants: **[docs/DOCKER.md](docs/DOCKER.md)**.
298
303
 
@@ -462,6 +467,7 @@ Device code flows for existing subscriptions:
462
467
  relay-ai providers auth github-copilot # GitHub Copilot
463
468
  relay-ai providers auth openai-oauth # ChatGPT Plus / Pro
464
469
  relay-ai providers auth xai-oauth # xAI SuperGrok
470
+ relay-ai providers auth cline-pass # ClinePass account
465
471
  ```
466
472
 
467
473
  ### Codex CLI (`relay-ai codex`)
@@ -475,7 +481,7 @@ relay-ai codex # pick provider + model → Codex TUI
475
481
 
476
482
  ### Claude Desktop app (`relay-ai claude-app`)
477
483
 
478
- Launch **Claude Desktop** (macOS or Windows) with registry providers:
484
+ Launch **Claude Desktop** (macOS, Windows, or Linux) with registry providers:
479
485
 
480
486
  ```bash
481
487
  relay-ai claude-app
@@ -508,7 +514,7 @@ For agent / alef-agent integration (boot flags, NDJSON, JSONL): **[docs/AI-AGENT
508
514
 
509
515
  > OpenAI merged the standalone Codex app into the ChatGPT desktop app on 2026-07-09 — it's now named "ChatGPT" on disk (bundle id and config format unchanged) and opens in Codex mode for existing Codex users. `relay-ai codex-app` and `relay-ai chatgpt` are the same command.
510
516
 
511
- Launch the **ChatGPT app in Codex mode** (macOS or Windows) with registry providers:
517
+ Launch the **ChatGPT app in Codex mode** (macOS, Windows, or Linux) with registry providers:
512
518
 
513
519
  ```bash
514
520
  relay-ai codex-app
@@ -516,6 +522,16 @@ relay-ai codex-app
516
522
 
517
523
  Patches `~/.codex/config.toml` with backup; **Ctrl+C** in the relay-ai terminal asks whether to close ChatGPT Desktop and restore your config (choose "No, keep session running" to decline and keep going). The app keeps Codex's built-in `openai` provider active so existing conversation history remains visible, and routes the selected model through a foreground local proxy. Preview config without writing: `relay-ai codex-app --config`. Recovery: `relay-ai codex-app --restore`.
518
524
 
525
+ On Linux, Relay supports the packaged ChatGPT desktop app at `/usr/bin/chatgpt` or `/usr/lib/chatgpt/ChatGPT`. When launched from an X11/RDP terminal, Relay uses that terminal's window identity to resolve the active display, so the app opens in the current graphical session even when the inherited `DISPLAY` value is stale. Keep the Relay terminal open while using the app; it owns the local proxy.
526
+
527
+ To configure the model Codex uses when it launches a sub-agent, build the independent catalog before starting Codex:
528
+
529
+ ```bash
530
+ relay-ai subagents
531
+ ```
532
+
533
+ The catalog starts empty and has one slot. In mixed native/Relay mode, Codex decides when to launch a sub-agent and Relay routes that child to the configured Codex SubAgent model. Enable **Load native Codex models alongside Relay models** in the UI, or pass `--with-native` from the CLI. General Favorites and Codex SubAgent are separate lists.
534
+
519
535
  See **[docs/CODEX.md](docs/CODEX.md)** for CLI vs app differences, file ownership, and troubleshooting.
520
536
 
521
537
  > **MCP tools (Context7, chrome-devtools, the built-in browser, etc.) now work with non-native models.** Codex wraps local `[mcp_servers.*]` tools — and the built-in browser, which is itself exposed as an MCP tool — in a proprietary, undocumented format that only Codex's own ChatGPT backend used to be able to dispatch. relay-ai now translates this format on both the request and response side (splitting the model's flattened tool-call name back into Codex's expected `{namespace, name}` shape), so MCP tools and the browser work through any provider relay-ai routes to, not just Codex's native OpenAI/ChatGPT models.
@@ -31,7 +31,7 @@ __export(provider_templates_exports, {
31
31
  listVisibleOAuthTemplates: () => listVisibleOAuthTemplates
32
32
  });
33
33
  function listSupportedTemplates() {
34
- return PROVIDER_TEMPLATES.filter((t) => t.supported && t.authType === "api" && t.addable !== false && !t.hidden).sort((a, b) => a.name.localeCompare(b.name));
34
+ return PROVIDER_TEMPLATES.filter((t) => t.supported && (t.authMethods ?? [t.authType]).includes("api") && t.addable !== false && !t.hidden).sort((a, b) => a.name.localeCompare(b.name));
35
35
  }
36
36
  function listAddableTemplates(configuredIds = []) {
37
37
  const configured = new Set(configuredIds);
@@ -44,7 +44,10 @@ function listAddableTemplates(configuredIds = []) {
44
44
  }
45
45
  function listVisibleOAuthTemplates(configuredIds = []) {
46
46
  const configured = new Set(configuredIds);
47
- return PROVIDER_TEMPLATES.filter((t) => t.authType === "oauth" && t.supported && t.addable !== false && !t.hidden && !configured.has(t.id)).sort((a, b) => a.name.localeCompare(b.name));
47
+ return PROVIDER_TEMPLATES.filter((t) => {
48
+ const methods = t.authMethods ?? [t.authType];
49
+ return methods.includes("oauth") && !methods.includes("api") && t.supported && t.addable !== false && !t.hidden && !configured.has(t.id);
50
+ }).sort((a, b) => a.name.localeCompare(b.name));
48
51
  }
49
52
  function getTemplateById(id) {
50
53
  return PROVIDER_TEMPLATES.find((t) => t.id === id);
@@ -60,6 +63,19 @@ var PROVIDER_TEMPLATES;
60
63
  var init_provider_templates = __esm({
61
64
  "src/provider-templates.ts"() {
62
65
  PROVIDER_TEMPLATES = [
66
+ {
67
+ id: "cline-pass",
68
+ name: "ClinePass",
69
+ authType: "api",
70
+ authMethods: ["api", "oauth"],
71
+ npm: "@ai-sdk/openai-compatible",
72
+ defaultBaseUrl: "https://api.cline.bot/api/v1",
73
+ signupUrl: "https://app.cline.bot",
74
+ modelSource: "cline-recommended",
75
+ headers: { "HTTP-Referer": "https://cline.bot", "X-Title": "Cline" },
76
+ supported: true,
77
+ subscriptionRisk: true
78
+ },
63
79
  {
64
80
  id: "groq",
65
81
  name: "Groq",
@@ -456,4 +472,4 @@ export {
456
472
  provider_templates_exports,
457
473
  init_provider_templates
458
474
  };
459
- //# sourceMappingURL=chunk-HXGZ4CTV.js.map
475
+ //# sourceMappingURL=chunk-Q2FTCICO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/provider-templates.ts"],"sourcesContent":["// src/provider-templates.ts — builtin provider templates for relay-ai providers add\n\nexport type ProviderAuthType = 'api' | 'oauth' | 'none';\nexport type ProviderModelSource = 'api-list' | 'static-seed' | 'manual-only' | 'zen-go-api' | 'cline-recommended';\n\nexport interface ProviderTemplate {\n id: string;\n name: string;\n authType: ProviderAuthType;\n /** Supported setup methods; defaults to the template's authType. */\n authMethods?: ProviderAuthType[];\n npm: string;\n defaultBaseUrl?: string;\n modelsPath?: string;\n signupUrl?: string;\n urlPlaceholder?: string;\n urlPrompt?: string;\n accountIdPrompt?: string;\n apiKeyOptional?: boolean;\n anonymousFreeModels?: boolean;\n /** Static headers this provider requires on every request (model listing and runtime). */\n headers?: Record<string, string>;\n modelSource: ProviderModelSource;\n staticModels?: Array<{ id: string; name: string }>;\n supported: boolean;\n addable?: boolean;\n hidden?: boolean;\n unsupportedReason?: string;\n /** True for providers that extract subscription tokens — carries account risk. */\n subscriptionRisk?: boolean;\n}\n\n/** Templates aligned with SDK packages shipped in package.json (API-key providers first). */\nexport const PROVIDER_TEMPLATES: ProviderTemplate[] = [\n {\n id: 'cline-pass',\n name: 'ClinePass',\n authType: 'api',\n authMethods: ['api', 'oauth'],\n npm: '@ai-sdk/openai-compatible',\n defaultBaseUrl: 'https://api.cline.bot/api/v1',\n signupUrl: 'https://app.cline.bot',\n modelSource: 'cline-recommended',\n headers: { 'HTTP-Referer': 'https://cline.bot', 'X-Title': 'Cline' },\n supported: true,\n subscriptionRisk: true,\n },\n {\n id: 'groq',\n name: 'Groq',\n authType: 'api',\n npm: '@ai-sdk/groq',\n defaultBaseUrl: 'https://api.groq.com/openai/v1',\n signupUrl: 'https://console.groq.com/keys',\n modelSource: 'api-list',\n supported: true,\n },\n {\n id: 'nvidia',\n name: 'Nvidia',\n authType: 'api',\n npm: '@ai-sdk/openai-compatible',\n defaultBaseUrl: 'https://integrate.api.nvidia.com/v1',\n signupUrl: 'https://build.nvidia.com',\n modelSource: 'api-list',\n supported: true,\n },\n {\n id: 'mistral',\n name: 'Mistral',\n authType: 'api',\n npm: '@ai-sdk/mistral',\n defaultBaseUrl: 'https://api.mistral.ai/v1',\n signupUrl: 'https://console.mistral.ai/api-keys',\n modelSource: 'api-list',\n supported: true,\n },\n {\n id: 'togetherai',\n name: 'Together AI',\n authType: 'api',\n npm: '@ai-sdk/togetherai',\n defaultBaseUrl: 'https://api.together.xyz/v1',\n signupUrl: 'https://api.together.xyz/settings/api-keys',\n modelSource: 'api-list',\n supported: true,\n },\n {\n id: 'cerebras',\n name: 'Cerebras',\n authType: 'api',\n npm: '@ai-sdk/cerebras',\n defaultBaseUrl: 'https://api.cerebras.ai/v1',\n signupUrl: 'https://cloud.cerebras.ai',\n modelSource: 'api-list',\n supported: true,\n },\n {\n id: 'deepinfra',\n name: 'DeepInfra',\n authType: 'api',\n npm: '@ai-sdk/deepinfra',\n defaultBaseUrl: 'https://api.deepinfra.com/v1/openai',\n signupUrl: 'https://deepinfra.com/dash/api_keys',\n modelSource: 'api-list',\n supported: true,\n },\n {\n id: 'deepseek',\n name: 'DeepSeek',\n authType: 'api',\n npm: '@ai-sdk/openai-compatible',\n defaultBaseUrl: 'https://api.deepseek.com/v1',\n signupUrl: 'https://platform.deepseek.com',\n modelSource: 'api-list',\n supported: true,\n },\n {\n id: 'zhipu',\n name: 'Zhipu AI (GLM)',\n authType: 'api',\n npm: '@ai-sdk/openai-compatible',\n defaultBaseUrl: 'https://open.bigmodel.cn/api/paas/v4',\n signupUrl: 'https://open.bigmodel.cn',\n modelSource: 'api-list',\n supported: true,\n },\n {\n id: 'moonshot',\n name: 'Moonshot (Kimi)',\n authType: 'api',\n npm: '@ai-sdk/openai-compatible',\n defaultBaseUrl: 'https://api.moonshot.cn/v1',\n signupUrl: 'https://platform.moonshot.cn',\n modelSource: 'api-list',\n supported: true,\n },\n {\n id: 'moonshot-global',\n name: 'Moonshot Global (kimi.ai)',\n authType: 'api',\n npm: '@ai-sdk/openai-compatible',\n defaultBaseUrl: 'https://api.moonshot.ai/v1',\n signupUrl: 'https://platform.kimi.ai',\n modelSource: 'api-list',\n supported: true,\n },\n {\n id: 'kimi-code',\n name: 'Kimi Code (Subscription Required)',\n authType: 'api',\n npm: '@ai-sdk/openai-compatible',\n defaultBaseUrl: 'https://api.kimi.com/coding/v1',\n modelSource: 'static-seed',\n staticModels: [\n { id: 'kimi-for-coding', name: 'Kimi Code K2.7 (Unified)' }\n ],\n supported: true,\n },\n {\n id: 'xai',\n name: 'xAI',\n authType: 'api',\n npm: '@ai-sdk/xai',\n defaultBaseUrl: 'https://api.x.ai/v1',\n signupUrl: 'https://console.x.ai',\n modelSource: 'api-list',\n supported: true,\n },\n {\n id: 'perplexity',\n name: 'Perplexity',\n authType: 'api',\n npm: '@ai-sdk/perplexity',\n defaultBaseUrl: 'https://api.perplexity.ai',\n signupUrl: 'https://www.perplexity.ai/settings/api',\n modelSource: 'api-list',\n supported: true,\n },\n {\n id: 'cohere',\n name: 'Cohere',\n authType: 'api',\n npm: '@ai-sdk/cohere',\n defaultBaseUrl: 'https://api.cohere.com/compatibility/v1',\n signupUrl: 'https://dashboard.cohere.com/api-keys',\n modelSource: 'api-list',\n supported: true,\n },\n {\n id: 'openai',\n name: 'OpenAI',\n authType: 'api',\n npm: '@ai-sdk/openai',\n defaultBaseUrl: 'https://api.openai.com/v1',\n signupUrl: 'https://platform.openai.com/api-keys',\n modelSource: 'api-list',\n supported: true,\n },\n {\n id: 'google',\n name: 'Google Gemini',\n authType: 'api',\n npm: '@ai-sdk/google',\n defaultBaseUrl: 'https://generativelanguage.googleapis.com/v1beta/openai',\n signupUrl: 'https://aistudio.google.com/apikey',\n modelSource: 'api-list',\n supported: true,\n },\n {\n id: 'alibaba',\n name: 'Alibaba DashScope (China)',\n authType: 'api',\n npm: '@ai-sdk/alibaba',\n defaultBaseUrl: 'https://dashscope.aliyuncs.com/compatible-mode/v1',\n signupUrl: 'https://dashscope.console.aliyun.com/apiKey',\n modelSource: 'api-list',\n supported: true,\n },\n {\n id: 'qwen-cloud-token-plan',\n name: 'Qwen Cloud (Token Plan)',\n authType: 'api',\n npm: '@ai-sdk/alibaba',\n defaultBaseUrl: 'https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1',\n signupUrl: 'https://home.qwencloud.com/api-keys',\n modelSource: 'api-list',\n supported: true,\n },\n {\n id: 'qwen-cloud-payg',\n name: 'Qwen Cloud (Pay-As-You-Go)',\n authType: 'api',\n npm: '@ai-sdk/alibaba',\n defaultBaseUrl: 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1',\n signupUrl: 'https://home.qwencloud.com/api-keys',\n modelSource: 'api-list',\n supported: true,\n },\n {\n id: 'openrouter',\n name: 'OpenRouter',\n authType: 'api',\n npm: '@openrouter/ai-sdk-provider',\n defaultBaseUrl: 'https://openrouter.ai/api/v1',\n signupUrl: 'https://openrouter.ai/keys',\n modelSource: 'api-list',\n supported: true,\n },\n {\n id: 'kilo',\n name: 'Kilo Code',\n authType: 'api',\n npm: '@ai-sdk/openai-compatible',\n defaultBaseUrl: 'https://api.kilo.ai/api/gateway',\n modelsPath: '/models',\n signupUrl: 'https://app.kilo.ai',\n apiKeyOptional: true,\n anonymousFreeModels: true,\n modelSource: 'api-list',\n supported: true,\n },\n {\n id: 'ollama',\n name: 'Ollama',\n authType: 'api',\n npm: '@ai-sdk/openai-compatible',\n defaultBaseUrl: 'http://127.0.0.1:11434/v1',\n urlPrompt: 'Ollama API Base URL:',\n apiKeyOptional: true,\n modelSource: 'api-list',\n supported: true,\n },\n {\n id: 'lmstudio',\n name: 'LM Studio',\n authType: 'api',\n npm: '@ai-sdk/openai-compatible',\n defaultBaseUrl: 'http://127.0.0.1:1234/v1',\n urlPrompt: 'LM Studio API Base URL:',\n apiKeyOptional: true,\n modelSource: 'api-list',\n supported: true,\n },\n {\n id: 'venice',\n name: 'Venice AI',\n authType: 'api',\n npm: 'venice-ai-sdk-provider',\n defaultBaseUrl: 'https://api.venice.ai/api/v1',\n signupUrl: 'https://venice.ai/settings/api',\n modelSource: 'api-list',\n supported: true,\n },\n {\n id: 'cloudflare',\n name: 'Cloudflare Workers AI',\n authType: 'api',\n npm: '@ai-sdk/openai-compatible',\n defaultBaseUrl: 'https://api.cloudflare.com/client/v4/accounts/{ACCOUNT_ID}/ai/v1',\n modelsPath: '/models/search?task=Text%20Generation',\n signupUrl: 'https://dash.cloudflare.com',\n accountIdPrompt: 'Cloudflare Account ID:',\n modelSource: 'api-list',\n supported: true,\n },\n {\n id: 'anthropic',\n name: 'Anthropic',\n authType: 'api',\n npm: '@ai-sdk/anthropic',\n defaultBaseUrl: 'https://api.anthropic.com',\n signupUrl: 'https://console.anthropic.com/settings/keys',\n modelSource: 'api-list',\n supported: true,\n },\n {\n id: 'bedrock',\n name: 'Amazon Bedrock',\n authType: 'api',\n npm: '@ai-sdk/amazon-bedrock',\n modelSource: 'manual-only',\n supported: false,\n unsupportedReason: 'Not supported yet (requires AWS credentials). Optional: relay-ai providers import if already set up in OpenCode CLI.',\n },\n {\n id: 'azure',\n name: 'Azure OpenAI',\n authType: 'api',\n npm: '@ai-sdk/azure',\n modelSource: 'manual-only',\n supported: false,\n unsupportedReason: 'Not supported yet (requires Azure deployment URLs). Optional: relay-ai providers import if already set up in OpenCode CLI.',\n },\n {\n id: 'vertex',\n name: 'Google Vertex AI',\n authType: 'none',\n npm: '@ai-sdk/google-vertex',\n modelSource: 'manual-only',\n supported: false,\n unsupportedReason: 'Uses gcloud Application Default Credentials — use relay-ai server --vertex, not an API key.',\n },\n {\n id: 'opencode-cloud',\n name: 'OpenCode Zen / Go',\n authType: 'api',\n npm: '@ai-sdk/openai-compatible',\n signupUrl: 'https://opencode.ai/auth',\n modelSource: 'zen-go-api',\n supported: true,\n },\n {\n id: 'zen',\n name: 'OpenCode Zen',\n authType: 'api',\n npm: '@ai-sdk/openai-compatible',\n signupUrl: 'https://opencode.ai/auth',\n modelSource: 'zen-go-api',\n supported: true,\n addable: false,\n },\n {\n id: 'go',\n name: 'OpenCode Go',\n authType: 'api',\n npm: '@ai-sdk/openai-compatible',\n signupUrl: 'https://opencode.ai/auth',\n modelSource: 'zen-go-api',\n supported: true,\n addable: false,\n },\n // Subscription OAuth providers — Authorization Code + PKCE (browser redirect)\n // ⚠️ These extract tokens from paid subscriptions. Account risk — see plan docs.\n {\n id: 'claude-code',\n name: 'Claude Code (Anthropic subscription)',\n authType: 'oauth',\n npm: '@ai-sdk/anthropic',\n defaultBaseUrl: 'https://api.anthropic.com',\n signupUrl: 'https://claude.ai',\n modelSource: 'api-list',\n supported: true,\n hidden: true,\n subscriptionRisk: true,\n },\n {\n id: 'antigravity',\n name: 'Antigravity (Google Cloud Code Assist)',\n authType: 'oauth',\n npm: '@ai-sdk/openai-compatible',\n signupUrl: 'https://antigravity.google',\n modelSource: 'api-list',\n supported: true,\n hidden: true,\n subscriptionRisk: true,\n },\n // OAuth-gated subscription providers — device code or broker sign-in\n {\n id: 'xai-oauth',\n name: 'xAI Grok (SuperGrok)',\n authType: 'oauth',\n npm: '@ai-sdk/xai',\n signupUrl: 'https://x.ai',\n modelSource: 'api-list',\n supported: true,\n },\n {\n id: 'openai-oauth',\n name: 'OpenAI (ChatGPT)',\n authType: 'oauth',\n npm: '@ai-sdk/openai',\n signupUrl: 'https://chatgpt.com',\n modelSource: 'api-list',\n supported: true,\n },\n {\n id: 'github-copilot',\n name: 'GitHub Copilot',\n authType: 'oauth',\n npm: '@ai-sdk/openai-compatible',\n defaultBaseUrl: 'https://api.githubcopilot.com',\n modelsPath: '/models',\n signupUrl: 'https://github.com/features/copilot',\n modelSource: 'api-list',\n headers: { 'Editor-Version': 'vscode/1.85.1' },\n supported: true,\n },\n];\n\nexport function listSupportedTemplates(): ProviderTemplate[] {\n return PROVIDER_TEMPLATES\n .filter(t => t.supported && (t.authMethods ?? [t.authType]).includes('api') && t.addable !== false && !t.hidden)\n .sort((a, b) => a.name.localeCompare(b.name));\n}\n\n/** Supported templates not yet present in the user's registry. */\nexport function listAddableTemplates(configuredIds: Iterable<string> = []): ProviderTemplate[] {\n const configured = new Set(configuredIds);\n return listSupportedTemplates().filter(t => {\n if (t.id === 'opencode-cloud') {\n return !configured.has('zen') && !configured.has('go');\n }\n return !configured.has(t.id);\n });\n}\n\nexport function listVisibleOAuthTemplates(configuredIds: Iterable<string> = []): ProviderTemplate[] {\n const configured = new Set(configuredIds);\n return PROVIDER_TEMPLATES\n .filter(t => {\n const methods = t.authMethods ?? [t.authType];\n return methods.includes('oauth')\n && !methods.includes('api')\n && t.supported\n && t.addable !== false\n && !t.hidden\n && !configured.has(t.id);\n })\n .sort((a, b) => a.name.localeCompare(b.name));\n}\n\nexport function getTemplateById(id: string): ProviderTemplate | undefined {\n return PROVIDER_TEMPLATES.find(t => t.id === id);\n}\n\nexport function filterTemplates(templates: ProviderTemplate[], query: string): ProviderTemplate[] {\n const q = query.trim().toLowerCase();\n if (!q) return templates;\n return templates.filter(\n t =>\n t.id.toLowerCase().includes(q) ||\n t.name.toLowerCase().includes(q) ||\n t.npm.toLowerCase().includes(q),\n );\n}\n"],"mappings":"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","names":[]}