@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.
- package/README.md +8 -4
- package/dist/{chunk-GHSURQOK.js → chunk-5DDQJSTU.js} +535 -104
- package/dist/chunk-5DDQJSTU.js.map +1 -0
- package/dist/{chunk-HXGZ4CTV.js → chunk-Q2FTCICO.js} +19 -3
- package/dist/chunk-Q2FTCICO.js.map +1 -0
- package/dist/cli.js +156 -49
- package/dist/cli.js.map +1 -1
- package/dist/core/index.js +628 -7
- package/dist/core/index.js.map +1 -1
- package/dist/{provider-templates-4H3C4DRL.js → provider-templates-XKNRKAQU.js} +2 -2
- package/dist/ui/public/app.js +106 -0
- package/dist/{ui-command-27X4WJKC.js → ui-command-RYWL36VR.js} +44 -7
- package/dist/ui-command-RYWL36VR.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-GHSURQOK.js.map +0 -1
- package/dist/chunk-HXGZ4CTV.js.map +0 -1
- package/dist/ui-command-27X4WJKC.js.map +0 -1
- /package/dist/{provider-templates-4H3C4DRL.js.map → provider-templates-XKNRKAQU.js.map} +0 -0
|
@@ -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.
|
|
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) =>
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
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
|
-
|
|
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" : "
|
|
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))
|
|
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
|
|
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
|
|
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-
|
|
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
|
}
|