refactor: extract single-provider plugin entry helper

This commit is contained in:
Peter Steinberger
2026-03-23 01:34:24 +00:00
parent 6237cfc6a6
commit 956fe72b39
15 changed files with 739 additions and 597 deletions

View File

@@ -1,6 +1,4 @@
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-auth";
import { buildSingleProviderApiKeyCatalog } from "openclaw/plugin-sdk/provider-catalog";
import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
import {
createKilocodeWrapper,
isProxyReasoningUnsupported,
@@ -10,59 +8,40 @@ import { buildKilocodeProviderWithDiscovery } from "./provider-catalog.js";
const PROVIDER_ID = "kilocode";
export default definePluginEntry({
export default defineSingleProviderPluginEntry({
id: PROVIDER_ID,
name: "Kilo Gateway Provider",
description: "Bundled Kilo Gateway provider plugin",
register(api) {
api.registerProvider({
id: PROVIDER_ID,
label: "Kilo Gateway",
docsPath: "/providers/kilocode",
envVars: ["KILOCODE_API_KEY"],
auth: [
createProviderApiKeyAuthMethod({
providerId: PROVIDER_ID,
methodId: "api-key",
label: "Kilo Gateway API key",
hint: "API key (OpenRouter-compatible)",
optionKey: "kilocodeApiKey",
flagName: "--kilocode-api-key",
envVar: "KILOCODE_API_KEY",
promptMessage: "Enter Kilo Gateway API key",
defaultModel: KILOCODE_DEFAULT_MODEL_REF,
expectedProviders: ["kilocode"],
applyConfig: (cfg) => applyKilocodeConfig(cfg),
wizard: {
choiceId: "kilocode-api-key",
choiceLabel: "Kilo Gateway API key",
groupId: "kilocode",
groupLabel: "Kilo Gateway",
groupHint: "API key (OpenRouter-compatible)",
},
}),
],
catalog: {
order: "simple",
run: (ctx) =>
buildSingleProviderApiKeyCatalog({
ctx,
providerId: PROVIDER_ID,
buildProvider: buildKilocodeProviderWithDiscovery,
}),
provider: {
label: "Kilo Gateway",
docsPath: "/providers/kilocode",
auth: [
{
methodId: "api-key",
label: "Kilo Gateway API key",
hint: "API key (OpenRouter-compatible)",
optionKey: "kilocodeApiKey",
flagName: "--kilocode-api-key",
envVar: "KILOCODE_API_KEY",
promptMessage: "Enter Kilo Gateway API key",
defaultModel: KILOCODE_DEFAULT_MODEL_REF,
applyConfig: (cfg) => applyKilocodeConfig(cfg),
},
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/"),
});
],
catalog: {
buildProvider: buildKilocodeProviderWithDiscovery,
},
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/"),
},
});

View File

@@ -1,67 +1,51 @@
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-auth";
import { buildSingleProviderApiKeyCatalog } from "openclaw/plugin-sdk/provider-catalog";
import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
import { mistralMediaUnderstandingProvider } from "./media-understanding-provider.js";
import { applyMistralConfig, MISTRAL_DEFAULT_MODEL_REF } from "./onboard.js";
import { buildMistralProvider } from "./provider-catalog.js";
const PROVIDER_ID = "mistral";
export default definePluginEntry({
export default defineSingleProviderPluginEntry({
id: PROVIDER_ID,
name: "Mistral Provider",
description: "Bundled Mistral provider plugin",
register(api) {
api.registerProvider({
id: PROVIDER_ID,
label: "Mistral",
docsPath: "/providers/models",
envVars: ["MISTRAL_API_KEY"],
auth: [
createProviderApiKeyAuthMethod({
providerId: PROVIDER_ID,
methodId: "api-key",
label: "Mistral API key",
hint: "API key",
optionKey: "mistralApiKey",
flagName: "--mistral-api-key",
envVar: "MISTRAL_API_KEY",
promptMessage: "Enter Mistral API key",
defaultModel: MISTRAL_DEFAULT_MODEL_REF,
expectedProviders: ["mistral"],
applyConfig: (cfg) => applyMistralConfig(cfg),
wizard: {
choiceId: "mistral-api-key",
choiceLabel: "Mistral API key",
groupId: "mistral",
groupLabel: "Mistral AI",
groupHint: "API key",
},
}),
provider: {
label: "Mistral",
docsPath: "/providers/models",
auth: [
{
methodId: "api-key",
label: "Mistral API key",
hint: "API key",
optionKey: "mistralApiKey",
flagName: "--mistral-api-key",
envVar: "MISTRAL_API_KEY",
promptMessage: "Enter Mistral API key",
defaultModel: MISTRAL_DEFAULT_MODEL_REF,
applyConfig: (cfg) => applyMistralConfig(cfg),
wizard: {
groupLabel: "Mistral AI",
},
},
],
catalog: {
buildProvider: buildMistralProvider,
allowExplicitBaseUrl: true,
},
capabilities: {
transcriptToolCallIdMode: "strict9",
transcriptToolCallIdModelHints: [
"mistral",
"mixtral",
"codestral",
"pixtral",
"devstral",
"ministral",
"mistralai",
],
catalog: {
order: "simple",
run: (ctx) =>
buildSingleProviderApiKeyCatalog({
ctx,
providerId: PROVIDER_ID,
buildProvider: buildMistralProvider,
allowExplicitBaseUrl: true,
}),
},
capabilities: {
transcriptToolCallIdMode: "strict9",
transcriptToolCallIdModelHints: [
"mistral",
"mixtral",
"codestral",
"pixtral",
"devstral",
"ministral",
"mistralai",
],
},
});
},
},
register(api) {
api.registerMediaUnderstandingProvider(mistralMediaUnderstandingProvider);
},
});

View File

@@ -1,6 +1,4 @@
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-auth";
import { buildSingleProviderApiKeyCatalog } from "openclaw/plugin-sdk/provider-catalog";
import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
import {
applyModelStudioConfig,
applyModelStudioConfigCn,
@@ -10,82 +8,62 @@ import { buildModelStudioProvider } from "./provider-catalog.js";
const PROVIDER_ID = "modelstudio";
export default definePluginEntry({
export default defineSingleProviderPluginEntry({
id: PROVIDER_ID,
name: "Model Studio Provider",
description: "Bundled Model Studio provider plugin",
register(api) {
api.registerProvider({
id: PROVIDER_ID,
label: "Model Studio",
docsPath: "/providers/models",
envVars: ["MODELSTUDIO_API_KEY"],
auth: [
createProviderApiKeyAuthMethod({
providerId: PROVIDER_ID,
methodId: "api-key-cn",
label: "Coding Plan API Key for China (subscription)",
hint: "Endpoint: coding.dashscope.aliyuncs.com",
optionKey: "modelstudioApiKeyCn",
flagName: "--modelstudio-api-key-cn",
envVar: "MODELSTUDIO_API_KEY",
promptMessage: "Enter Alibaba Cloud Model Studio Coding Plan API key (China)",
defaultModel: MODELSTUDIO_DEFAULT_MODEL_REF,
expectedProviders: ["modelstudio"],
applyConfig: (cfg) => applyModelStudioConfigCn(cfg),
noteMessage: [
"Get your API key at: https://bailian.console.aliyun.com/",
"Endpoint: coding.dashscope.aliyuncs.com",
"Models: qwen3.5-plus, glm-4.7, kimi-k2.5, MiniMax-M2.5, etc.",
].join("\n"),
noteTitle: "Alibaba Cloud Model Studio Coding Plan (China)",
wizard: {
choiceId: "modelstudio-api-key-cn",
choiceLabel: "Coding Plan API Key for China (subscription)",
choiceHint: "Endpoint: coding.dashscope.aliyuncs.com",
groupId: "modelstudio",
groupLabel: "Alibaba Cloud Model Studio",
groupHint: "Coding Plan API key (CN / Global)",
},
}),
createProviderApiKeyAuthMethod({
providerId: PROVIDER_ID,
methodId: "api-key",
label: "Coding Plan API Key for Global/Intl (subscription)",
hint: "Endpoint: coding-intl.dashscope.aliyuncs.com",
optionKey: "modelstudioApiKey",
flagName: "--modelstudio-api-key",
envVar: "MODELSTUDIO_API_KEY",
promptMessage: "Enter Alibaba Cloud Model Studio Coding Plan API key (Global/Intl)",
defaultModel: MODELSTUDIO_DEFAULT_MODEL_REF,
expectedProviders: ["modelstudio"],
applyConfig: (cfg) => applyModelStudioConfig(cfg),
noteMessage: [
"Get your API key at: https://bailian.console.aliyun.com/",
"Endpoint: coding-intl.dashscope.aliyuncs.com",
"Models: qwen3.5-plus, glm-4.7, kimi-k2.5, MiniMax-M2.5, etc.",
].join("\n"),
noteTitle: "Alibaba Cloud Model Studio Coding Plan (Global/Intl)",
wizard: {
choiceId: "modelstudio-api-key",
choiceLabel: "Coding Plan API Key for Global/Intl (subscription)",
choiceHint: "Endpoint: coding-intl.dashscope.aliyuncs.com",
groupId: "modelstudio",
groupLabel: "Alibaba Cloud Model Studio",
groupHint: "Coding Plan API key (CN / Global)",
},
}),
],
catalog: {
order: "simple",
run: (ctx) =>
buildSingleProviderApiKeyCatalog({
ctx,
providerId: PROVIDER_ID,
buildProvider: buildModelStudioProvider,
allowExplicitBaseUrl: true,
}),
provider: {
label: "Model Studio",
docsPath: "/providers/models",
auth: [
{
methodId: "api-key-cn",
label: "Coding Plan API Key for China (subscription)",
hint: "Endpoint: coding.dashscope.aliyuncs.com",
optionKey: "modelstudioApiKeyCn",
flagName: "--modelstudio-api-key-cn",
envVar: "MODELSTUDIO_API_KEY",
promptMessage: "Enter Alibaba Cloud Model Studio Coding Plan API key (China)",
defaultModel: MODELSTUDIO_DEFAULT_MODEL_REF,
applyConfig: (cfg) => applyModelStudioConfigCn(cfg),
noteMessage: [
"Get your API key at: https://bailian.console.aliyun.com/",
"Endpoint: coding.dashscope.aliyuncs.com",
"Models: qwen3.5-plus, glm-4.7, kimi-k2.5, MiniMax-M2.5, etc.",
].join("\n"),
noteTitle: "Alibaba Cloud Model Studio Coding Plan (China)",
wizard: {
choiceHint: "Endpoint: coding.dashscope.aliyuncs.com",
groupLabel: "Alibaba Cloud Model Studio",
groupHint: "Coding Plan API key (CN / Global)",
},
},
});
{
methodId: "api-key",
label: "Coding Plan API Key for Global/Intl (subscription)",
hint: "Endpoint: coding-intl.dashscope.aliyuncs.com",
optionKey: "modelstudioApiKey",
flagName: "--modelstudio-api-key",
envVar: "MODELSTUDIO_API_KEY",
promptMessage: "Enter Alibaba Cloud Model Studio Coding Plan API key (Global/Intl)",
defaultModel: MODELSTUDIO_DEFAULT_MODEL_REF,
applyConfig: (cfg) => applyModelStudioConfig(cfg),
noteMessage: [
"Get your API key at: https://bailian.console.aliyun.com/",
"Endpoint: coding-intl.dashscope.aliyuncs.com",
"Models: qwen3.5-plus, glm-4.7, kimi-k2.5, MiniMax-M2.5, etc.",
].join("\n"),
noteTitle: "Alibaba Cloud Model Studio Coding Plan (Global/Intl)",
wizard: {
choiceHint: "Endpoint: coding-intl.dashscope.aliyuncs.com",
groupLabel: "Alibaba Cloud Model Studio",
groupHint: "Coding Plan API key (CN / Global)",
},
},
],
catalog: {
buildProvider: buildModelStudioProvider,
allowExplicitBaseUrl: true,
},
},
});

View File

@@ -1,6 +1,4 @@
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-auth";
import { buildSingleProviderApiKeyCatalog } from "openclaw/plugin-sdk/provider-catalog";
import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
import {
createMoonshotThinkingWrapper,
resolveMoonshotThinkingType,
@@ -16,76 +14,56 @@ import { createKimiWebSearchProvider } from "./src/kimi-web-search-provider.js";
const PROVIDER_ID = "moonshot";
export default definePluginEntry({
export default defineSingleProviderPluginEntry({
id: PROVIDER_ID,
name: "Moonshot Provider",
description: "Bundled Moonshot provider plugin",
provider: {
label: "Moonshot",
docsPath: "/providers/moonshot",
auth: [
{
methodId: "api-key",
label: "Kimi API key (.ai)",
hint: "Kimi K2.5 + Kimi",
optionKey: "moonshotApiKey",
flagName: "--moonshot-api-key",
envVar: "MOONSHOT_API_KEY",
promptMessage: "Enter Moonshot API key",
defaultModel: MOONSHOT_DEFAULT_MODEL_REF,
applyConfig: (cfg) => applyMoonshotConfig(cfg),
wizard: {
groupLabel: "Moonshot AI (Kimi K2.5)",
},
},
{
methodId: "api-key-cn",
label: "Kimi API key (.cn)",
hint: "Kimi K2.5 + Kimi",
optionKey: "moonshotApiKey",
flagName: "--moonshot-api-key",
envVar: "MOONSHOT_API_KEY",
promptMessage: "Enter Moonshot API key (.cn)",
defaultModel: MOONSHOT_DEFAULT_MODEL_REF,
applyConfig: (cfg) => applyMoonshotConfigCn(cfg),
wizard: {
groupLabel: "Moonshot AI (Kimi K2.5)",
},
},
],
catalog: {
buildProvider: buildMoonshotProvider,
allowExplicitBaseUrl: true,
},
wrapStreamFn: (ctx) => {
const thinkingType = resolveMoonshotThinkingType({
configuredThinking: ctx.extraParams?.thinking,
thinkingLevel: ctx.thinkingLevel,
});
return createMoonshotThinkingWrapper(ctx.streamFn, thinkingType);
},
},
register(api) {
api.registerProvider({
id: PROVIDER_ID,
label: "Moonshot",
docsPath: "/providers/moonshot",
envVars: ["MOONSHOT_API_KEY"],
auth: [
createProviderApiKeyAuthMethod({
providerId: PROVIDER_ID,
methodId: "api-key",
label: "Kimi API key (.ai)",
hint: "Kimi K2.5 + Kimi",
optionKey: "moonshotApiKey",
flagName: "--moonshot-api-key",
envVar: "MOONSHOT_API_KEY",
promptMessage: "Enter Moonshot API key",
defaultModel: MOONSHOT_DEFAULT_MODEL_REF,
expectedProviders: ["moonshot"],
applyConfig: (cfg) => applyMoonshotConfig(cfg),
wizard: {
choiceId: "moonshot-api-key",
choiceLabel: "Kimi API key (.ai)",
groupId: "moonshot",
groupLabel: "Moonshot AI (Kimi K2.5)",
groupHint: "Kimi K2.5 + Kimi",
},
}),
createProviderApiKeyAuthMethod({
providerId: PROVIDER_ID,
methodId: "api-key-cn",
label: "Kimi API key (.cn)",
hint: "Kimi K2.5 + Kimi",
optionKey: "moonshotApiKey",
flagName: "--moonshot-api-key",
envVar: "MOONSHOT_API_KEY",
promptMessage: "Enter Moonshot API key (.cn)",
defaultModel: MOONSHOT_DEFAULT_MODEL_REF,
expectedProviders: ["moonshot"],
applyConfig: (cfg) => applyMoonshotConfigCn(cfg),
wizard: {
choiceId: "moonshot-api-key-cn",
choiceLabel: "Kimi API key (.cn)",
groupId: "moonshot",
groupLabel: "Moonshot AI (Kimi K2.5)",
groupHint: "Kimi K2.5 + Kimi",
},
}),
],
catalog: {
order: "simple",
run: (ctx) =>
buildSingleProviderApiKeyCatalog({
ctx,
providerId: PROVIDER_ID,
buildProvider: buildMoonshotProvider,
allowExplicitBaseUrl: true,
}),
},
wrapStreamFn: (ctx) => {
const thinkingType = resolveMoonshotThinkingType({
configuredThinking: ctx.extraParams?.thinking,
thinkingLevel: ctx.thinkingLevel,
});
return createMoonshotThinkingWrapper(ctx.streamFn, thinkingType);
},
});
api.registerMediaUnderstandingProvider(moonshotMediaUnderstandingProvider);
api.registerWebSearchProvider(createKimiWebSearchProvider());
},

View File

@@ -1,29 +1,19 @@
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
import { buildSingleProviderApiKeyCatalog } from "openclaw/plugin-sdk/provider-catalog";
import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
import { buildNvidiaProvider } from "./provider-catalog.js";
const PROVIDER_ID = "nvidia";
export default definePluginEntry({
export default defineSingleProviderPluginEntry({
id: PROVIDER_ID,
name: "NVIDIA Provider",
description: "Bundled NVIDIA provider plugin",
register(api) {
api.registerProvider({
id: PROVIDER_ID,
label: "NVIDIA",
docsPath: "/providers/nvidia",
envVars: ["NVIDIA_API_KEY"],
auth: [],
catalog: {
order: "simple",
run: (ctx) =>
buildSingleProviderApiKeyCatalog({
ctx,
providerId: PROVIDER_ID,
buildProvider: buildNvidiaProvider,
}),
},
});
provider: {
label: "NVIDIA",
docsPath: "/providers/nvidia",
envVars: ["NVIDIA_API_KEY"],
auth: [],
catalog: {
buildProvider: buildNvidiaProvider,
},
},
});

View File

@@ -1,52 +1,31 @@
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-auth";
import { buildSingleProviderApiKeyCatalog } from "openclaw/plugin-sdk/provider-catalog";
import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
import { applyQianfanConfig, QIANFAN_DEFAULT_MODEL_REF } from "./onboard.js";
import { buildQianfanProvider } from "./provider-catalog.js";
const PROVIDER_ID = "qianfan";
export default definePluginEntry({
export default defineSingleProviderPluginEntry({
id: PROVIDER_ID,
name: "Qianfan Provider",
description: "Bundled Qianfan provider plugin",
register(api) {
api.registerProvider({
id: PROVIDER_ID,
label: "Qianfan",
docsPath: "/providers/qianfan",
envVars: ["QIANFAN_API_KEY"],
auth: [
createProviderApiKeyAuthMethod({
providerId: PROVIDER_ID,
methodId: "api-key",
label: "Qianfan API key",
hint: "API key",
optionKey: "qianfanApiKey",
flagName: "--qianfan-api-key",
envVar: "QIANFAN_API_KEY",
promptMessage: "Enter Qianfan API key",
defaultModel: QIANFAN_DEFAULT_MODEL_REF,
expectedProviders: ["qianfan"],
applyConfig: (cfg) => applyQianfanConfig(cfg),
wizard: {
choiceId: "qianfan-api-key",
choiceLabel: "Qianfan API key",
groupId: "qianfan",
groupLabel: "Qianfan",
groupHint: "API key",
},
}),
],
catalog: {
order: "simple",
run: (ctx) =>
buildSingleProviderApiKeyCatalog({
ctx,
providerId: PROVIDER_ID,
buildProvider: buildQianfanProvider,
}),
provider: {
label: "Qianfan",
docsPath: "/providers/qianfan",
auth: [
{
methodId: "api-key",
label: "Qianfan API key",
hint: "API key",
optionKey: "qianfanApiKey",
flagName: "--qianfan-api-key",
envVar: "QIANFAN_API_KEY",
promptMessage: "Enter Qianfan API key",
defaultModel: QIANFAN_DEFAULT_MODEL_REF,
applyConfig: (cfg) => applyQianfanConfig(cfg),
},
});
],
catalog: {
buildProvider: buildQianfanProvider,
},
},
});

View File

@@ -1,52 +1,31 @@
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-auth";
import { buildSingleProviderApiKeyCatalog } from "openclaw/plugin-sdk/provider-catalog";
import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
import { applySyntheticConfig, SYNTHETIC_DEFAULT_MODEL_REF } from "./onboard.js";
import { buildSyntheticProvider } from "./provider-catalog.js";
const PROVIDER_ID = "synthetic";
export default definePluginEntry({
export default defineSingleProviderPluginEntry({
id: PROVIDER_ID,
name: "Synthetic Provider",
description: "Bundled Synthetic provider plugin",
register(api) {
api.registerProvider({
id: PROVIDER_ID,
label: "Synthetic",
docsPath: "/providers/synthetic",
envVars: ["SYNTHETIC_API_KEY"],
auth: [
createProviderApiKeyAuthMethod({
providerId: PROVIDER_ID,
methodId: "api-key",
label: "Synthetic API key",
hint: "Anthropic-compatible (multi-model)",
optionKey: "syntheticApiKey",
flagName: "--synthetic-api-key",
envVar: "SYNTHETIC_API_KEY",
promptMessage: "Enter Synthetic API key",
defaultModel: SYNTHETIC_DEFAULT_MODEL_REF,
expectedProviders: ["synthetic"],
applyConfig: (cfg) => applySyntheticConfig(cfg),
wizard: {
choiceId: "synthetic-api-key",
choiceLabel: "Synthetic API key",
groupId: "synthetic",
groupLabel: "Synthetic",
groupHint: "Anthropic-compatible (multi-model)",
},
}),
],
catalog: {
order: "simple",
run: (ctx) =>
buildSingleProviderApiKeyCatalog({
ctx,
providerId: PROVIDER_ID,
buildProvider: buildSyntheticProvider,
}),
provider: {
label: "Synthetic",
docsPath: "/providers/synthetic",
auth: [
{
methodId: "api-key",
label: "Synthetic API key",
hint: "Anthropic-compatible (multi-model)",
optionKey: "syntheticApiKey",
flagName: "--synthetic-api-key",
envVar: "SYNTHETIC_API_KEY",
promptMessage: "Enter Synthetic API key",
defaultModel: SYNTHETIC_DEFAULT_MODEL_REF,
applyConfig: (cfg) => applySyntheticConfig(cfg),
},
});
],
catalog: {
buildProvider: buildSyntheticProvider,
},
},
});

View File

@@ -1,52 +1,34 @@
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-auth";
import { buildSingleProviderApiKeyCatalog } from "openclaw/plugin-sdk/provider-catalog";
import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
import { applyTogetherConfig, TOGETHER_DEFAULT_MODEL_REF } from "./onboard.js";
import { buildTogetherProvider } from "./provider-catalog.js";
const PROVIDER_ID = "together";
export default definePluginEntry({
export default defineSingleProviderPluginEntry({
id: PROVIDER_ID,
name: "Together Provider",
description: "Bundled Together provider plugin",
register(api) {
api.registerProvider({
id: PROVIDER_ID,
label: "Together",
docsPath: "/providers/together",
envVars: ["TOGETHER_API_KEY"],
auth: [
createProviderApiKeyAuthMethod({
providerId: PROVIDER_ID,
methodId: "api-key",
label: "Together AI API key",
hint: "API key",
optionKey: "togetherApiKey",
flagName: "--together-api-key",
envVar: "TOGETHER_API_KEY",
promptMessage: "Enter Together AI API key",
defaultModel: TOGETHER_DEFAULT_MODEL_REF,
expectedProviders: ["together"],
applyConfig: (cfg) => applyTogetherConfig(cfg),
wizard: {
choiceId: "together-api-key",
choiceLabel: "Together AI API key",
groupId: "together",
groupLabel: "Together AI",
groupHint: "API key",
},
}),
],
catalog: {
order: "simple",
run: (ctx) =>
buildSingleProviderApiKeyCatalog({
ctx,
providerId: PROVIDER_ID,
buildProvider: buildTogetherProvider,
}),
provider: {
label: "Together",
docsPath: "/providers/together",
auth: [
{
methodId: "api-key",
label: "Together AI API key",
hint: "API key",
optionKey: "togetherApiKey",
flagName: "--together-api-key",
envVar: "TOGETHER_API_KEY",
promptMessage: "Enter Together AI API key",
defaultModel: TOGETHER_DEFAULT_MODEL_REF,
applyConfig: (cfg) => applyTogetherConfig(cfg),
wizard: {
groupLabel: "Together AI",
},
},
});
],
catalog: {
buildProvider: buildTogetherProvider,
},
},
});

View File

@@ -1,6 +1,4 @@
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-auth-api-key";
import { buildSingleProviderApiKeyCatalog } from "openclaw/plugin-sdk/provider-catalog";
import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
import { applyXaiModelCompat } from "openclaw/plugin-sdk/provider-models";
import { applyVeniceConfig, VENICE_DEFAULT_MODEL_REF } from "./onboard.js";
import { buildVeniceProvider } from "./provider-catalog.js";
@@ -11,55 +9,39 @@ function isXaiBackedVeniceModel(modelId: string): boolean {
return modelId.trim().toLowerCase().includes("grok");
}
export default definePluginEntry({
export default defineSingleProviderPluginEntry({
id: PROVIDER_ID,
name: "Venice Provider",
description: "Bundled Venice provider plugin",
register(api) {
api.registerProvider({
id: PROVIDER_ID,
label: "Venice",
docsPath: "/providers/venice",
envVars: ["VENICE_API_KEY"],
auth: [
createProviderApiKeyAuthMethod({
providerId: PROVIDER_ID,
methodId: "api-key",
label: "Venice AI API key",
hint: "Privacy-focused (uncensored models)",
optionKey: "veniceApiKey",
flagName: "--venice-api-key",
envVar: "VENICE_API_KEY",
promptMessage: "Enter Venice AI API key",
defaultModel: VENICE_DEFAULT_MODEL_REF,
expectedProviders: ["venice"],
applyConfig: (cfg) => applyVeniceConfig(cfg),
noteMessage: [
"Venice AI provides privacy-focused inference with uncensored models.",
"Get your API key at: https://venice.ai/settings/api",
"Supports 'private' (fully private) and 'anonymized' (proxy) modes.",
].join("\n"),
noteTitle: "Venice AI",
wizard: {
choiceId: "venice-api-key",
choiceLabel: "Venice AI API key",
groupId: "venice",
groupLabel: "Venice AI",
groupHint: "Privacy-focused (uncensored models)",
},
}),
],
catalog: {
order: "simple",
run: (ctx) =>
buildSingleProviderApiKeyCatalog({
ctx,
providerId: PROVIDER_ID,
buildProvider: buildVeniceProvider,
}),
provider: {
label: "Venice",
docsPath: "/providers/venice",
auth: [
{
methodId: "api-key",
label: "Venice AI API key",
hint: "Privacy-focused (uncensored models)",
optionKey: "veniceApiKey",
flagName: "--venice-api-key",
envVar: "VENICE_API_KEY",
promptMessage: "Enter Venice AI API key",
defaultModel: VENICE_DEFAULT_MODEL_REF,
applyConfig: (cfg) => applyVeniceConfig(cfg),
noteMessage: [
"Venice AI provides privacy-focused inference with uncensored models.",
"Get your API key at: https://venice.ai/settings/api",
"Supports 'private' (fully private) and 'anonymized' (proxy) modes.",
].join("\n"),
noteTitle: "Venice AI",
wizard: {
groupLabel: "Venice AI",
},
},
normalizeResolvedModel: ({ modelId, model }) =>
isXaiBackedVeniceModel(modelId) ? applyXaiModelCompat(model) : undefined,
});
],
catalog: {
buildProvider: buildVeniceProvider,
},
normalizeResolvedModel: ({ modelId, model }) =>
isXaiBackedVeniceModel(modelId) ? applyXaiModelCompat(model) : undefined,
},
});

View File

@@ -1,52 +1,35 @@
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-auth";
import { buildSingleProviderApiKeyCatalog } from "openclaw/plugin-sdk/provider-catalog";
import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
import { applyVercelAiGatewayConfig, VERCEL_AI_GATEWAY_DEFAULT_MODEL_REF } from "./onboard.js";
import { buildVercelAiGatewayProvider } from "./provider-catalog.js";
const PROVIDER_ID = "vercel-ai-gateway";
export default definePluginEntry({
export default defineSingleProviderPluginEntry({
id: PROVIDER_ID,
name: "Vercel AI Gateway Provider",
description: "Bundled Vercel AI Gateway provider plugin",
register(api) {
api.registerProvider({
id: PROVIDER_ID,
label: "Vercel AI Gateway",
docsPath: "/providers/vercel-ai-gateway",
envVars: ["AI_GATEWAY_API_KEY"],
auth: [
createProviderApiKeyAuthMethod({
providerId: PROVIDER_ID,
methodId: "api-key",
label: "Vercel AI Gateway API key",
hint: "API key",
optionKey: "aiGatewayApiKey",
flagName: "--ai-gateway-api-key",
envVar: "AI_GATEWAY_API_KEY",
promptMessage: "Enter Vercel AI Gateway API key",
defaultModel: VERCEL_AI_GATEWAY_DEFAULT_MODEL_REF,
expectedProviders: ["vercel-ai-gateway"],
applyConfig: (cfg) => applyVercelAiGatewayConfig(cfg),
wizard: {
choiceId: "ai-gateway-api-key",
choiceLabel: "Vercel AI Gateway API key",
groupId: "ai-gateway",
groupLabel: "Vercel AI Gateway",
groupHint: "API key",
},
}),
],
catalog: {
order: "simple",
run: (ctx) =>
buildSingleProviderApiKeyCatalog({
ctx,
providerId: PROVIDER_ID,
buildProvider: buildVercelAiGatewayProvider,
}),
provider: {
label: "Vercel AI Gateway",
docsPath: "/providers/vercel-ai-gateway",
auth: [
{
methodId: "api-key",
label: "Vercel AI Gateway API key",
hint: "API key",
optionKey: "aiGatewayApiKey",
flagName: "--ai-gateway-api-key",
envVar: "AI_GATEWAY_API_KEY",
promptMessage: "Enter Vercel AI Gateway API key",
defaultModel: VERCEL_AI_GATEWAY_DEFAULT_MODEL_REF,
applyConfig: (cfg) => applyVercelAiGatewayConfig(cfg),
wizard: {
choiceId: "ai-gateway-api-key",
groupId: "ai-gateway",
},
},
});
],
catalog: {
buildProvider: buildVercelAiGatewayProvider,
},
},
});

View File

@@ -1,6 +1,4 @@
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-auth-api-key";
import { buildSingleProviderApiKeyCatalog } from "openclaw/plugin-sdk/provider-catalog";
import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
import { applyXaiModelCompat } from "openclaw/plugin-sdk/provider-models";
import { createToolStreamWrapper } from "openclaw/plugin-sdk/provider-stream";
import { applyXaiConfig, XAI_DEFAULT_MODEL_REF } from "./onboard.js";
@@ -14,68 +12,54 @@ import { createXaiWebSearchProvider } from "./web-search.js";
const PROVIDER_ID = "xai";
export default definePluginEntry({
export default defineSingleProviderPluginEntry({
id: "xai",
name: "xAI Plugin",
description: "Bundled xAI plugin",
register(api) {
api.registerProvider({
id: PROVIDER_ID,
label: "xAI",
aliases: ["x-ai"],
docsPath: "/providers/xai",
envVars: ["XAI_API_KEY"],
auth: [
createProviderApiKeyAuthMethod({
providerId: PROVIDER_ID,
methodId: "api-key",
label: "xAI API key",
hint: "API key",
optionKey: "xaiApiKey",
flagName: "--xai-api-key",
envVar: "XAI_API_KEY",
promptMessage: "Enter xAI API key",
defaultModel: XAI_DEFAULT_MODEL_REF,
expectedProviders: ["xai"],
applyConfig: (cfg) => applyXaiConfig(cfg),
wizard: {
choiceId: "xai-api-key",
choiceLabel: "xAI API key",
groupId: "xai",
groupLabel: "xAI (Grok)",
groupHint: "API key",
},
}),
],
catalog: {
order: "simple",
run: (ctx) =>
buildSingleProviderApiKeyCatalog({
ctx,
providerId: PROVIDER_ID,
buildProvider: buildXaiProvider,
}),
provider: {
label: "xAI",
aliases: ["x-ai"],
docsPath: "/providers/xai",
auth: [
{
methodId: "api-key",
label: "xAI API key",
hint: "API key",
optionKey: "xaiApiKey",
flagName: "--xai-api-key",
envVar: "XAI_API_KEY",
promptMessage: "Enter xAI API key",
defaultModel: XAI_DEFAULT_MODEL_REF,
applyConfig: (cfg) => applyXaiConfig(cfg),
wizard: {
groupLabel: "xAI (Grok)",
},
},
prepareExtraParams: (ctx) => {
if (ctx.extraParams?.tool_stream !== undefined) {
return ctx.extraParams;
}
return {
...ctx.extraParams,
tool_stream: true,
};
},
wrapStreamFn: (ctx) =>
createToolStreamWrapper(
createXaiToolCallArgumentDecodingWrapper(
createXaiToolPayloadCompatibilityWrapper(ctx.streamFn),
),
ctx.extraParams?.tool_stream !== false,
],
catalog: {
buildProvider: buildXaiProvider,
},
prepareExtraParams: (ctx) => {
if (ctx.extraParams?.tool_stream !== undefined) {
return ctx.extraParams;
}
return {
...ctx.extraParams,
tool_stream: true,
};
},
wrapStreamFn: (ctx) =>
createToolStreamWrapper(
createXaiToolCallArgumentDecodingWrapper(
createXaiToolPayloadCompatibilityWrapper(ctx.streamFn),
),
normalizeResolvedModel: ({ model }) => applyXaiModelCompat(model),
resolveDynamicModel: (ctx) => resolveXaiForwardCompatModel({ providerId: PROVIDER_ID, ctx }),
isModernModelRef: ({ modelId }) => isModernXaiModel(modelId),
});
ctx.extraParams?.tool_stream !== false,
),
normalizeResolvedModel: ({ model }) => applyXaiModelCompat(model),
resolveDynamicModel: (ctx) => resolveXaiForwardCompatModel({ providerId: PROVIDER_ID, ctx }),
isModernModelRef: ({ modelId }) => isModernXaiModel(modelId),
},
register(api) {
api.registerWebSearchProvider(createXaiWebSearchProvider());
},
});

View File

@@ -1,64 +1,43 @@
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-auth";
import { buildSingleProviderApiKeyCatalog } from "openclaw/plugin-sdk/provider-catalog";
import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
import { PROVIDER_LABELS } from "openclaw/plugin-sdk/provider-usage";
import { applyXiaomiConfig, XIAOMI_DEFAULT_MODEL_REF } from "./onboard.js";
import { buildXiaomiProvider } from "./provider-catalog.js";
const PROVIDER_ID = "xiaomi";
export default definePluginEntry({
export default defineSingleProviderPluginEntry({
id: PROVIDER_ID,
name: "Xiaomi Provider",
description: "Bundled Xiaomi provider plugin",
register(api) {
api.registerProvider({
id: PROVIDER_ID,
label: "Xiaomi",
docsPath: "/providers/xiaomi",
envVars: ["XIAOMI_API_KEY"],
auth: [
createProviderApiKeyAuthMethod({
providerId: PROVIDER_ID,
methodId: "api-key",
label: "Xiaomi API key",
hint: "API key",
optionKey: "xiaomiApiKey",
flagName: "--xiaomi-api-key",
envVar: "XIAOMI_API_KEY",
promptMessage: "Enter Xiaomi API key",
defaultModel: XIAOMI_DEFAULT_MODEL_REF,
expectedProviders: ["xiaomi"],
applyConfig: (cfg) => applyXiaomiConfig(cfg),
wizard: {
choiceId: "xiaomi-api-key",
choiceLabel: "Xiaomi API key",
groupId: "xiaomi",
groupLabel: "Xiaomi",
groupHint: "API key",
},
}),
],
catalog: {
order: "simple",
run: (ctx) =>
buildSingleProviderApiKeyCatalog({
ctx,
providerId: PROVIDER_ID,
buildProvider: buildXiaomiProvider,
}),
provider: {
label: "Xiaomi",
docsPath: "/providers/xiaomi",
auth: [
{
methodId: "api-key",
label: "Xiaomi API key",
hint: "API key",
optionKey: "xiaomiApiKey",
flagName: "--xiaomi-api-key",
envVar: "XIAOMI_API_KEY",
promptMessage: "Enter Xiaomi API key",
defaultModel: XIAOMI_DEFAULT_MODEL_REF,
applyConfig: (cfg) => applyXiaomiConfig(cfg),
},
resolveUsageAuth: async (ctx) => {
const apiKey = ctx.resolveApiKeyFromConfigAndStore({
envDirect: [ctx.env.XIAOMI_API_KEY],
});
return apiKey ? { token: apiKey } : null;
},
fetchUsageSnapshot: async () => ({
provider: "xiaomi",
displayName: PROVIDER_LABELS.xiaomi,
windows: [],
}),
});
],
catalog: {
buildProvider: buildXiaomiProvider,
},
resolveUsageAuth: async (ctx) => {
const apiKey = ctx.resolveApiKeyFromConfigAndStore({
envDirect: [ctx.env.XIAOMI_API_KEY],
});
return apiKey ? { token: apiKey } : null;
},
fetchUsageSnapshot: async () => ({
provider: "xiaomi",
displayName: PROVIDER_LABELS.xiaomi,
windows: [],
}),
},
});