@jacobbd/relay-ai 0.7.6 → 0.8.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.
@@ -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":[]}
package/dist/cli.js CHANGED
@@ -116,6 +116,7 @@ import {
116
116
  parseDsmlToolCalls,
117
117
  parseToolArguments,
118
118
  prepareClaudeTraceLog,
119
+ prepareProviderTraceLog,
119
120
  printApiKeyPanel,
120
121
  printCloudProviderPanel,
121
122
  printDryRunPanel,
@@ -126,6 +127,7 @@ import {
126
127
  printTraceLog,
127
128
  printWelcomePanel,
128
129
  providerAuthHelpText,
130
+ providerRefreshToken,
129
131
  providerSelectOption,
130
132
  providersForPicker,
131
133
  providersForTarget,
@@ -182,14 +184,15 @@ import {
182
184
  validateCustomEndpointUrl,
183
185
  writeSecureLogLine,
184
186
  zenRegistryStub
185
- } from "./chunk-GHSURQOK.js";
187
+ } from "./chunk-5DDQJSTU.js";
186
188
  import {
187
189
  filterTemplates,
190
+ getTemplateById,
188
191
  init_provider_templates,
189
192
  listAddableTemplates,
190
193
  listSupportedTemplates,
191
194
  listVisibleOAuthTemplates
192
- } from "./chunk-HXGZ4CTV.js";
195
+ } from "./chunk-Q2FTCICO.js";
193
196
 
194
197
  // src/cli.ts
195
198
  import pc12 from "picocolors";
@@ -1288,7 +1291,7 @@ ${pc4.bold("Subcommands:")}
1288
1291
  (none) Provider hub wizard ${pc4.dim("[Phase 1.1]")}
1289
1292
  add Add a provider (Groq, Mistral, Together AI, \u2026) ${pc4.dim("[Phase 1.1]")}
1290
1293
  import Optional one-time import from OpenCode CLI ${pc4.dim("[Phase 1.0]")}
1291
- auth Sign in with OAuth (GitHub Copilot, xAI, OpenAI)
1294
+ auth Sign in with OAuth (GitHub Copilot, xAI, OpenAI, ClinePass)
1292
1295
  list Show configured providers ${pc4.dim("[Phase 1.0]")}
1293
1296
  remove Remove a provider by id ${pc4.dim("[Phase 1.1]")}
