@vheins/opencode-9router 0.1.0 → 0.3.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/dist/constants.d.ts +13 -0
- package/dist/constants.js +68 -0
- package/dist/plugin.d.ts +2 -0
- package/dist/plugin.js +86 -0
- package/package.json +25 -13
- package/index.ts +0 -1
- package/src/constants.ts +0 -80
- package/src/plugin.ts +0 -111
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare const PLUGIN_NAME = "9router";
|
|
2
|
+
export declare const PROVIDER_DISPLAY_NAME = "9Router";
|
|
3
|
+
export declare const DEFAULT_BASE_URL = "http://localhost:20128";
|
|
4
|
+
export declare const DEFAULT_API_PATH = "/v1";
|
|
5
|
+
/**
|
|
6
|
+
* Well-known 9Router models used as fallback when the API is unreachable.
|
|
7
|
+
* Covers the most common providers and tiers routed through 9Router.
|
|
8
|
+
*/
|
|
9
|
+
export declare const FALLBACK_MODELS: Record<string, {
|
|
10
|
+
name: string;
|
|
11
|
+
}>;
|
|
12
|
+
/** Known provider prefixes in 9Router model IDs for human-readable naming. */
|
|
13
|
+
export declare const KNOWN_PROVIDER_PREFIXES: Record<string, string>;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
export const PLUGIN_NAME = "9router";
|
|
2
|
+
export const PROVIDER_DISPLAY_NAME = "9Router";
|
|
3
|
+
export const DEFAULT_BASE_URL = "http://localhost:20128";
|
|
4
|
+
export const DEFAULT_API_PATH = "/v1";
|
|
5
|
+
/**
|
|
6
|
+
* Well-known 9Router models used as fallback when the API is unreachable.
|
|
7
|
+
* Covers the most common providers and tiers routed through 9Router.
|
|
8
|
+
*/
|
|
9
|
+
export const FALLBACK_MODELS = {
|
|
10
|
+
// --- Claude Code (Subscription) ---
|
|
11
|
+
"cc/claude-opus-4-7": { name: "Claude Opus 4.7 (Claude Code)" },
|
|
12
|
+
"cc/claude-opus-4-6": { name: "Claude Opus 4.6 (Claude Code)" },
|
|
13
|
+
"cc/claude-sonnet-4-6": { name: "Claude Sonnet 4.6 (Claude Code)" },
|
|
14
|
+
"cc/claude-haiku-4-5-20251001": { name: "Claude Haiku 4.5 (Claude Code)" },
|
|
15
|
+
// --- OpenCode / Codex (Subscription) ---
|
|
16
|
+
"cx/gpt-5.5": { name: "GPT-5.5 (Codex)" },
|
|
17
|
+
"cx/gpt-5.4": { name: "GPT-5.4 (Codex)" },
|
|
18
|
+
// --- GitHub Copilot (Subscription) ---
|
|
19
|
+
"gh/gpt-5.4": { name: "GPT-5.4 (Copilot)" },
|
|
20
|
+
"gh/claude-sonnet-4.6": { name: "Claude Sonnet 4.6 (Copilot)" },
|
|
21
|
+
// --- Kiro AI (FREE) ---
|
|
22
|
+
"kr/claude-sonnet-4.5": { name: "Claude Sonnet 4.5 (Kiro Free)" },
|
|
23
|
+
"kr/claude-haiku-4.5": { name: "Claude Haiku 4.5 (Kiro Free)" },
|
|
24
|
+
"kr/glm-5": { name: "GLM-5 (Kiro Free)" },
|
|
25
|
+
"kr/MiniMax-M2.5": { name: "MiniMax M2.5 (Kiro Free)" },
|
|
26
|
+
"kr/qwen3-coder-next": { name: "Qwen3 Coder Next (Kiro Free)" },
|
|
27
|
+
"kr/deepseek-3.2": { name: "DeepSeek 3.2 (Kiro Free)" },
|
|
28
|
+
// --- OpenCode Free (FREE) ---
|
|
29
|
+
"oc/auto": { name: "OpenCode Free (Auto)" },
|
|
30
|
+
// --- Vertex AI ($300 credits) ---
|
|
31
|
+
"vertex/gemini-3.1-pro-preview": { name: "Gemini 3.1 Pro (Vertex)" },
|
|
32
|
+
"vertex/gemini-3-flash-preview": { name: "Gemini 3 Flash (Vertex)" },
|
|
33
|
+
// --- GLM (Cheap, $0.6/1M) ---
|
|
34
|
+
"glm/glm-5.1": { name: "GLM-5.1" },
|
|
35
|
+
"glm/glm-5": { name: "GLM-5" },
|
|
36
|
+
"glm/glm-4.7": { name: "GLM-4.7" },
|
|
37
|
+
// --- MiniMax (Cheapest, $0.2/1M) ---
|
|
38
|
+
"minimax/MiniMax-M2.7": { name: "MiniMax M2.7" },
|
|
39
|
+
"minimax/MiniMax-M2.5": { name: "MiniMax M2.5" },
|
|
40
|
+
// --- Kimi ($9/mo flat) ---
|
|
41
|
+
"kimi/kimi-k2.5": { name: "Kimi K2.5" },
|
|
42
|
+
"kimi/kimi-k2.5-thinking": { name: "Kimi K2.5 (Thinking)" },
|
|
43
|
+
// --- Cursor (Subscription) ---
|
|
44
|
+
"cu/claude-4.6-opus-max": { name: "Claude 4.6 Opus Max (Cursor)" },
|
|
45
|
+
// --- Standard Key Providers ---
|
|
46
|
+
"deepseek/deepseek-chat": { name: "DeepSeek Chat" },
|
|
47
|
+
"groq/llama-4.5-70b": { name: "Llama 4.5 70B (Groq)" },
|
|
48
|
+
};
|
|
49
|
+
/** Known provider prefixes in 9Router model IDs for human-readable naming. */
|
|
50
|
+
export const KNOWN_PROVIDER_PREFIXES = {
|
|
51
|
+
"cc/": "Claude Code",
|
|
52
|
+
"cx/": "Codex",
|
|
53
|
+
"gh/": "GitHub Copilot",
|
|
54
|
+
"kr/": "Kiro AI",
|
|
55
|
+
"oc/": "OpenCode Free",
|
|
56
|
+
"vertex/": "Vertex AI",
|
|
57
|
+
"vertex-partner/": "Vertex Partner",
|
|
58
|
+
"glm/": "GLM",
|
|
59
|
+
"minimax/": "MiniMax",
|
|
60
|
+
"kimi/": "Kimi",
|
|
61
|
+
"cu/": "Cursor",
|
|
62
|
+
"gc/": "Gemini CLI",
|
|
63
|
+
"if/": "iFlow",
|
|
64
|
+
"qw/": "Qwen",
|
|
65
|
+
"openrouter/": "OpenRouter",
|
|
66
|
+
"deepseek/": "DeepSeek",
|
|
67
|
+
"groq/": "Groq",
|
|
68
|
+
};
|
package/dist/plugin.d.ts
ADDED
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { PLUGIN_NAME, PROVIDER_DISPLAY_NAME, DEFAULT_BASE_URL, DEFAULT_API_PATH, FALLBACK_MODELS, KNOWN_PROVIDER_PREFIXES, } from "./constants.js";
|
|
2
|
+
function formatModelName(modelId) {
|
|
3
|
+
for (const [prefix, provider] of Object.entries(KNOWN_PROVIDER_PREFIXES)) {
|
|
4
|
+
if (modelId.startsWith(prefix)) {
|
|
5
|
+
return `${modelId.slice(prefix.length)} (${provider})`;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
return modelId;
|
|
9
|
+
}
|
|
10
|
+
async function discoverModels(baseURL) {
|
|
11
|
+
const apiURL = `${baseURL}${DEFAULT_API_PATH}`;
|
|
12
|
+
try {
|
|
13
|
+
const response = await fetch(`${apiURL}/models`, {
|
|
14
|
+
signal: AbortSignal.timeout(3000),
|
|
15
|
+
});
|
|
16
|
+
if (!response.ok)
|
|
17
|
+
return null;
|
|
18
|
+
const data = (await response.json());
|
|
19
|
+
if (!data.data || !Array.isArray(data.data) || data.data.length === 0) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
const models = {};
|
|
23
|
+
for (const model of data.data) {
|
|
24
|
+
models[model.id] = { name: formatModelName(model.id) };
|
|
25
|
+
}
|
|
26
|
+
return models;
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export const NineRouterPlugin = async ({ client }) => {
|
|
33
|
+
const configuredBaseURL = DEFAULT_BASE_URL;
|
|
34
|
+
const discovered = await discoverModels(configuredBaseURL);
|
|
35
|
+
const models = discovered ?? FALLBACK_MODELS;
|
|
36
|
+
if (!discovered && client?.app?.log) {
|
|
37
|
+
await client.app.log({
|
|
38
|
+
body: {
|
|
39
|
+
service: "9router-provider",
|
|
40
|
+
level: "warn",
|
|
41
|
+
message: `9Router not reachable at ${configuredBaseURL}. Using well-known model list. Start 9Router and restart opencode to auto-discover models.`,
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
provider: {
|
|
47
|
+
[PLUGIN_NAME]: {
|
|
48
|
+
npm: "@ai-sdk/openai-compatible",
|
|
49
|
+
name: PROVIDER_DISPLAY_NAME,
|
|
50
|
+
options: {
|
|
51
|
+
baseURL: `${configuredBaseURL}${DEFAULT_API_PATH}`,
|
|
52
|
+
},
|
|
53
|
+
models,
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
auth: {
|
|
57
|
+
provider: PLUGIN_NAME,
|
|
58
|
+
async loader(getAuth) {
|
|
59
|
+
const auth = await getAuth();
|
|
60
|
+
if (auth && typeof auth === "object" && "baseURL" in auth) {
|
|
61
|
+
return { baseURL: `${String(auth.baseURL)}${DEFAULT_API_PATH}` };
|
|
62
|
+
}
|
|
63
|
+
return {};
|
|
64
|
+
},
|
|
65
|
+
methods: [
|
|
66
|
+
{
|
|
67
|
+
label: `Connect to ${PROVIDER_DISPLAY_NAME}`,
|
|
68
|
+
type: "api",
|
|
69
|
+
prompts: [
|
|
70
|
+
{
|
|
71
|
+
type: "text",
|
|
72
|
+
message: `${PROVIDER_DISPLAY_NAME} Base URL (default: ${DEFAULT_BASE_URL})`,
|
|
73
|
+
key: "baseURL",
|
|
74
|
+
default: DEFAULT_BASE_URL,
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
type: "text",
|
|
78
|
+
message: `${PROVIDER_DISPLAY_NAME} API Key (from Dashboard → Endpoints)`,
|
|
79
|
+
key: "apiKey",
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vheins/opencode-9router",
|
|
3
|
-
"
|
|
4
|
-
"version": "0.1.0",
|
|
3
|
+
"version": "0.3.0",
|
|
5
4
|
"description": "OpenCode plugin provider for 9Router — FREE AI Router & Token Saver. 40+ providers, 100+ models.",
|
|
6
5
|
"author": "vheins",
|
|
7
6
|
"keywords": [
|
|
@@ -14,21 +13,34 @@
|
|
|
14
13
|
"token-saver",
|
|
15
14
|
"plugin"
|
|
16
15
|
],
|
|
17
|
-
"repository":
|
|
18
|
-
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
],
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/vheins/opencode-9router.git"
|
|
19
|
+
},
|
|
22
20
|
"license": "MIT",
|
|
23
21
|
"type": "module",
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"types": "./dist/plugin.d.ts",
|
|
25
|
+
"default": "./dist/plugin.js"
|
|
26
|
+
}
|
|
27
27
|
},
|
|
28
|
-
"
|
|
29
|
-
|
|
28
|
+
"main": "dist/plugin.js",
|
|
29
|
+
"types": "dist/plugin.d.ts",
|
|
30
|
+
"files": [
|
|
31
|
+
"dist",
|
|
32
|
+
"README.md",
|
|
33
|
+
"LICENSE"
|
|
34
|
+
],
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "tsc",
|
|
37
|
+
"prepublishOnly": "npm run build"
|
|
30
38
|
},
|
|
31
39
|
"dependencies": {
|
|
32
|
-
"@opencode-ai/plugin": "^1.0.182"
|
|
40
|
+
"@opencode-ai/plugin": "^1.0.182",
|
|
41
|
+
"@opencode-ai/sdk": "^1.0.182"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"typescript": "^5.9.3"
|
|
33
45
|
}
|
|
34
46
|
}
|
package/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from "./src/plugin";
|
package/src/constants.ts
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
export const PLUGIN_NAME = "9router";
|
|
2
|
-
export const PROVIDER_DISPLAY_NAME = "9Router";
|
|
3
|
-
export const DEFAULT_BASE_URL = "http://localhost:20128";
|
|
4
|
-
export const DEFAULT_API_PATH = "/v1";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Well-known 9Router models used as fallback when the API is unreachable.
|
|
8
|
-
* Covers the most common providers and tiers routed through 9Router.
|
|
9
|
-
*/
|
|
10
|
-
export const FALLBACK_MODELS: Record<string, { name: string }> = {
|
|
11
|
-
// --- Claude Code (Subscription) ---
|
|
12
|
-
"cc/claude-opus-4-7": { name: "Claude Opus 4.7 (Claude Code)" },
|
|
13
|
-
"cc/claude-opus-4-6": { name: "Claude Opus 4.6 (Claude Code)" },
|
|
14
|
-
"cc/claude-sonnet-4-6": { name: "Claude Sonnet 4.6 (Claude Code)" },
|
|
15
|
-
"cc/claude-haiku-4-5-20251001": { name: "Claude Haiku 4.5 (Claude Code)" },
|
|
16
|
-
|
|
17
|
-
// --- OpenCode / Codex (Subscription) ---
|
|
18
|
-
"cx/gpt-5.5": { name: "GPT-5.5 (Codex)" },
|
|
19
|
-
"cx/gpt-5.4": { name: "GPT-5.4 (Codex)" },
|
|
20
|
-
|
|
21
|
-
// --- GitHub Copilot (Subscription) ---
|
|
22
|
-
"gh/gpt-5.4": { name: "GPT-5.4 (Copilot)" },
|
|
23
|
-
"gh/claude-sonnet-4.6": { name: "Claude Sonnet 4.6 (Copilot)" },
|
|
24
|
-
|
|
25
|
-
// --- Kiro AI (FREE) ---
|
|
26
|
-
"kr/claude-sonnet-4.5": { name: "Claude Sonnet 4.5 (Kiro Free)" },
|
|
27
|
-
"kr/claude-haiku-4.5": { name: "Claude Haiku 4.5 (Kiro Free)" },
|
|
28
|
-
"kr/glm-5": { name: "GLM-5 (Kiro Free)" },
|
|
29
|
-
"kr/MiniMax-M2.5": { name: "MiniMax M2.5 (Kiro Free)" },
|
|
30
|
-
"kr/qwen3-coder-next": { name: "Qwen3 Coder Next (Kiro Free)" },
|
|
31
|
-
"kr/deepseek-3.2": { name: "DeepSeek 3.2 (Kiro Free)" },
|
|
32
|
-
|
|
33
|
-
// --- OpenCode Free (FREE) ---
|
|
34
|
-
"oc/auto": { name: "OpenCode Free (Auto)" },
|
|
35
|
-
|
|
36
|
-
// --- Vertex AI ($300 credits) ---
|
|
37
|
-
"vertex/gemini-3.1-pro-preview": { name: "Gemini 3.1 Pro (Vertex)" },
|
|
38
|
-
"vertex/gemini-3-flash-preview": { name: "Gemini 3 Flash (Vertex)" },
|
|
39
|
-
|
|
40
|
-
// --- GLM (Cheap, $0.6/1M) ---
|
|
41
|
-
"glm/glm-5.1": { name: "GLM-5.1" },
|
|
42
|
-
"glm/glm-5": { name: "GLM-5" },
|
|
43
|
-
"glm/glm-4.7": { name: "GLM-4.7" },
|
|
44
|
-
|
|
45
|
-
// --- MiniMax (Cheapest, $0.2/1M) ---
|
|
46
|
-
"minimax/MiniMax-M2.7": { name: "MiniMax M2.7" },
|
|
47
|
-
"minimax/MiniMax-M2.5": { name: "MiniMax M2.5" },
|
|
48
|
-
|
|
49
|
-
// --- Kimi ($9/mo flat) ---
|
|
50
|
-
"kimi/kimi-k2.5": { name: "Kimi K2.5" },
|
|
51
|
-
"kimi/kimi-k2.5-thinking": { name: "Kimi K2.5 (Thinking)" },
|
|
52
|
-
|
|
53
|
-
// --- Cursor (Subscription) ---
|
|
54
|
-
"cu/claude-4.6-opus-max": { name: "Claude 4.6 Opus Max (Cursor)" },
|
|
55
|
-
|
|
56
|
-
// --- Standard Key Providers ---
|
|
57
|
-
"deepseek/deepseek-chat": { name: "DeepSeek Chat" },
|
|
58
|
-
"groq/llama-4.5-70b": { name: "Llama 4.5 70B (Groq)" },
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
/** Known provider prefixes in 9Router model IDs for human-readable naming. */
|
|
62
|
-
export const KNOWN_PROVIDER_PREFIXES: Record<string, string> = {
|
|
63
|
-
"cc/": "Claude Code",
|
|
64
|
-
"cx/": "Codex",
|
|
65
|
-
"gh/": "GitHub Copilot",
|
|
66
|
-
"kr/": "Kiro AI",
|
|
67
|
-
"oc/": "OpenCode Free",
|
|
68
|
-
"vertex/": "Vertex AI",
|
|
69
|
-
"vertex-partner/": "Vertex Partner",
|
|
70
|
-
"glm/": "GLM",
|
|
71
|
-
"minimax/": "MiniMax",
|
|
72
|
-
"kimi/": "Kimi",
|
|
73
|
-
"cu/": "Cursor",
|
|
74
|
-
"gc/": "Gemini CLI",
|
|
75
|
-
"if/": "iFlow",
|
|
76
|
-
"qw/": "Qwen",
|
|
77
|
-
"openrouter/": "OpenRouter",
|
|
78
|
-
"deepseek/": "DeepSeek",
|
|
79
|
-
"groq/": "Groq",
|
|
80
|
-
};
|
package/src/plugin.ts
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import type { Plugin, PluginInput } from "@opencode-ai/plugin";
|
|
2
|
-
import type { Auth } from "@opencode-ai/sdk";
|
|
3
|
-
import {
|
|
4
|
-
PLUGIN_NAME,
|
|
5
|
-
PROVIDER_DISPLAY_NAME,
|
|
6
|
-
DEFAULT_BASE_URL,
|
|
7
|
-
DEFAULT_API_PATH,
|
|
8
|
-
FALLBACK_MODELS,
|
|
9
|
-
KNOWN_PROVIDER_PREFIXES,
|
|
10
|
-
} from "./constants";
|
|
11
|
-
|
|
12
|
-
function formatModelName(modelId: string): string {
|
|
13
|
-
for (const [prefix, provider] of Object.entries(KNOWN_PROVIDER_PREFIXES)) {
|
|
14
|
-
if (modelId.startsWith(prefix)) {
|
|
15
|
-
return `${modelId.slice(prefix.length)} (${provider})`;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
return modelId;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
async function discoverModels(
|
|
22
|
-
baseURL: string,
|
|
23
|
-
): Promise<Record<string, { name: string }> | null> {
|
|
24
|
-
const apiURL = `${baseURL}${DEFAULT_API_PATH}`;
|
|
25
|
-
try {
|
|
26
|
-
const response = await fetch(`${apiURL}/models`, {
|
|
27
|
-
signal: AbortSignal.timeout(3000),
|
|
28
|
-
});
|
|
29
|
-
if (!response.ok) return null;
|
|
30
|
-
|
|
31
|
-
const data = (await response.json()) as {
|
|
32
|
-
data?: Array<{ id: string }>;
|
|
33
|
-
};
|
|
34
|
-
if (!data.data || !Array.isArray(data.data) || data.data.length === 0) {
|
|
35
|
-
return null;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const models: Record<string, { name: string }> = {};
|
|
39
|
-
for (const model of data.data) {
|
|
40
|
-
models[model.id] = { name: formatModelName(model.id) };
|
|
41
|
-
}
|
|
42
|
-
return models;
|
|
43
|
-
} catch {
|
|
44
|
-
return null;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const plugin: Plugin = async ({ client }: PluginInput, options?: { baseURL?: string }) => {
|
|
49
|
-
const configuredBaseURL = options?.baseURL ?? DEFAULT_BASE_URL;
|
|
50
|
-
|
|
51
|
-
const discovered = await discoverModels(configuredBaseURL);
|
|
52
|
-
const models = discovered ?? FALLBACK_MODELS;
|
|
53
|
-
|
|
54
|
-
if (!discovered && client?.app?.log) {
|
|
55
|
-
await client.app.log({
|
|
56
|
-
body: {
|
|
57
|
-
service: "9router-provider",
|
|
58
|
-
level: "warn",
|
|
59
|
-
message: `9Router not reachable at ${configuredBaseURL}. Using well-known model list. Start 9Router and restart opencode to auto-discover models.`,
|
|
60
|
-
},
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return {
|
|
65
|
-
// provider hook: auto-registers 9Router with models — NO manual opencode.json config needed
|
|
66
|
-
provider: {
|
|
67
|
-
[PLUGIN_NAME]: {
|
|
68
|
-
npm: "@ai-sdk/openai-compatible",
|
|
69
|
-
name: PROVIDER_DISPLAY_NAME,
|
|
70
|
-
options: {
|
|
71
|
-
baseURL: `${configuredBaseURL}${DEFAULT_API_PATH}`,
|
|
72
|
-
},
|
|
73
|
-
models,
|
|
74
|
-
},
|
|
75
|
-
},
|
|
76
|
-
|
|
77
|
-
// auth hook: enables /connect flow with configurable baseURL + API key
|
|
78
|
-
auth: {
|
|
79
|
-
provider: PLUGIN_NAME,
|
|
80
|
-
async loader(getAuth: () => Promise<Auth>, _provider: unknown) {
|
|
81
|
-
const auth = await getAuth();
|
|
82
|
-
// If user set custom baseURL via /connect, override the provider default
|
|
83
|
-
if (auth && typeof auth === "object" && "baseURL" in auth) {
|
|
84
|
-
return { baseURL: `${String(auth.baseURL)}${DEFAULT_API_PATH}` };
|
|
85
|
-
}
|
|
86
|
-
return {};
|
|
87
|
-
},
|
|
88
|
-
methods: [
|
|
89
|
-
{
|
|
90
|
-
label: `Connect to ${PROVIDER_DISPLAY_NAME}`,
|
|
91
|
-
type: "api",
|
|
92
|
-
prompts: [
|
|
93
|
-
{
|
|
94
|
-
type: "text",
|
|
95
|
-
message: `${PROVIDER_DISPLAY_NAME} Base URL (default: ${DEFAULT_BASE_URL})`,
|
|
96
|
-
key: "baseURL",
|
|
97
|
-
default: DEFAULT_BASE_URL,
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
type: "text",
|
|
101
|
-
message: `${PROVIDER_DISPLAY_NAME} API Key (from Dashboard → Endpoints)`,
|
|
102
|
-
key: "apiKey",
|
|
103
|
-
},
|
|
104
|
-
],
|
|
105
|
-
},
|
|
106
|
-
],
|
|
107
|
-
},
|
|
108
|
-
};
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
export default plugin;
|