mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-16 12:30:49 +00:00
build(plugins): add bundled provider plugin packages
This commit is contained in:
64
.github/labeler.yml
vendored
64
.github/labeler.yml
vendored
@@ -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/**"
|
||||
|
||||
40
extensions/byteplus/index.ts
Normal file
40
extensions/byteplus/index.ts
Normal file
@@ -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;
|
||||
9
extensions/byteplus/openclaw.plugin.json
Normal file
9
extensions/byteplus/openclaw.plugin.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"id": "byteplus",
|
||||
"providers": ["byteplus", "byteplus-plan"],
|
||||
"configSchema": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {}
|
||||
}
|
||||
}
|
||||
12
extensions/byteplus/package.json
Normal file
12
extensions/byteplus/package.json
Normal file
@@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
82
extensions/cloudflare-ai-gateway/index.ts
Normal file
82
extensions/cloudflare-ai-gateway/index.ts
Normal file
@@ -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<typeof ensureAuthProfileStore>["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;
|
||||
9
extensions/cloudflare-ai-gateway/openclaw.plugin.json
Normal file
9
extensions/cloudflare-ai-gateway/openclaw.plugin.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"id": "cloudflare-ai-gateway",
|
||||
"providers": ["cloudflare-ai-gateway"],
|
||||
"configSchema": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {}
|
||||
}
|
||||
}
|
||||
12
extensions/cloudflare-ai-gateway/package.json
Normal file
12
extensions/cloudflare-ai-gateway/package.json
Normal file
@@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
37
extensions/huggingface/index.ts
Normal file
37
extensions/huggingface/index.ts
Normal file
@@ -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;
|
||||
9
extensions/huggingface/openclaw.plugin.json
Normal file
9
extensions/huggingface/openclaw.plugin.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"id": "huggingface",
|
||||
"providers": ["huggingface"],
|
||||
"configSchema": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {}
|
||||
}
|
||||
}
|
||||
12
extensions/huggingface/package.json
Normal file
12
extensions/huggingface/package.json
Normal file
@@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
53
extensions/kilocode/index.ts
Normal file
53
extensions/kilocode/index.ts
Normal file
@@ -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;
|
||||
9
extensions/kilocode/openclaw.plugin.json
Normal file
9
extensions/kilocode/openclaw.plugin.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"id": "kilocode",
|
||||
"providers": ["kilocode"],
|
||||
"configSchema": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {}
|
||||
}
|
||||
}
|
||||
12
extensions/kilocode/package.json
Normal file
12
extensions/kilocode/package.json
Normal file
@@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
58
extensions/kimi-coding/index.ts
Normal file
58
extensions/kimi-coding/index.ts
Normal file
@@ -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;
|
||||
9
extensions/kimi-coding/openclaw.plugin.json
Normal file
9
extensions/kimi-coding/openclaw.plugin.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"id": "kimi-coding",
|
||||
"providers": ["kimi-coding"],
|
||||
"configSchema": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {}
|
||||
}
|
||||
}
|
||||
12
extensions/kimi-coding/package.json
Normal file
12
extensions/kimi-coding/package.json
Normal file
@@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
37
extensions/minimax/index.ts
Normal file
37
extensions/minimax/index.ts
Normal file
@@ -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;
|
||||
9
extensions/minimax/openclaw.plugin.json
Normal file
9
extensions/minimax/openclaw.plugin.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"id": "minimax",
|
||||
"providers": ["minimax"],
|
||||
"configSchema": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {}
|
||||
}
|
||||
}
|
||||
12
extensions/minimax/package.json
Normal file
12
extensions/minimax/package.json
Normal file
@@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
41
extensions/modelstudio/index.ts
Normal file
41
extensions/modelstudio/index.ts
Normal file
@@ -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;
|
||||
9
extensions/modelstudio/openclaw.plugin.json
Normal file
9
extensions/modelstudio/openclaw.plugin.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"id": "modelstudio",
|
||||
"providers": ["modelstudio"],
|
||||
"configSchema": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {}
|
||||
}
|
||||
}
|
||||
12
extensions/modelstudio/package.json
Normal file
12
extensions/modelstudio/package.json
Normal file
@@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
52
extensions/moonshot/index.ts
Normal file
52
extensions/moonshot/index.ts
Normal file
@@ -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;
|
||||
9
extensions/moonshot/openclaw.plugin.json
Normal file
9
extensions/moonshot/openclaw.plugin.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"id": "moonshot",
|
||||
"providers": ["moonshot"],
|
||||
"configSchema": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {}
|
||||
}
|
||||
}
|
||||
12
extensions/moonshot/package.json
Normal file
12
extensions/moonshot/package.json
Normal file
@@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
37
extensions/nvidia/index.ts
Normal file
37
extensions/nvidia/index.ts
Normal file
@@ -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;
|
||||
9
extensions/nvidia/openclaw.plugin.json
Normal file
9
extensions/nvidia/openclaw.plugin.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"id": "nvidia",
|
||||
"providers": ["nvidia"],
|
||||
"configSchema": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {}
|
||||
}
|
||||
}
|
||||
12
extensions/nvidia/package.json
Normal file
12
extensions/nvidia/package.json
Normal file
@@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
37
extensions/qianfan/index.ts
Normal file
37
extensions/qianfan/index.ts
Normal file
@@ -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;
|
||||
9
extensions/qianfan/openclaw.plugin.json
Normal file
9
extensions/qianfan/openclaw.plugin.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"id": "qianfan",
|
||||
"providers": ["qianfan"],
|
||||
"configSchema": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {}
|
||||
}
|
||||
}
|
||||
12
extensions/qianfan/package.json
Normal file
12
extensions/qianfan/package.json
Normal file
@@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
37
extensions/synthetic/index.ts
Normal file
37
extensions/synthetic/index.ts
Normal file
@@ -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;
|
||||
9
extensions/synthetic/openclaw.plugin.json
Normal file
9
extensions/synthetic/openclaw.plugin.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"id": "synthetic",
|
||||
"providers": ["synthetic"],
|
||||
"configSchema": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {}
|
||||
}
|
||||
}
|
||||
12
extensions/synthetic/package.json
Normal file
12
extensions/synthetic/package.json
Normal file
@@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
37
extensions/together/index.ts
Normal file
37
extensions/together/index.ts
Normal file
@@ -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;
|
||||
9
extensions/together/openclaw.plugin.json
Normal file
9
extensions/together/openclaw.plugin.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"id": "together",
|
||||
"providers": ["together"],
|
||||
"configSchema": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {}
|
||||
}
|
||||
}
|
||||
12
extensions/together/package.json
Normal file
12
extensions/together/package.json
Normal file
@@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
37
extensions/venice/index.ts
Normal file
37
extensions/venice/index.ts
Normal file
@@ -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;
|
||||
9
extensions/venice/openclaw.plugin.json
Normal file
9
extensions/venice/openclaw.plugin.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"id": "venice",
|
||||
"providers": ["venice"],
|
||||
"configSchema": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {}
|
||||
}
|
||||
}
|
||||
12
extensions/venice/package.json
Normal file
12
extensions/venice/package.json
Normal file
@@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
37
extensions/vercel-ai-gateway/index.ts
Normal file
37
extensions/vercel-ai-gateway/index.ts
Normal file
@@ -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;
|
||||
9
extensions/vercel-ai-gateway/openclaw.plugin.json
Normal file
9
extensions/vercel-ai-gateway/openclaw.plugin.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"id": "vercel-ai-gateway",
|
||||
"providers": ["vercel-ai-gateway"],
|
||||
"configSchema": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {}
|
||||
}
|
||||
}
|
||||
12
extensions/vercel-ai-gateway/package.json
Normal file
12
extensions/vercel-ai-gateway/package.json
Normal file
@@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
40
extensions/volcengine/index.ts
Normal file
40
extensions/volcengine/index.ts
Normal file
@@ -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;
|
||||
9
extensions/volcengine/openclaw.plugin.json
Normal file
9
extensions/volcengine/openclaw.plugin.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"id": "volcengine",
|
||||
"providers": ["volcengine", "volcengine-plan"],
|
||||
"configSchema": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {}
|
||||
}
|
||||
}
|
||||
12
extensions/volcengine/package.json
Normal file
12
extensions/volcengine/package.json
Normal file
@@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
37
extensions/xiaomi/index.ts
Normal file
37
extensions/xiaomi/index.ts
Normal file
@@ -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;
|
||||
9
extensions/xiaomi/openclaw.plugin.json
Normal file
9
extensions/xiaomi/openclaw.plugin.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"id": "xiaomi",
|
||||
"providers": ["xiaomi"],
|
||||
"configSchema": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {}
|
||||
}
|
||||
}
|
||||
12
extensions/xiaomi/package.json
Normal file
12
extensions/xiaomi/package.json
Normal file
@@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user