重构主控编排与运行时预热链路,统一工作区提示词/专家调度协议并补齐 wiki 记忆注入与写回闭环。

同时收敛启动与运维脚本默认行为(含 wiki worker)、更新 Admin 可观测性与相关测试,降低首轮时延并提高运行稳定性。

Made-with: Cursor
This commit is contained in:
oliver 2026-04-26 08:34:33 +08:00
parent 4a23b715a2
commit dbbe3add6a
14438 changed files with 2693620 additions and 2546 deletions

View file

@ -0,0 +1,8 @@
export {
applyLitellmConfig,
applyLitellmProviderConfig,
buildLitellmModelDefinition,
LITELLM_BASE_URL,
LITELLM_DEFAULT_MODEL_ID,
LITELLM_DEFAULT_MODEL_REF,
} from "./onboard.js";

View file

@ -0,0 +1,41 @@
import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
import { applyLitellmConfig, LITELLM_DEFAULT_MODEL_REF } from "./onboard.js";
import { buildLitellmProvider } from "./provider-catalog.js";
const PROVIDER_ID = "litellm";
export default defineSingleProviderPluginEntry({
id: PROVIDER_ID,
name: "LiteLLM Provider",
description: "Bundled LiteLLM provider plugin",
provider: {
label: "LiteLLM",
docsPath: "/providers/litellm",
auth: [
{
methodId: "api-key",
label: "LiteLLM API key",
hint: "Unified gateway for 100+ LLM providers",
optionKey: "litellmApiKey",
flagName: "--litellm-api-key",
envVar: "LITELLM_API_KEY",
promptMessage: "Enter LiteLLM API key",
defaultModel: LITELLM_DEFAULT_MODEL_REF,
applyConfig: (cfg) => applyLitellmConfig(cfg),
noteTitle: "LiteLLM",
noteMessage: [
"LiteLLM provides a unified API to 100+ LLM providers.",
"Get your API key from your LiteLLM proxy or https://litellm.ai",
"Default proxy runs on http://localhost:4000",
].join("\n"),
wizard: {
groupHint: "Unified LLM gateway (100+ providers)",
},
},
],
catalog: {
buildProvider: buildLitellmProvider,
allowExplicitBaseUrl: true,
},
},
});

View file

@ -0,0 +1,21 @@
import { describe, expect, it } from "vitest";
import { expectProviderOnboardMergedLegacyConfig } from "../../test/helpers/plugins/provider-onboard.js";
import { applyLitellmProviderConfig } from "./onboard.js";
describe("litellm onboard", () => {
it("preserves existing baseUrl and api key while adding the default model", () => {
const provider = expectProviderOnboardMergedLegacyConfig({
applyProviderConfig: applyLitellmProviderConfig,
providerId: "litellm",
providerApi: "openai-completions",
baseUrl: "https://litellm.example/v1",
legacyApi: "anthropic-messages",
legacyModelId: "custom-model",
legacyModelName: "Custom",
legacyBaseUrl: "https://litellm.example/v1",
legacyApiKey: " old-key ",
});
expect(provider?.models.map((m) => m.id)).toEqual(["custom-model", "claude-opus-4-6"]);
});
});

View file

@ -0,0 +1,55 @@
import {
createDefaultModelPresetAppliers,
type ModelDefinitionConfig,
type OpenClawConfig,
} from "openclaw/plugin-sdk/provider-onboard";
export const LITELLM_BASE_URL = "http://localhost:4000";
export const LITELLM_DEFAULT_MODEL_ID = "claude-opus-4-6";
export const LITELLM_DEFAULT_MODEL_REF = `litellm/${LITELLM_DEFAULT_MODEL_ID}`;
const LITELLM_DEFAULT_CONTEXT_WINDOW = 128_000;
const LITELLM_DEFAULT_MAX_TOKENS = 8_192;
const LITELLM_DEFAULT_COST = {
input: 0,
output: 0,
cacheRead: 0,
cacheWrite: 0,
};
export function buildLitellmModelDefinition(): ModelDefinitionConfig {
return {
id: LITELLM_DEFAULT_MODEL_ID,
name: "Claude Opus 4.6",
reasoning: true,
input: ["text", "image"],
cost: LITELLM_DEFAULT_COST,
contextWindow: LITELLM_DEFAULT_CONTEXT_WINDOW,
maxTokens: LITELLM_DEFAULT_MAX_TOKENS,
};
}
const litellmPresetAppliers = createDefaultModelPresetAppliers({
primaryModelRef: LITELLM_DEFAULT_MODEL_REF,
resolveParams: (cfg: OpenClawConfig) => {
const existingProvider = cfg.models?.providers?.litellm as { baseUrl?: unknown } | undefined;
const resolvedBaseUrl =
typeof existingProvider?.baseUrl === "string" ? existingProvider.baseUrl.trim() : "";
return {
providerId: "litellm",
api: "openai-completions" as const,
baseUrl: resolvedBaseUrl || LITELLM_BASE_URL,
defaultModel: buildLitellmModelDefinition(),
defaultModelId: LITELLM_DEFAULT_MODEL_ID,
aliases: [{ modelRef: LITELLM_DEFAULT_MODEL_REF, alias: "LiteLLM" }],
};
},
});
export function applyLitellmProviderConfig(cfg: OpenClawConfig): OpenClawConfig {
return litellmPresetAppliers.applyProviderConfig(cfg);
}
export function applyLitellmConfig(cfg: OpenClawConfig): OpenClawConfig {
return litellmPresetAppliers.applyConfig(cfg);
}

View file

@ -0,0 +1,29 @@
{
"id": "litellm",
"enabledByDefault": true,
"providers": ["litellm"],
"providerAuthEnvVars": {
"litellm": ["LITELLM_API_KEY"]
},
"providerAuthChoices": [
{
"provider": "litellm",
"method": "api-key",
"choiceId": "litellm-api-key",
"choiceLabel": "LiteLLM API key",
"choiceHint": "Unified gateway for 100+ LLM providers",
"groupId": "litellm",
"groupLabel": "LiteLLM",
"groupHint": "Unified LLM gateway (100+ providers)",
"optionKey": "litellmApiKey",
"cliFlag": "--litellm-api-key",
"cliOption": "--litellm-api-key <key>",
"cliDescription": "LiteLLM API key"
}
],
"configSchema": {
"type": "object",
"additionalProperties": false,
"properties": {}
}
}

View file

@ -0,0 +1,15 @@
{
"name": "@openclaw/litellm-provider",
"version": "2026.4.20",
"private": true,
"description": "OpenClaw LiteLLM provider plugin",
"type": "module",
"devDependencies": {
"@openclaw/plugin-sdk": "workspace:*"
},
"openclaw": {
"extensions": [
"./index.ts"
]
}
}

View file

@ -0,0 +1,10 @@
import type { ModelProviderConfig } from "openclaw/plugin-sdk/provider-model-shared";
import { buildLitellmModelDefinition, LITELLM_BASE_URL } from "./onboard.js";
export function buildLitellmProvider(): ModelProviderConfig {
return {
baseUrl: LITELLM_BASE_URL,
api: "openai-completions",
models: [buildLitellmModelDefinition()],
};
}

View file

@ -0,0 +1,16 @@
{
"extends": "../tsconfig.package-boundary.base.json",
"compilerOptions": {
"rootDir": "."
},
"include": ["./*.ts", "./src/**/*.ts"],
"exclude": [
"./**/*.test.ts",
"./dist/**",
"./node_modules/**",
"./src/test-support/**",
"./src/**/*test-helpers.ts",
"./src/**/*test-harness.ts",
"./src/**/*test-support.ts"
]
}