1294
1297
  refresh-models Update cached model lists ${pc4.dim("[Phase 1.2]")}`;
@@ -1510,6 +1513,69 @@ async function pickTemplateFromCatalog() {
1510
1513
  if (template) return template;
1511
1514
  }
1512
1515
  }
1516
+ function hasApiAndOAuth(template) {
1517
+ const methods = template.authMethods ?? [template.authType];
1518
+ return methods.includes("api") && methods.includes("oauth");
1519
+ }
1520
+ function showProviderAddFailure(error, hint, fallback) {
1521
+ printPanel(pc4.red("Provider was not added"), [
1522
+ pc4.white(error ?? fallback),
1523
+ pc4.dim("No changes were saved."),
1524
+ ...hint ? [pc4.white(hint)] : []
1525
+ ]);
1526
+ }
1527
+ async function runDualAuthTemplateFlow(template, existing) {
1528
+ const method = await p5.select({
1529
+ message: existing ? `Change ${template.name} authentication` : `How would you like to connect to ${template.name}?`,
1530
+ options: [
1531
+ {
1532
+ value: "api",
1533
+ label: "Use an API key",
1534
+ hint: existing?.authType === "api" ? "Replace the current API key" : "Use your ClinePass API key"
1535
+ },
1536
+ {
1537
+ value: "oauth",
1538
+ label: "Sign in with ClinePass",
1539
+ hint: "One-time device code; uses your ClinePass account"
1540
+ },
1541
+ { value: "back", label: "Back", hint: "" }
1542
+ ]
1543
+ });
1544
+ if (p5.isCancel(method) || method === "back") return 0;
1545
+ if (method === "oauth") {
1546
+ return runProvidersAuth(template.id);
1547
+ }
1548
+ if (template.signupUrl) {
1549
+ printPanel(fmtProvider(template.name), [
1550
+ `${pc4.white("Get an API key at:")} ${fmtUrl(template.signupUrl)}`
1551
+ ]);
1552
+ }
1553
+ const apiKeyInput = await p5.password({
1554
+ message: `Paste your ${template.name} API key:`,
1555
+ validate: (value) => value.trim() ? void 0 : "Key cannot be empty"
1556
+ });
1557
+ if (p5.isCancel(apiKeyInput)) {
1558
+ p5.cancel("Cancelled.");
1559
+ return 0;
1560
+ }
1561
+ const apiKey = String(apiKeyInput).trim();
1562
+ if (!apiKey) {
1563
+ showProviderAddFailure("Key cannot be empty.", void 0, "Could not add provider.");
1564
+ return 1;
1565
+ }
1566
+ const spinner9 = p5.spinner();
1567
+ spinner9.start(`Testing connection to ${template.name}...`);
1568
+ const result = await addProviderFromTemplate(template, apiKey, {
1569
+ replaceExisting: Boolean(existing)
1570
+ });
1571
+ spinner9.stop("");
1572
+ if (!result.added) {
1573
+ showProviderAddFailure(result.error, result.hint, "Could not add provider.");
1574
+ return 1;
1575
+ }
1576
+ logConnected(template.name, result.modelCount ?? 0);
1577
+ return 0;
1578
+ }
1513
1579
  async function runTemplateAddFlow() {
1514
1580
  if (listAddableTemplates(loadRegistry().providers.map((p15) => p15.id)).length === 0) {
1515
1581
  p5.log.info("All catalog providers are already configured.");
@@ -1517,6 +1583,9 @@ async function runTemplateAddFlow() {
1517
1583
  }
1518
1584
  const template = await pickTemplateFromCatalog();
1519
1585
  if (!template) return 0;
1586
+ if (hasApiAndOAuth(template)) {
1587
+ return runDualAuthTemplateFlow(template);
1588
+ }
1520
1589
  if (template.modelSource === "zen-go-api") {
1521
1590
  const existingKey = await readGlobalOpencodeCredential();
1522
1591
  let apiKey2 = existingKey;
@@ -1599,8 +1668,7 @@ async function runTemplateAddFlow() {
1599
1668
  const result = await addProviderFromTemplate(template, apiKey, { baseUrl: baseUrlOverride });
1600
1669
  spinner9.stop("");
1601
1670
  if (!result.added) {
1602
- p5.log.error(result.error ?? "Could not add provider.");
1603
- if (result.hint) p5.log.info(result.hint);
1671
+ showProviderAddFailure(result.error, result.hint, "Could not add provider.");
1604
1672
  return 1;
1605
1673
  }
1606
1674
  logConnected(template.name, result.modelCount ?? 0);
@@ -1688,8 +1756,7 @@ async function runCustomEndpointAddFlow() {
1688
1756
  });
1689
1757
  spinner9.stop("");
1690
1758
  if (!result.added) {
1691
- p5.log.error(result.error ?? "Could not add custom provider.");
1692
- if (result.hint) p5.log.info(result.hint);
1759
+ showProviderAddFailure(result.error, result.hint, "Could not add custom provider.");
1693
1760
  return 1;
1694
1761
  }
1695
1762
  logConnected(result.provider?.name ?? "Provider", result.modelCount ?? 0);
@@ -1792,6 +1859,8 @@ async function runProviderDetail(id) {
1792
1859
  const modelCount = provider.modelsCache?.models.length ?? 0;
1793
1860
  const authLabel = formatRegistryAuthLabel(provider);
1794
1861
  printProviderDetailPanel(provider.name, modelCount, authLabel);
1862
+ const template = getTemplateById(provider.templateId) ?? getTemplateById(id);
1863
+ const hasDualAuth = template ? hasApiAndOAuth(template) : false;
1795
1864
  const detailOptions = [];
1796
1865
  if (modelCount > 0) {
1797
1866
  detailOptions.push({
@@ -1805,7 +1874,13 @@ async function runProviderDetail(id) {
1805
1874
  label: "Refresh model list",
1806
1875
  hint: "Fetch latest models from the provider API"
1807
1876
  });
1808
- if (supportsNativeOAuth(id) || provider.authType === "oauth") {
1877
+ if (hasDualAuth && template) {
1878
+ detailOptions.push({
1879
+ value: "change-auth",
1880
+ label: "Change authentication (API/OAuth)",
1881
+ hint: "Switch between a ClinePass API key and account sign-in"
1882
+ });
1883
+ } else if (supportsNativeOAuth(id) || provider.authType === "oauth") {
1809
1884
  detailOptions.push({
1810
1885
  value: "auth",
1811
1886
  label: "Sign in again (OAuth)",
@@ -1839,12 +1914,13 @@ async function runProviderDetail(id) {
1839
1914
  return "back";
1840
1915
  }
1841
1916
  if (action === "refresh") {
1842
- await runProvidersRefreshModels(id);
1843
- return "back";
1917
+ return await runProvidersRefreshModels(id) === 0 ? "back" : "failed";
1918
+ }
1919
+ if (action === "change-auth" && template) {
1920
+ return await runDualAuthTemplateFlow(template, provider) === 0 ? "back" : "failed";
1844
1921
  }
1845
1922
  if (action === "auth") {
1846
- await runProvidersAuth(id);
1847
- return "back";
1923
+ return await runProvidersAuth(id) === 0 ? "back" : "failed";
1848
1924
  }
1849
1925
  if (action === "toggle") {
1850
1926
  const result = toggleProviderEnabled(id);
@@ -1854,10 +1930,11 @@ async function runProviderDetail(id) {
1854
1930
  return "back";
1855
1931
  }
1856
1932
  const code = await runProvidersRemove(id, true);
1857
- return code === 0 ? "removed" : "back";
1933
+ return code === 0 ? "removed" : "failed";
1858
1934
  }
1859
1935
  async function runProvidersHub() {
1860
1936
  const hasOpencode = findOpencodeBinary() !== null;
1937
+ let lastOperationFailed = false;
1861
1938
  while (true) {
1862
1939
  const entries = await resolveProvidersForDisplay();
1863
1940
  const options = [
@@ -1885,18 +1962,18 @@ async function runProvidersHub() {
1885
1962
  options
1886
1963
  });
1887
1964
  if (p5.isCancel(choice) || choice === "done") {
1888
- return 0;
1965
+ return lastOperationFailed ? 1 : 0;
1889
1966
  }
1890
1967
  if (choice === "add") {
1891
- await runProvidersAdd();
1968
+ lastOperationFailed = await runProvidersAdd() !== 0;
1892
1969
  continue;
1893
1970
  }
1894
1971
  if (choice === "import") {
1895
- await runProvidersImport();
1972
+ lastOperationFailed = await runProvidersImport() !== 0;
1896
1973
  continue;
1897
1974
  }
1898
1975
  if (choice === "refresh-all") {
1899
- await runProvidersRefreshModels();
1976
+ lastOperationFailed = await runProvidersRefreshModels() !== 0;
1900
1977
  continue;
1901
1978
  }
1902
1979
  if (choice === "auth-menu") {
@@ -1914,7 +1991,9 @@ async function runProvidersHub() {
1914
1991
  hint: "device code"
1915
1992
  }))
1916
1993
  });
1917
- if (!p5.isCancel(providerId)) await runProvidersAuth(providerId);
1994
+ if (!p5.isCancel(providerId)) {
1995
+ lastOperationFailed = await runProvidersAuth(providerId) !== 0;
1996
+ }
1918
1997
  continue;
1919
1998
  }
1920
1999
  if (typeof choice === "string" && choice.startsWith("cloud:")) {
@@ -1925,6 +2004,7 @@ async function runProvidersHub() {
1925
2004
  if (typeof choice === "string" && choice.startsWith("provider:")) {
1926
2005
  const id = choice.slice("provider:".length);
1927
2006
  const outcome = await runProviderDetail(id);
2007
+ lastOperationFailed = outcome === "failed";
1928
2008
  if (outcome === "removed") continue;
1929
2009
  }
1930
2010
  }
@@ -3199,7 +3279,11 @@ async function startCodexProxy(routes, options = {}) {
3199
3279
  oauthAccountId: route.oauthAccountId,
3200
3280
  providerData: route.providerData,
3201
3281
  vertex: route.vertex,
3202
- headers: route.headers
3282
+ headers: route.headers,
3283
+ refreshToken: route.refreshToken,
3284
+ onTokenRefreshed: (refreshed) => {
3285
+ route.apiKey = refreshed;
3286
+ }
3203
3287
  }));
3204
3288
  }
3205
3289
  return new Promise((resolve2, reject2) => {
@@ -3744,7 +3828,8 @@ function resolveCodexRoute(provider, model, apiKey) {
3744
3828
  supportedParameters: model.supportedParameters,
3745
3829
  reasoning: model.reasoning,
3746
3830
  interleavedReasoningField: model.interleavedReasoningField,
3747
- headers: provider.headers
3831
+ headers: provider.headers,
3832
+ refreshToken: providerRefreshToken(provider.id, provider.authType, provider.authRef)
3748
3833
  };
3749
3834
  if (model.modelFormat === "cloud-code") {
3750
3835
  return {
@@ -3762,7 +3847,8 @@ function resolveCodexRoute(provider, model, apiKey) {
3762
3847
  supportedParameters: model.supportedParameters,
3763
3848
  reasoning: model.reasoning,
3764
3849
  interleavedReasoningField: model.interleavedReasoningField,
3765
- headers: provider.headers
3850
+ headers: provider.headers,
3851
+ refreshToken: providerRefreshToken(provider.id, provider.authType, provider.authRef)
3766
3852
  };
3767
3853
  }
3768
3854
  if (model.npm === "@ai-sdk/openai" && provider.authType !== "oauth" && model.modelFormat === "openai") {
@@ -4304,7 +4390,9 @@ async function resolveFavorite(fav, ctx) {
4304
4390
  apiKey: await resolveLocalProviderApiKey(found.provider) ?? "",
4305
4391
  authType: found.provider.authType,
4306
4392
  oauthAccountId: found.provider.oauthAccountId,
4307
- providerData: found.provider.providerData
4393
+ providerData: found.provider.providerData,
4394
+ headers: found.provider.headers,
4395
+ refreshToken: providerRefreshToken(found.provider.id, found.provider.authType, found.provider.authRef)
4308
4396
  };
4309
4397
  }
4310
4398
  return void 0;
@@ -5206,7 +5294,8 @@ Error: ${launchPlan.error}
5206
5294
  supportedParameters: route.supportedParameters,
5207
5295
  reasoning: route.reasoning,
5208
5296
  interleavedReasoningField: route.interleavedReasoningField,
5209
- headers: route.headers
5297
+ headers: route.headers,
5298
+ refreshToken: route.refreshToken
5210
5299
  }], { debug: trace });
5211
5300
  proxyPort = proxyHandle.port;
5212
5301
  }
@@ -5700,7 +5789,11 @@ async function startGeminiProxy(routes, debug = false) {
5700
5789
  authType: route.authType,
5701
5790
  oauthAccountId: route.oauthAccountId,
5702
5791
  providerData: route.providerData,
5703
- headers: route.headers
5792
+ headers: route.headers,
5793
+ refreshToken: route.refreshToken,
5794
+ onTokenRefreshed: (refreshed) => {
5795
+ route.apiKey = refreshed;
5796
+ }
5704
5797
  });
5705
5798
  models.set(route.aliasId, m);
5706
5799
  }
@@ -7471,6 +7564,26 @@ var MAX_REASONING_ECHOES_PER_CONVERSATION = 20;
7471
7564
  function isCloudCodeOAuthRoute(route) {
7472
7565
  return route.providerId === "antigravity" && route.authType === "oauth" && route.modelFormat === "cloud-code";
7473
7566
  }
7567
+ async function createRouteLanguageModel(route) {
7568
+ const spec = {
7569
+ npm: route.npm,
7570
+ modelId: route.upstreamModelId,
7571
+ apiKey: route.apiKey,
7572
+ baseURL: route.baseURL,
7573
+ providerId: route.providerId,
7574
+ authType: route.authType,
7575
+ oauthAccountId: route.oauthAccountId,
7576
+ providerData: route.providerData
7577
+ };
7578
+ if (route.headers !== void 0) spec.headers = route.headers;
7579
+ if (route.refreshToken) {
7580
+ spec.refreshToken = route.refreshToken;
7581
+ spec.onTokenRefreshed = (refreshed) => {
7582
+ route.apiKey = refreshed;
7583
+ };
7584
+ }
7585
+ return createLanguageModel(spec);
7586
+ }
7474
7587
  function isUserTurnRequest(parsed) {
7475
7588
  return typeof parsed?.requestId === "string" && parsed.requestId.startsWith("agent/");
7476
7589
  }
@@ -8021,16 +8134,7 @@ async function handleStreamingRequest(res, route, providerOptions, parsed, log14
8021
8134
  providerOptions,
8022
8135
  sdkParams.providerOptions
8023
8136
  );
8024
- const langModel = await createLanguageModel({
8025
- npm: route.npm,
8026
- modelId: route.upstreamModelId,
8027
- apiKey: route.apiKey,
8028
- baseURL: route.baseURL,
8029
- providerId: route.providerId,
8030
- authType: route.authType,
8031
- oauthAccountId: route.oauthAccountId,
8032
- providerData: route.providerData
8033
- });
8137
+ const langModel = await createRouteLanguageModel(route);
8034
8138
  const responseId = `relay-${Date.now()}`;
8035
8139
  const { fullStream } = streamText3({
8036
8140
  model: langModel,
@@ -8207,16 +8311,7 @@ async function handleUnaryRequest(res, route, providerOptions, parsed, log14, op
8207
8311
  providerOptions,
8208
8312
  sdkParams.providerOptions
8209
8313
  );
8210
- const langModel = await createLanguageModel({
8211
- npm: route.npm,
8212
- modelId: route.upstreamModelId,
8213
- apiKey: route.apiKey,
8214
- baseURL: route.baseURL,
8215
- providerId: route.providerId,
8216
- authType: route.authType,
8217
- oauthAccountId: route.oauthAccountId,
8218
- providerData: route.providerData
8219
- });
8314
+ const langModel = await createRouteLanguageModel(route);
8220
8315
  const responseId = `relay-${Date.now()}`;
8221
8316
  const result = await generateText3({
8222
8317
  model: langModel,
@@ -8275,7 +8370,9 @@ async function resolveAntigravityLaunchRoutes(opts) {
8275
8370
  apiKey,
8276
8371
  authType: opts.provider.authType,
8277
8372
  oauthAccountId: opts.provider.oauthAccountId,
8278
- providerData: opts.provider.providerData
8373
+ providerData: opts.provider.providerData,
8374
+ headers: opts.provider.headers,
8375
+ refreshToken: providerRefreshToken(opts.provider.id, opts.provider.authType, opts.provider.authRef)
8279
8376
  };
8280
8377
  const ctx = {
8281
8378
  agent: "antigravity",
@@ -9117,7 +9214,8 @@ function codexRouteToProxyRoute(provider, model, apiKey) {
9117
9214
  supportedParameters: route.supportedParameters,
9118
9215
  reasoning: route.reasoning,
9119
9216
  interleavedReasoningField: route.interleavedReasoningField,
9120
- headers: route.headers
9217
+ headers: route.headers,
9218
+ refreshToken: route.refreshToken
9121
9219
  };
9122
9220
  }
9123
9221
  async function buildCodexAppProviderCatalogRoutes(provider, apiKey, selectedModelId, trace) {
@@ -9583,7 +9681,8 @@ function codexProxyRouteToCodexRoute(route, fallbackProviderId) {
9583
9681
  supportedParameters: route.supportedParameters,
9584
9682
  reasoning: route.reasoning,
9585
9683
  interleavedReasoningField: route.interleavedReasoningField,
9586
- headers: route.headers
9684
+ headers: route.headers,
9685
+ refreshToken: route.refreshToken
9587
9686
  };
9588
9687
  }
9589
9688
  async function waitForShutdownWithConfirm() {
@@ -13384,7 +13483,9 @@ Error: ${launchPlan.error}
13384
13483
  reasoning: selectedModel.reasoning,
13385
13484
  interleavedReasoningField: selectedModel.interleavedReasoningField,
13386
13485
  useResponsesLite: selectedModel.useResponsesLite,
13387
- preferWebSockets: selectedModel.preferWebSockets
13486
+ preferWebSockets: selectedModel.preferWebSockets,
13487
+ refreshToken: providerRefreshToken(activeProvider.id, activeProvider.authType, activeProvider.authRef),
13488
+ headers: activeProvider.headers
13388
13489
  },
13389
13490
  launchApiKey
13390
13491
  );
@@ -13492,7 +13593,7 @@ Options:
13492
13593
  --trace Write debug logs under ~/.relay-ai/logs/`);
13493
13594
  return 0;
13494
13595
  }
13495
- const { runUiCommand } = await import("./ui-command-27X4WJKC.js");
13596
+ const { runUiCommand } = await import("./ui-command-RYWL36VR.js");
13496
13597
  return runUiCommand({ trace: parsed.trace, serverMode: parsed.uiServerMode });
13497
13598
  }
13498
13599
  if (parsed.command === "models") {
@@ -13517,6 +13618,12 @@ Options:
13517
13618
  }
13518
13619
  if (parsed.trace) {
13519
13620
  process.env.RELAY_AI_TRACE = "1";
13621
+ const providerTraceLogPath = prepareProviderTraceLog();
13622
+ try {
13623
+ return await runProvidersCommand(parsed.claudeArgs);
13624
+ } finally {
13625
+ printTraceLog(providerTraceLogPath);
13626
+ }
13520
13627
  }
13521
13628
  return runProvidersCommand(parsed.claudeArgs);
13522
13629
  }