diff --git a/.github/labeler.yml b/.github/labeler.yml index 91c202b7ed6..08ede2a1ca5 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -238,15 +238,79 @@ - changed-files: - any-glob-to-any-file: - "extensions/acpx/**" +"extensions: byteplus": + - changed-files: + - any-glob-to-any-file: + - "extensions/byteplus/**" +"extensions: cloudflare-ai-gateway": + - changed-files: + - any-glob-to-any-file: + - "extensions/cloudflare-ai-gateway/**" "extensions: minimax-portal-auth": - changed-files: - any-glob-to-any-file: - "extensions/minimax-portal-auth/**" +"extensions: huggingface": + - changed-files: + - any-glob-to-any-file: + - "extensions/huggingface/**" +"extensions: kilocode": + - changed-files: + - any-glob-to-any-file: + - "extensions/kilocode/**" +"extensions: kimi-coding": + - changed-files: + - any-glob-to-any-file: + - "extensions/kimi-coding/**" +"extensions: minimax": + - changed-files: + - any-glob-to-any-file: + - "extensions/minimax/**" +"extensions: modelstudio": + - changed-files: + - any-glob-to-any-file: + - "extensions/modelstudio/**" +"extensions: moonshot": + - changed-files: + - any-glob-to-any-file: + - "extensions/moonshot/**" +"extensions: nvidia": + - changed-files: + - any-glob-to-any-file: + - "extensions/nvidia/**" "extensions: phone-control": - changed-files: - any-glob-to-any-file: - "extensions/phone-control/**" +"extensions: qianfan": + - changed-files: + - any-glob-to-any-file: + - "extensions/qianfan/**" +"extensions: synthetic": + - changed-files: + - any-glob-to-any-file: + - "extensions/synthetic/**" "extensions: talk-voice": - changed-files: - any-glob-to-any-file: - "extensions/talk-voice/**" +"extensions: together": + - changed-files: + - any-glob-to-any-file: + - "extensions/together/**" +"extensions: venice": + - changed-files: + - any-glob-to-any-file: + - "extensions/venice/**" +"extensions: vercel-ai-gateway": + - changed-files: + - any-glob-to-any-file: + - "extensions/vercel-ai-gateway/**" +"extensions: volcengine": + - changed-files: + - any-glob-to-any-file: + - "extensions/volcengine/**" +"extensions: xiaomi": + - changed-files: + - any-glob-to-any-file: + - "extensions/xiaomi/**" diff --git a/extensions/byteplus/index.ts b/extensions/byteplus/index.ts new file mode 100644 index 00000000000..35050f2c789 --- /dev/null +++ b/extensions/byteplus/index.ts @@ -0,0 +1,40 @@ +import { emptyPluginConfigSchema, type OpenClawPluginApi } from "openclaw/plugin-sdk/core"; +import { + buildBytePlusCodingProvider, + buildBytePlusProvider, +} from "../../src/agents/models-config.providers.static.js"; + +const PROVIDER_ID = "byteplus"; + +const byteplusPlugin = { + id: PROVIDER_ID, + name: "BytePlus Provider", + description: "Bundled BytePlus provider plugin", + configSchema: emptyPluginConfigSchema(), + register(api: OpenClawPluginApi) { + api.registerProvider({ + id: PROVIDER_ID, + label: "BytePlus", + docsPath: "/concepts/model-providers#byteplus-international", + envVars: ["BYTEPLUS_API_KEY"], + auth: [], + catalog: { + order: "paired", + run: async (ctx) => { + const apiKey = ctx.resolveProviderApiKey(PROVIDER_ID).apiKey; + if (!apiKey) { + return null; + } + return { + providers: { + byteplus: { ...buildBytePlusProvider(), apiKey }, + "byteplus-plan": { ...buildBytePlusCodingProvider(), apiKey }, + }, + }; + }, + }, + }); + }, +}; + +export default byteplusPlugin; diff --git a/extensions/byteplus/openclaw.plugin.json b/extensions/byteplus/openclaw.plugin.json new file mode 100644 index 00000000000..8885280bf32 --- /dev/null +++ b/extensions/byteplus/openclaw.plugin.json @@ -0,0 +1,9 @@ +{ + "id": "byteplus", + "providers": ["byteplus", "byteplus-plan"], + "configSchema": { + "type": "object", + "additionalProperties": false, + "properties": {} + } +} diff --git a/extensions/byteplus/package.json b/extensions/byteplus/package.json new file mode 100644 index 00000000000..8eda5930c69 --- /dev/null +++ b/extensions/byteplus/package.json @@ -0,0 +1,12 @@ +{ + "name": "@openclaw/byteplus-provider", + "version": "2026.3.14", + "private": true, + "description": "OpenClaw BytePlus provider plugin", + "type": "module", + "openclaw": { + "extensions": [ + "./index.ts" + ] + } +} diff --git a/extensions/cloudflare-ai-gateway/index.ts b/extensions/cloudflare-ai-gateway/index.ts new file mode 100644 index 00000000000..173c9eaf48b --- /dev/null +++ b/extensions/cloudflare-ai-gateway/index.ts @@ -0,0 +1,82 @@ +import { emptyPluginConfigSchema, type OpenClawPluginApi } from "openclaw/plugin-sdk/core"; +import { ensureAuthProfileStore, listProfilesForProvider } from "../../src/agents/auth-profiles.js"; +import { + buildCloudflareAiGatewayModelDefinition, + resolveCloudflareAiGatewayBaseUrl, +} from "../../src/agents/cloudflare-ai-gateway.js"; +import { resolveNonEnvSecretRefApiKeyMarker } from "../../src/agents/model-auth-markers.js"; +import { coerceSecretRef } from "../../src/config/types.secrets.js"; + +const PROVIDER_ID = "cloudflare-ai-gateway"; +const PROVIDER_ENV_VAR = "CLOUDFLARE_AI_GATEWAY_API_KEY"; + +function resolveApiKeyFromCredential( + cred: ReturnType["profiles"][string] | undefined, +): string | undefined { + if (!cred || cred.type !== "api_key") { + return undefined; + } + + const keyRef = coerceSecretRef(cred.keyRef); + if (keyRef && keyRef.id.trim()) { + return keyRef.source === "env" + ? keyRef.id.trim() + : resolveNonEnvSecretRefApiKeyMarker(keyRef.source); + } + return cred.key?.trim() || undefined; +} + +const cloudflareAiGatewayPlugin = { + id: PROVIDER_ID, + name: "Cloudflare AI Gateway Provider", + description: "Bundled Cloudflare AI Gateway provider plugin", + configSchema: emptyPluginConfigSchema(), + register(api: OpenClawPluginApi) { + api.registerProvider({ + id: PROVIDER_ID, + label: "Cloudflare AI Gateway", + docsPath: "/providers/cloudflare-ai-gateway", + envVars: ["CLOUDFLARE_AI_GATEWAY_API_KEY"], + auth: [], + catalog: { + order: "late", + run: async (ctx) => { + const authStore = ensureAuthProfileStore(ctx.agentDir, { + allowKeychainPrompt: false, + }); + const envManagedApiKey = ctx.env[PROVIDER_ENV_VAR]?.trim() ? PROVIDER_ENV_VAR : undefined; + for (const profileId of listProfilesForProvider(authStore, PROVIDER_ID)) { + const cred = authStore.profiles[profileId]; + if (!cred || cred.type !== "api_key") { + continue; + } + const apiKey = envManagedApiKey ?? resolveApiKeyFromCredential(cred); + if (!apiKey) { + continue; + } + const accountId = cred.metadata?.accountId?.trim(); + const gatewayId = cred.metadata?.gatewayId?.trim(); + if (!accountId || !gatewayId) { + continue; + } + const baseUrl = resolveCloudflareAiGatewayBaseUrl({ accountId, gatewayId }); + if (!baseUrl) { + continue; + } + return { + provider: { + baseUrl, + api: "anthropic-messages", + apiKey, + models: [buildCloudflareAiGatewayModelDefinition()], + }, + }; + } + return null; + }, + }, + }); + }, +}; + +export default cloudflareAiGatewayPlugin; diff --git a/extensions/cloudflare-ai-gateway/openclaw.plugin.json b/extensions/cloudflare-ai-gateway/openclaw.plugin.json new file mode 100644 index 00000000000..fc7a41f77bb --- /dev/null +++ b/extensions/cloudflare-ai-gateway/openclaw.plugin.json @@ -0,0 +1,9 @@ +{ + "id": "cloudflare-ai-gateway", + "providers": ["cloudflare-ai-gateway"], + "configSchema": { + "type": "object", + "additionalProperties": false, + "properties": {} + } +} diff --git a/extensions/cloudflare-ai-gateway/package.json b/extensions/cloudflare-ai-gateway/package.json new file mode 100644 index 00000000000..288bc1c7203 --- /dev/null +++ b/extensions/cloudflare-ai-gateway/package.json @@ -0,0 +1,12 @@ +{ + "name": "@openclaw/cloudflare-ai-gateway-provider", + "version": "2026.3.14", + "private": true, + "description": "OpenClaw Cloudflare AI Gateway provider plugin", + "type": "module", + "openclaw": { + "extensions": [ + "./index.ts" + ] + } +} diff --git a/extensions/huggingface/index.ts b/extensions/huggingface/index.ts new file mode 100644 index 00000000000..c6407954811 --- /dev/null +++ b/extensions/huggingface/index.ts @@ -0,0 +1,37 @@ +import { emptyPluginConfigSchema, type OpenClawPluginApi } from "openclaw/plugin-sdk/core"; +import { buildHuggingfaceProvider } from "../../src/agents/models-config.providers.discovery.js"; + +const PROVIDER_ID = "huggingface"; + +const huggingfacePlugin = { + id: PROVIDER_ID, + name: "Hugging Face Provider", + description: "Bundled Hugging Face provider plugin", + configSchema: emptyPluginConfigSchema(), + register(api: OpenClawPluginApi) { + api.registerProvider({ + id: PROVIDER_ID, + label: "Hugging Face", + docsPath: "/providers/huggingface", + envVars: ["HUGGINGFACE_HUB_TOKEN", "HF_TOKEN"], + auth: [], + catalog: { + order: "simple", + run: async (ctx) => { + const { apiKey, discoveryApiKey } = ctx.resolveProviderApiKey(PROVIDER_ID); + if (!apiKey) { + return null; + } + return { + provider: { + ...(await buildHuggingfaceProvider(discoveryApiKey)), + apiKey, + }, + }; + }, + }, + }); + }, +}; + +export default huggingfacePlugin; diff --git a/extensions/huggingface/openclaw.plugin.json b/extensions/huggingface/openclaw.plugin.json new file mode 100644 index 00000000000..4b68bcedb26 --- /dev/null +++ b/extensions/huggingface/openclaw.plugin.json @@ -0,0 +1,9 @@ +{ + "id": "huggingface", + "providers": ["huggingface"], + "configSchema": { + "type": "object", + "additionalProperties": false, + "properties": {} + } +} diff --git a/extensions/huggingface/package.json b/extensions/huggingface/package.json new file mode 100644 index 00000000000..7e58582f4f9 --- /dev/null +++ b/extensions/huggingface/package.json @@ -0,0 +1,12 @@ +{ + "name": "@openclaw/huggingface-provider", + "version": "2026.3.14", + "private": true, + "description": "OpenClaw Hugging Face provider plugin", + "type": "module", + "openclaw": { + "extensions": [ + "./index.ts" + ] + } +} diff --git a/extensions/kilocode/index.ts b/extensions/kilocode/index.ts new file mode 100644 index 00000000000..10fc30f67d4 --- /dev/null +++ b/extensions/kilocode/index.ts @@ -0,0 +1,53 @@ +import { emptyPluginConfigSchema, type OpenClawPluginApi } from "openclaw/plugin-sdk/core"; +import { buildKilocodeProviderWithDiscovery } from "../../src/agents/models-config.providers.discovery.js"; +import { + createKilocodeWrapper, + isProxyReasoningUnsupported, +} from "../../src/agents/pi-embedded-runner/proxy-stream-wrappers.js"; + +const PROVIDER_ID = "kilocode"; + +const kilocodePlugin = { + id: PROVIDER_ID, + name: "Kilo Gateway Provider", + description: "Bundled Kilo Gateway provider plugin", + configSchema: emptyPluginConfigSchema(), + register(api: OpenClawPluginApi) { + api.registerProvider({ + id: PROVIDER_ID, + label: "Kilo Gateway", + docsPath: "/providers/kilocode", + envVars: ["KILOCODE_API_KEY"], + auth: [], + catalog: { + order: "simple", + run: async (ctx) => { + const apiKey = ctx.resolveProviderApiKey(PROVIDER_ID).apiKey; + if (!apiKey) { + return null; + } + return { + provider: { + ...(await buildKilocodeProviderWithDiscovery()), + apiKey, + }, + }; + }, + }, + capabilities: { + geminiThoughtSignatureSanitization: true, + geminiThoughtSignatureModelHints: ["gemini"], + }, + wrapStreamFn: (ctx) => { + const thinkingLevel = + ctx.modelId === "kilo/auto" || isProxyReasoningUnsupported(ctx.modelId) + ? undefined + : ctx.thinkingLevel; + return createKilocodeWrapper(ctx.streamFn, thinkingLevel); + }, + isCacheTtlEligible: (ctx) => ctx.modelId.startsWith("anthropic/"), + }); + }, +}; + +export default kilocodePlugin; diff --git a/extensions/kilocode/openclaw.plugin.json b/extensions/kilocode/openclaw.plugin.json new file mode 100644 index 00000000000..ec078c33ab7 --- /dev/null +++ b/extensions/kilocode/openclaw.plugin.json @@ -0,0 +1,9 @@ +{ + "id": "kilocode", + "providers": ["kilocode"], + "configSchema": { + "type": "object", + "additionalProperties": false, + "properties": {} + } +} diff --git a/extensions/kilocode/package.json b/extensions/kilocode/package.json new file mode 100644 index 00000000000..9ef4b7fe0c5 --- /dev/null +++ b/extensions/kilocode/package.json @@ -0,0 +1,12 @@ +{ + "name": "@openclaw/kilocode-provider", + "version": "2026.3.14", + "private": true, + "description": "OpenClaw Kilo Gateway provider plugin", + "type": "module", + "openclaw": { + "extensions": [ + "./index.ts" + ] + } +} diff --git a/extensions/kimi-coding/index.ts b/extensions/kimi-coding/index.ts new file mode 100644 index 00000000000..d6e6e1d74a7 --- /dev/null +++ b/extensions/kimi-coding/index.ts @@ -0,0 +1,58 @@ +import { emptyPluginConfigSchema, type OpenClawPluginApi } from "openclaw/plugin-sdk/core"; +import { buildKimiCodingProvider } from "../../src/agents/models-config.providers.static.js"; +import { isRecord } from "../../src/utils.js"; + +const PROVIDER_ID = "kimi-coding"; + +const kimiCodingPlugin = { + id: PROVIDER_ID, + name: "Kimi Coding Provider", + description: "Bundled Kimi Coding provider plugin", + configSchema: emptyPluginConfigSchema(), + register(api: OpenClawPluginApi) { + api.registerProvider({ + id: PROVIDER_ID, + label: "Kimi Coding", + aliases: ["kimi-code"], + docsPath: "/providers/moonshot", + envVars: ["KIMI_API_KEY", "KIMICODE_API_KEY"], + auth: [], + catalog: { + order: "simple", + run: async (ctx) => { + const apiKey = ctx.resolveProviderApiKey(PROVIDER_ID).apiKey; + if (!apiKey) { + return null; + } + const explicitProvider = ctx.config.models?.providers?.[PROVIDER_ID]; + const builtInProvider = buildKimiCodingProvider(); + const explicitBaseUrl = + typeof explicitProvider?.baseUrl === "string" ? explicitProvider.baseUrl.trim() : ""; + const explicitHeaders = isRecord(explicitProvider?.headers) + ? explicitProvider.headers + : undefined; + return { + provider: { + ...builtInProvider, + ...(explicitBaseUrl ? { baseUrl: explicitBaseUrl } : {}), + ...(explicitHeaders + ? { + headers: { + ...builtInProvider.headers, + ...explicitHeaders, + }, + } + : {}), + apiKey, + }, + }; + }, + }, + capabilities: { + preserveAnthropicThinkingSignatures: false, + }, + }); + }, +}; + +export default kimiCodingPlugin; diff --git a/extensions/kimi-coding/openclaw.plugin.json b/extensions/kimi-coding/openclaw.plugin.json new file mode 100644 index 00000000000..8874fb6501b --- /dev/null +++ b/extensions/kimi-coding/openclaw.plugin.json @@ -0,0 +1,9 @@ +{ + "id": "kimi-coding", + "providers": ["kimi-coding"], + "configSchema": { + "type": "object", + "additionalProperties": false, + "properties": {} + } +} diff --git a/extensions/kimi-coding/package.json b/extensions/kimi-coding/package.json new file mode 100644 index 00000000000..738dd1abd1f --- /dev/null +++ b/extensions/kimi-coding/package.json @@ -0,0 +1,12 @@ +{ + "name": "@openclaw/kimi-coding-provider", + "version": "2026.3.14", + "private": true, + "description": "OpenClaw Kimi Coding provider plugin", + "type": "module", + "openclaw": { + "extensions": [ + "./index.ts" + ] + } +} diff --git a/extensions/minimax/index.ts b/extensions/minimax/index.ts new file mode 100644 index 00000000000..4076362404f --- /dev/null +++ b/extensions/minimax/index.ts @@ -0,0 +1,37 @@ +import { emptyPluginConfigSchema, type OpenClawPluginApi } from "openclaw/plugin-sdk/core"; +import { buildMinimaxProvider } from "../../src/agents/models-config.providers.static.js"; + +const PROVIDER_ID = "minimax"; + +const minimaxPlugin = { + id: PROVIDER_ID, + name: "MiniMax Provider", + description: "Bundled MiniMax provider plugin", + configSchema: emptyPluginConfigSchema(), + register(api: OpenClawPluginApi) { + api.registerProvider({ + id: PROVIDER_ID, + label: "MiniMax", + docsPath: "/providers/minimax", + envVars: ["MINIMAX_API_KEY"], + auth: [], + catalog: { + order: "simple", + run: async (ctx) => { + const apiKey = ctx.resolveProviderApiKey(PROVIDER_ID).apiKey; + if (!apiKey) { + return null; + } + return { + provider: { + ...buildMinimaxProvider(), + apiKey, + }, + }; + }, + }, + }); + }, +}; + +export default minimaxPlugin; diff --git a/extensions/minimax/openclaw.plugin.json b/extensions/minimax/openclaw.plugin.json new file mode 100644 index 00000000000..01f3e5efbea --- /dev/null +++ b/extensions/minimax/openclaw.plugin.json @@ -0,0 +1,9 @@ +{ + "id": "minimax", + "providers": ["minimax"], + "configSchema": { + "type": "object", + "additionalProperties": false, + "properties": {} + } +} diff --git a/extensions/minimax/package.json b/extensions/minimax/package.json new file mode 100644 index 00000000000..6650cf1e456 --- /dev/null +++ b/extensions/minimax/package.json @@ -0,0 +1,12 @@ +{ + "name": "@openclaw/minimax-provider", + "version": "2026.3.14", + "private": true, + "description": "OpenClaw MiniMax provider plugin", + "type": "module", + "openclaw": { + "extensions": [ + "./index.ts" + ] + } +} diff --git a/extensions/modelstudio/index.ts b/extensions/modelstudio/index.ts new file mode 100644 index 00000000000..487f14498b1 --- /dev/null +++ b/extensions/modelstudio/index.ts @@ -0,0 +1,41 @@ +import { emptyPluginConfigSchema, type OpenClawPluginApi } from "openclaw/plugin-sdk/core"; +import { buildModelStudioProvider } from "../../src/agents/models-config.providers.static.js"; + +const PROVIDER_ID = "modelstudio"; + +const modelStudioPlugin = { + id: PROVIDER_ID, + name: "Model Studio Provider", + description: "Bundled Model Studio provider plugin", + configSchema: emptyPluginConfigSchema(), + register(api: OpenClawPluginApi) { + api.registerProvider({ + id: PROVIDER_ID, + label: "Model Studio", + docsPath: "/providers/models", + envVars: ["MODELSTUDIO_API_KEY"], + auth: [], + catalog: { + order: "simple", + run: async (ctx) => { + const apiKey = ctx.resolveProviderApiKey(PROVIDER_ID).apiKey; + if (!apiKey) { + return null; + } + const explicitProvider = ctx.config.models?.providers?.[PROVIDER_ID]; + const explicitBaseUrl = + typeof explicitProvider?.baseUrl === "string" ? explicitProvider.baseUrl.trim() : ""; + return { + provider: { + ...buildModelStudioProvider(), + ...(explicitBaseUrl ? { baseUrl: explicitBaseUrl } : {}), + apiKey, + }, + }; + }, + }, + }); + }, +}; + +export default modelStudioPlugin; diff --git a/extensions/modelstudio/openclaw.plugin.json b/extensions/modelstudio/openclaw.plugin.json new file mode 100644 index 00000000000..1a8d9e71c75 --- /dev/null +++ b/extensions/modelstudio/openclaw.plugin.json @@ -0,0 +1,9 @@ +{ + "id": "modelstudio", + "providers": ["modelstudio"], + "configSchema": { + "type": "object", + "additionalProperties": false, + "properties": {} + } +} diff --git a/extensions/modelstudio/package.json b/extensions/modelstudio/package.json new file mode 100644 index 00000000000..631c87d53ca --- /dev/null +++ b/extensions/modelstudio/package.json @@ -0,0 +1,12 @@ +{ + "name": "@openclaw/modelstudio-provider", + "version": "2026.3.14", + "private": true, + "description": "OpenClaw Model Studio provider plugin", + "type": "module", + "openclaw": { + "extensions": [ + "./index.ts" + ] + } +} diff --git a/extensions/moonshot/index.ts b/extensions/moonshot/index.ts new file mode 100644 index 00000000000..59176e42c15 --- /dev/null +++ b/extensions/moonshot/index.ts @@ -0,0 +1,52 @@ +import { emptyPluginConfigSchema, type OpenClawPluginApi } from "openclaw/plugin-sdk/core"; +import { buildMoonshotProvider } from "../../src/agents/models-config.providers.static.js"; +import { + createMoonshotThinkingWrapper, + resolveMoonshotThinkingType, +} from "../../src/agents/pi-embedded-runner/moonshot-stream-wrappers.js"; + +const PROVIDER_ID = "moonshot"; + +const moonshotPlugin = { + id: PROVIDER_ID, + name: "Moonshot Provider", + description: "Bundled Moonshot provider plugin", + configSchema: emptyPluginConfigSchema(), + register(api: OpenClawPluginApi) { + api.registerProvider({ + id: PROVIDER_ID, + label: "Moonshot", + docsPath: "/providers/moonshot", + envVars: ["MOONSHOT_API_KEY"], + auth: [], + catalog: { + order: "simple", + run: async (ctx) => { + const apiKey = ctx.resolveProviderApiKey(PROVIDER_ID).apiKey; + if (!apiKey) { + return null; + } + const explicitProvider = ctx.config.models?.providers?.[PROVIDER_ID]; + const explicitBaseUrl = + typeof explicitProvider?.baseUrl === "string" ? explicitProvider.baseUrl.trim() : ""; + return { + provider: { + ...buildMoonshotProvider(), + ...(explicitBaseUrl ? { baseUrl: explicitBaseUrl } : {}), + apiKey, + }, + }; + }, + }, + wrapStreamFn: (ctx) => { + const thinkingType = resolveMoonshotThinkingType({ + configuredThinking: ctx.extraParams?.thinking, + thinkingLevel: ctx.thinkingLevel, + }); + return createMoonshotThinkingWrapper(ctx.streamFn, thinkingType); + }, + }); + }, +}; + +export default moonshotPlugin; diff --git a/extensions/moonshot/openclaw.plugin.json b/extensions/moonshot/openclaw.plugin.json new file mode 100644 index 00000000000..e02cb3d21c5 --- /dev/null +++ b/extensions/moonshot/openclaw.plugin.json @@ -0,0 +1,9 @@ +{ + "id": "moonshot", + "providers": ["moonshot"], + "configSchema": { + "type": "object", + "additionalProperties": false, + "properties": {} + } +} diff --git a/extensions/moonshot/package.json b/extensions/moonshot/package.json new file mode 100644 index 00000000000..a9dab300c74 --- /dev/null +++ b/extensions/moonshot/package.json @@ -0,0 +1,12 @@ +{ + "name": "@openclaw/moonshot-provider", + "version": "2026.3.14", + "private": true, + "description": "OpenClaw Moonshot provider plugin", + "type": "module", + "openclaw": { + "extensions": [ + "./index.ts" + ] + } +} diff --git a/extensions/nvidia/index.ts b/extensions/nvidia/index.ts new file mode 100644 index 00000000000..afa83c4dff4 --- /dev/null +++ b/extensions/nvidia/index.ts @@ -0,0 +1,37 @@ +import { emptyPluginConfigSchema, type OpenClawPluginApi } from "openclaw/plugin-sdk/core"; +import { buildNvidiaProvider } from "../../src/agents/models-config.providers.static.js"; + +const PROVIDER_ID = "nvidia"; + +const nvidiaPlugin = { + id: PROVIDER_ID, + name: "NVIDIA Provider", + description: "Bundled NVIDIA provider plugin", + configSchema: emptyPluginConfigSchema(), + register(api: OpenClawPluginApi) { + api.registerProvider({ + id: PROVIDER_ID, + label: "NVIDIA", + docsPath: "/providers/nvidia", + envVars: ["NVIDIA_API_KEY"], + auth: [], + catalog: { + order: "simple", + run: async (ctx) => { + const apiKey = ctx.resolveProviderApiKey(PROVIDER_ID).apiKey; + if (!apiKey) { + return null; + } + return { + provider: { + ...buildNvidiaProvider(), + apiKey, + }, + }; + }, + }, + }); + }, +}; + +export default nvidiaPlugin; diff --git a/extensions/nvidia/openclaw.plugin.json b/extensions/nvidia/openclaw.plugin.json new file mode 100644 index 00000000000..268bfa2dafd --- /dev/null +++ b/extensions/nvidia/openclaw.plugin.json @@ -0,0 +1,9 @@ +{ + "id": "nvidia", + "providers": ["nvidia"], + "configSchema": { + "type": "object", + "additionalProperties": false, + "properties": {} + } +} diff --git a/extensions/nvidia/package.json b/extensions/nvidia/package.json new file mode 100644 index 00000000000..2caee766789 --- /dev/null +++ b/extensions/nvidia/package.json @@ -0,0 +1,12 @@ +{ + "name": "@openclaw/nvidia-provider", + "version": "2026.3.14", + "private": true, + "description": "OpenClaw NVIDIA provider plugin", + "type": "module", + "openclaw": { + "extensions": [ + "./index.ts" + ] + } +} diff --git a/extensions/qianfan/index.ts b/extensions/qianfan/index.ts new file mode 100644 index 00000000000..1da228d3772 --- /dev/null +++ b/extensions/qianfan/index.ts @@ -0,0 +1,37 @@ +import { emptyPluginConfigSchema, type OpenClawPluginApi } from "openclaw/plugin-sdk/core"; +import { buildQianfanProvider } from "../../src/agents/models-config.providers.static.js"; + +const PROVIDER_ID = "qianfan"; + +const qianfanPlugin = { + id: PROVIDER_ID, + name: "Qianfan Provider", + description: "Bundled Qianfan provider plugin", + configSchema: emptyPluginConfigSchema(), + register(api: OpenClawPluginApi) { + api.registerProvider({ + id: PROVIDER_ID, + label: "Qianfan", + docsPath: "/providers/qianfan", + envVars: ["QIANFAN_API_KEY"], + auth: [], + catalog: { + order: "simple", + run: async (ctx) => { + const apiKey = ctx.resolveProviderApiKey(PROVIDER_ID).apiKey; + if (!apiKey) { + return null; + } + return { + provider: { + ...buildQianfanProvider(), + apiKey, + }, + }; + }, + }, + }); + }, +}; + +export default qianfanPlugin; diff --git a/extensions/qianfan/openclaw.plugin.json b/extensions/qianfan/openclaw.plugin.json new file mode 100644 index 00000000000..9bd75d78c4b --- /dev/null +++ b/extensions/qianfan/openclaw.plugin.json @@ -0,0 +1,9 @@ +{ + "id": "qianfan", + "providers": ["qianfan"], + "configSchema": { + "type": "object", + "additionalProperties": false, + "properties": {} + } +} diff --git a/extensions/qianfan/package.json b/extensions/qianfan/package.json new file mode 100644 index 00000000000..57b2177e6d8 --- /dev/null +++ b/extensions/qianfan/package.json @@ -0,0 +1,12 @@ +{ + "name": "@openclaw/qianfan-provider", + "version": "2026.3.14", + "private": true, + "description": "OpenClaw Qianfan provider plugin", + "type": "module", + "openclaw": { + "extensions": [ + "./index.ts" + ] + } +} diff --git a/extensions/synthetic/index.ts b/extensions/synthetic/index.ts new file mode 100644 index 00000000000..c22dcc11f8b --- /dev/null +++ b/extensions/synthetic/index.ts @@ -0,0 +1,37 @@ +import { emptyPluginConfigSchema, type OpenClawPluginApi } from "openclaw/plugin-sdk/core"; +import { buildSyntheticProvider } from "../../src/agents/models-config.providers.static.js"; + +const PROVIDER_ID = "synthetic"; + +const syntheticPlugin = { + id: PROVIDER_ID, + name: "Synthetic Provider", + description: "Bundled Synthetic provider plugin", + configSchema: emptyPluginConfigSchema(), + register(api: OpenClawPluginApi) { + api.registerProvider({ + id: PROVIDER_ID, + label: "Synthetic", + docsPath: "/providers/synthetic", + envVars: ["SYNTHETIC_API_KEY"], + auth: [], + catalog: { + order: "simple", + run: async (ctx) => { + const apiKey = ctx.resolveProviderApiKey(PROVIDER_ID).apiKey; + if (!apiKey) { + return null; + } + return { + provider: { + ...buildSyntheticProvider(), + apiKey, + }, + }; + }, + }, + }); + }, +}; + +export default syntheticPlugin; diff --git a/extensions/synthetic/openclaw.plugin.json b/extensions/synthetic/openclaw.plugin.json new file mode 100644 index 00000000000..fab1326ca34 --- /dev/null +++ b/extensions/synthetic/openclaw.plugin.json @@ -0,0 +1,9 @@ +{ + "id": "synthetic", + "providers": ["synthetic"], + "configSchema": { + "type": "object", + "additionalProperties": false, + "properties": {} + } +} diff --git a/extensions/synthetic/package.json b/extensions/synthetic/package.json new file mode 100644 index 00000000000..ec471f1eadf --- /dev/null +++ b/extensions/synthetic/package.json @@ -0,0 +1,12 @@ +{ + "name": "@openclaw/synthetic-provider", + "version": "2026.3.14", + "private": true, + "description": "OpenClaw Synthetic provider plugin", + "type": "module", + "openclaw": { + "extensions": [ + "./index.ts" + ] + } +} diff --git a/extensions/together/index.ts b/extensions/together/index.ts new file mode 100644 index 00000000000..5b1f6ced62f --- /dev/null +++ b/extensions/together/index.ts @@ -0,0 +1,37 @@ +import { emptyPluginConfigSchema, type OpenClawPluginApi } from "openclaw/plugin-sdk/core"; +import { buildTogetherProvider } from "../../src/agents/models-config.providers.static.js"; + +const PROVIDER_ID = "together"; + +const togetherPlugin = { + id: PROVIDER_ID, + name: "Together Provider", + description: "Bundled Together provider plugin", + configSchema: emptyPluginConfigSchema(), + register(api: OpenClawPluginApi) { + api.registerProvider({ + id: PROVIDER_ID, + label: "Together", + docsPath: "/providers/together", + envVars: ["TOGETHER_API_KEY"], + auth: [], + catalog: { + order: "simple", + run: async (ctx) => { + const apiKey = ctx.resolveProviderApiKey(PROVIDER_ID).apiKey; + if (!apiKey) { + return null; + } + return { + provider: { + ...buildTogetherProvider(), + apiKey, + }, + }; + }, + }, + }); + }, +}; + +export default togetherPlugin; diff --git a/extensions/together/openclaw.plugin.json b/extensions/together/openclaw.plugin.json new file mode 100644 index 00000000000..2a868251f34 --- /dev/null +++ b/extensions/together/openclaw.plugin.json @@ -0,0 +1,9 @@ +{ + "id": "together", + "providers": ["together"], + "configSchema": { + "type": "object", + "additionalProperties": false, + "properties": {} + } +} diff --git a/extensions/together/package.json b/extensions/together/package.json new file mode 100644 index 00000000000..982a0a03734 --- /dev/null +++ b/extensions/together/package.json @@ -0,0 +1,12 @@ +{ + "name": "@openclaw/together-provider", + "version": "2026.3.14", + "private": true, + "description": "OpenClaw Together provider plugin", + "type": "module", + "openclaw": { + "extensions": [ + "./index.ts" + ] + } +} diff --git a/extensions/venice/index.ts b/extensions/venice/index.ts new file mode 100644 index 00000000000..75cd6adbaf1 --- /dev/null +++ b/extensions/venice/index.ts @@ -0,0 +1,37 @@ +import { emptyPluginConfigSchema, type OpenClawPluginApi } from "openclaw/plugin-sdk/core"; +import { buildVeniceProvider } from "../../src/agents/models-config.providers.discovery.js"; + +const PROVIDER_ID = "venice"; + +const venicePlugin = { + id: PROVIDER_ID, + name: "Venice Provider", + description: "Bundled Venice provider plugin", + configSchema: emptyPluginConfigSchema(), + register(api: OpenClawPluginApi) { + api.registerProvider({ + id: PROVIDER_ID, + label: "Venice", + docsPath: "/providers/venice", + envVars: ["VENICE_API_KEY"], + auth: [], + catalog: { + order: "simple", + run: async (ctx) => { + const apiKey = ctx.resolveProviderApiKey(PROVIDER_ID).apiKey; + if (!apiKey) { + return null; + } + return { + provider: { + ...(await buildVeniceProvider()), + apiKey, + }, + }; + }, + }, + }); + }, +}; + +export default venicePlugin; diff --git a/extensions/venice/openclaw.plugin.json b/extensions/venice/openclaw.plugin.json new file mode 100644 index 00000000000..6262595509e --- /dev/null +++ b/extensions/venice/openclaw.plugin.json @@ -0,0 +1,9 @@ +{ + "id": "venice", + "providers": ["venice"], + "configSchema": { + "type": "object", + "additionalProperties": false, + "properties": {} + } +} diff --git a/extensions/venice/package.json b/extensions/venice/package.json new file mode 100644 index 00000000000..1fa9b083088 --- /dev/null +++ b/extensions/venice/package.json @@ -0,0 +1,12 @@ +{ + "name": "@openclaw/venice-provider", + "version": "2026.3.14", + "private": true, + "description": "OpenClaw Venice provider plugin", + "type": "module", + "openclaw": { + "extensions": [ + "./index.ts" + ] + } +} diff --git a/extensions/vercel-ai-gateway/index.ts b/extensions/vercel-ai-gateway/index.ts new file mode 100644 index 00000000000..c3098130f3e --- /dev/null +++ b/extensions/vercel-ai-gateway/index.ts @@ -0,0 +1,37 @@ +import { emptyPluginConfigSchema, type OpenClawPluginApi } from "openclaw/plugin-sdk/core"; +import { buildVercelAiGatewayProvider } from "../../src/agents/models-config.providers.discovery.js"; + +const PROVIDER_ID = "vercel-ai-gateway"; + +const vercelAiGatewayPlugin = { + id: PROVIDER_ID, + name: "Vercel AI Gateway Provider", + description: "Bundled Vercel AI Gateway provider plugin", + configSchema: emptyPluginConfigSchema(), + register(api: OpenClawPluginApi) { + api.registerProvider({ + id: PROVIDER_ID, + label: "Vercel AI Gateway", + docsPath: "/providers/vercel-ai-gateway", + envVars: ["AI_GATEWAY_API_KEY"], + auth: [], + catalog: { + order: "simple", + run: async (ctx) => { + const apiKey = ctx.resolveProviderApiKey(PROVIDER_ID).apiKey; + if (!apiKey) { + return null; + } + return { + provider: { + ...(await buildVercelAiGatewayProvider()), + apiKey, + }, + }; + }, + }, + }); + }, +}; + +export default vercelAiGatewayPlugin; diff --git a/extensions/vercel-ai-gateway/openclaw.plugin.json b/extensions/vercel-ai-gateway/openclaw.plugin.json new file mode 100644 index 00000000000..14f4a214605 --- /dev/null +++ b/extensions/vercel-ai-gateway/openclaw.plugin.json @@ -0,0 +1,9 @@ +{ + "id": "vercel-ai-gateway", + "providers": ["vercel-ai-gateway"], + "configSchema": { + "type": "object", + "additionalProperties": false, + "properties": {} + } +} diff --git a/extensions/vercel-ai-gateway/package.json b/extensions/vercel-ai-gateway/package.json new file mode 100644 index 00000000000..c81a82e40c0 --- /dev/null +++ b/extensions/vercel-ai-gateway/package.json @@ -0,0 +1,12 @@ +{ + "name": "@openclaw/vercel-ai-gateway-provider", + "version": "2026.3.14", + "private": true, + "description": "OpenClaw Vercel AI Gateway provider plugin", + "type": "module", + "openclaw": { + "extensions": [ + "./index.ts" + ] + } +} diff --git a/extensions/volcengine/index.ts b/extensions/volcengine/index.ts new file mode 100644 index 00000000000..7d907b5f53e --- /dev/null +++ b/extensions/volcengine/index.ts @@ -0,0 +1,40 @@ +import { emptyPluginConfigSchema, type OpenClawPluginApi } from "openclaw/plugin-sdk/core"; +import { + buildDoubaoCodingProvider, + buildDoubaoProvider, +} from "../../src/agents/models-config.providers.static.js"; + +const PROVIDER_ID = "volcengine"; + +const volcenginePlugin = { + id: PROVIDER_ID, + name: "Volcengine Provider", + description: "Bundled Volcengine provider plugin", + configSchema: emptyPluginConfigSchema(), + register(api: OpenClawPluginApi) { + api.registerProvider({ + id: PROVIDER_ID, + label: "Volcengine", + docsPath: "/concepts/model-providers#volcano-engine-doubao", + envVars: ["VOLCANO_ENGINE_API_KEY"], + auth: [], + catalog: { + order: "paired", + run: async (ctx) => { + const apiKey = ctx.resolveProviderApiKey(PROVIDER_ID).apiKey; + if (!apiKey) { + return null; + } + return { + providers: { + volcengine: { ...buildDoubaoProvider(), apiKey }, + "volcengine-plan": { ...buildDoubaoCodingProvider(), apiKey }, + }, + }; + }, + }, + }); + }, +}; + +export default volcenginePlugin; diff --git a/extensions/volcengine/openclaw.plugin.json b/extensions/volcengine/openclaw.plugin.json new file mode 100644 index 00000000000..0773577aef9 --- /dev/null +++ b/extensions/volcengine/openclaw.plugin.json @@ -0,0 +1,9 @@ +{ + "id": "volcengine", + "providers": ["volcengine", "volcengine-plan"], + "configSchema": { + "type": "object", + "additionalProperties": false, + "properties": {} + } +} diff --git a/extensions/volcengine/package.json b/extensions/volcengine/package.json new file mode 100644 index 00000000000..5e65f3522ae --- /dev/null +++ b/extensions/volcengine/package.json @@ -0,0 +1,12 @@ +{ + "name": "@openclaw/volcengine-provider", + "version": "2026.3.14", + "private": true, + "description": "OpenClaw Volcengine provider plugin", + "type": "module", + "openclaw": { + "extensions": [ + "./index.ts" + ] + } +} diff --git a/extensions/xiaomi/index.ts b/extensions/xiaomi/index.ts new file mode 100644 index 00000000000..847d7836ecc --- /dev/null +++ b/extensions/xiaomi/index.ts @@ -0,0 +1,37 @@ +import { emptyPluginConfigSchema, type OpenClawPluginApi } from "openclaw/plugin-sdk/core"; +import { buildXiaomiProvider } from "../../src/agents/models-config.providers.static.js"; + +const PROVIDER_ID = "xiaomi"; + +const xiaomiPlugin = { + id: PROVIDER_ID, + name: "Xiaomi Provider", + description: "Bundled Xiaomi provider plugin", + configSchema: emptyPluginConfigSchema(), + register(api: OpenClawPluginApi) { + api.registerProvider({ + id: PROVIDER_ID, + label: "Xiaomi", + docsPath: "/providers/xiaomi", + envVars: ["XIAOMI_API_KEY"], + auth: [], + catalog: { + order: "simple", + run: async (ctx) => { + const apiKey = ctx.resolveProviderApiKey(PROVIDER_ID).apiKey; + if (!apiKey) { + return null; + } + return { + provider: { + ...buildXiaomiProvider(), + apiKey, + }, + }; + }, + }, + }); + }, +}; + +export default xiaomiPlugin; diff --git a/extensions/xiaomi/openclaw.plugin.json b/extensions/xiaomi/openclaw.plugin.json new file mode 100644 index 00000000000..78c758c6571 --- /dev/null +++ b/extensions/xiaomi/openclaw.plugin.json @@ -0,0 +1,9 @@ +{ + "id": "xiaomi", + "providers": ["xiaomi"], + "configSchema": { + "type": "object", + "additionalProperties": false, + "properties": {} + } +} diff --git a/extensions/xiaomi/package.json b/extensions/xiaomi/package.json new file mode 100644 index 00000000000..dc89cc57160 --- /dev/null +++ b/extensions/xiaomi/package.json @@ -0,0 +1,12 @@ +{ + "name": "@openclaw/xiaomi-provider", + "version": "2026.3.14", + "private": true, + "description": "OpenClaw Xiaomi provider plugin", + "type": "module", + "openclaw": { + "extensions": [ + "./index.ts" + ] + } +}