mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-25 08:52:12 +00:00
Rebase: restore compatibility surfaces
This commit is contained in:
@@ -14,8 +14,15 @@ import {
|
||||
} from "./agent-scope.js";
|
||||
import { DEFAULT_MODEL, DEFAULT_PROVIDER } from "./defaults.js";
|
||||
import type { ModelCatalogEntry } from "./model-catalog.js";
|
||||
import { normalizeGoogleModelId } from "./model-id-normalization.js";
|
||||
import { splitTrailingAuthProfile } from "./model-ref-profile.js";
|
||||
import {
|
||||
legacyModelKey,
|
||||
modelKey,
|
||||
normalizeModelRef,
|
||||
parseModelRef,
|
||||
type ModelRef,
|
||||
} from "./model-ref.js";
|
||||
import { normalizeProviderId, normalizeProviderIdForAuth } from "./provider-id.js";
|
||||
|
||||
const log = createSubsystemLogger("model-selection");
|
||||
|
||||
@@ -588,3 +595,13 @@ export function normalizeModelSelection(value: unknown): string | undefined {
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export {
|
||||
legacyModelKey,
|
||||
modelKey,
|
||||
normalizeModelRef,
|
||||
normalizeProviderId,
|
||||
normalizeProviderIdForAuth,
|
||||
parseModelRef,
|
||||
};
|
||||
export type { ModelRef };
|
||||
|
||||
@@ -799,7 +799,7 @@ type CommandsListItem = {
|
||||
|
||||
function buildCommandItems(
|
||||
commands: ChatCommandDefinition[],
|
||||
pluginCommands: ReturnType<typeof listPluginCommands>,
|
||||
pluginCommands: ReturnType<typeof listExtensionHostPluginCommands>,
|
||||
): CommandsListItem[] {
|
||||
const grouped = groupCommandsByCategory(commands);
|
||||
const items: CommandsListItem[] = [];
|
||||
|
||||
@@ -401,7 +401,7 @@ export async function promptDefaultModel(
|
||||
workspaceDir: params.workspaceDir,
|
||||
});
|
||||
if (applied.defaultModel) {
|
||||
await runExtensionHostProviderModelSelectedHook({
|
||||
await runProviderModelSelectedHook({
|
||||
config: applied.config,
|
||||
model: applied.defaultModel,
|
||||
prompter: params.prompter,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { AnyAgentTool } from "../../agents/tools/common.js";
|
||||
import type { PluginRecord } from "../../plugins/registry.js";
|
||||
import type { PluginRuntime } from "../../plugins/runtime/types.js";
|
||||
import type {
|
||||
@@ -31,7 +32,7 @@ export function createExtensionHostPluginApi(params: {
|
||||
config: OpenClawPluginApi["config"];
|
||||
pluginConfig?: Record<string, unknown>;
|
||||
registerTool: (
|
||||
tool: OpenClawPluginToolFactory | { name: string },
|
||||
tool: OpenClawPluginToolFactory | AnyAgentTool,
|
||||
opts?: { name?: string; names?: string[]; optional?: boolean },
|
||||
) => void;
|
||||
registerHook: (
|
||||
|
||||
@@ -24,7 +24,13 @@ export const EXTENSION_HOST_EMBEDDING_RUNTIME_BACKEND_IDS = [
|
||||
export function isExtensionHostEmbeddingRuntimeBackendAutoSelectable(
|
||||
backendId: EmbeddingProviderId,
|
||||
): boolean {
|
||||
return backendId === "local" || EXTENSION_HOST_REMOTE_EMBEDDING_PROVIDER_IDS.includes(backendId);
|
||||
return (
|
||||
backendId === "local" ||
|
||||
backendId === "openai" ||
|
||||
backendId === "gemini" ||
|
||||
backendId === "voyage" ||
|
||||
backendId === "mistral"
|
||||
);
|
||||
}
|
||||
|
||||
export function resolveExtensionHostEmbeddingRuntimeDefaultModel(
|
||||
|
||||
@@ -3,7 +3,17 @@ import type { ProviderPlugin } from "../plugins/types.js";
|
||||
import { listExtensionHostProviderRegistrations } from "./runtime-registry.js";
|
||||
|
||||
export function resolveExtensionHostProviders(params: {
|
||||
registry: Pick<PluginRegistry, "providers">;
|
||||
registry: Pick<
|
||||
PluginRegistry,
|
||||
| "channels"
|
||||
| "tools"
|
||||
| "providers"
|
||||
| "cliRegistrars"
|
||||
| "commands"
|
||||
| "services"
|
||||
| "httpRoutes"
|
||||
| "gatewayHandlers"
|
||||
>;
|
||||
}): ProviderPlugin[] {
|
||||
return listExtensionHostProviderRegistrations(params.registry).map((entry) => ({
|
||||
...entry.provider,
|
||||
|
||||
@@ -110,10 +110,13 @@ export function resolveExtensionToolRegistration(params: {
|
||||
names.push(params.tool.name);
|
||||
}
|
||||
const normalizedNames = normalizeNameList(names);
|
||||
const factory: OpenClawPluginToolFactory =
|
||||
typeof params.tool === "function"
|
||||
? params.tool
|
||||
: (_ctx: OpenClawPluginToolContext) => params.tool;
|
||||
let factory: OpenClawPluginToolFactory;
|
||||
if (typeof params.tool === "function") {
|
||||
factory = params.tool;
|
||||
} else {
|
||||
const tool = params.tool;
|
||||
factory = (_ctx: OpenClawPluginToolContext) => tool;
|
||||
}
|
||||
|
||||
return {
|
||||
names: normalizedNames,
|
||||
|
||||
@@ -44,7 +44,18 @@ function isOptionalToolAllowed(params: {
|
||||
}
|
||||
|
||||
export function resolveExtensionHostPluginTools(params: {
|
||||
registry: Pick<PluginRegistry, "tools" | "diagnostics">;
|
||||
registry: Pick<
|
||||
PluginRegistry,
|
||||
| "channels"
|
||||
| "tools"
|
||||
| "providers"
|
||||
| "cliRegistrars"
|
||||
| "commands"
|
||||
| "services"
|
||||
| "httpRoutes"
|
||||
| "gatewayHandlers"
|
||||
| "diagnostics"
|
||||
>;
|
||||
context: OpenClawPluginToolContext;
|
||||
existingToolNames?: Set<string>;
|
||||
toolAllowlist?: string[];
|
||||
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
supportsExtensionHostTtsTelephony,
|
||||
} from "./tts-runtime-registry.js";
|
||||
|
||||
const TELEGRAM_OUTPUT = {
|
||||
const TELEGRAM_OUTPUT: ExtensionHostTtsOutputFormat = {
|
||||
openai: "opus" as const,
|
||||
// ElevenLabs output formats use codec_sample_rate_bitrate naming.
|
||||
// Opus @ 48kHz/64kbps is a good voice-note tradeoff for Telegram.
|
||||
@@ -27,7 +27,7 @@ const TELEGRAM_OUTPUT = {
|
||||
voiceCompatible: true,
|
||||
};
|
||||
|
||||
const DEFAULT_OUTPUT = {
|
||||
const DEFAULT_OUTPUT: ExtensionHostTtsOutputFormat = {
|
||||
openai: "mp3" as const,
|
||||
elevenlabs: "mp3_44100_128",
|
||||
extension: ".mp3",
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { MAX_EXTENSION_HOST_REGISTRY_CACHE_ENTRIES } from "../extension-host/activation/loader-cache.js";
|
||||
import {
|
||||
listPluginSdkAliasCandidates,
|
||||
listPluginSdkExportedSubpaths,
|
||||
@@ -33,79 +37,18 @@ import type {
|
||||
|
||||
export type PluginLoadResult = PluginRegistry;
|
||||
|
||||
export type PluginLoadOptions = ExtensionHostPluginLoadOptions;
|
||||
export type PluginLoadOptions =
|
||||
import("../extension-host/activation/loader-orchestrator.js").ExtensionHostPluginLoadOptions;
|
||||
|
||||
export function clearPluginLoaderCache(): void {
|
||||
clearExtensionHostLoaderState();
|
||||
}
|
||||
|
||||
const defaultLogger = () => createSubsystemLogger("plugins");
|
||||
|
||||
type PluginSdkAliasCandidateKind = "dist" | "src";
|
||||
|
||||
function resolvePluginSdkAliasCandidateOrder(params: {
|
||||
modulePath: string;
|
||||
isProduction: boolean;
|
||||
}): PluginSdkAliasCandidateKind[] {
|
||||
const normalizedModulePath = params.modulePath.replace(/\\/g, "/");
|
||||
const isDistRuntime = normalizedModulePath.includes("/dist/");
|
||||
return isDistRuntime || params.isProduction ? ["dist", "src"] : ["src", "dist"];
|
||||
export function loadOpenClawPlugins(options: PluginLoadOptions = {}): PluginRegistry {
|
||||
return loadExtensionHostPluginRegistry(options);
|
||||
}
|
||||
|
||||
function listPluginSdkAliasCandidates(params: {
|
||||
srcFile: string;
|
||||
distFile: string;
|
||||
modulePath: string;
|
||||
}) {
|
||||
const orderedKinds = resolvePluginSdkAliasCandidateOrder({
|
||||
modulePath: params.modulePath,
|
||||
isProduction: process.env.NODE_ENV === "production",
|
||||
});
|
||||
let cursor = path.dirname(params.modulePath);
|
||||
const candidates: string[] = [];
|
||||
for (let i = 0; i < 6; i += 1) {
|
||||
const candidateMap = {
|
||||
src: path.join(cursor, "src", "plugin-sdk", params.srcFile),
|
||||
dist: path.join(cursor, "dist", "plugin-sdk", params.distFile),
|
||||
} as const;
|
||||
for (const kind of orderedKinds) {
|
||||
candidates.push(candidateMap[kind]);
|
||||
}
|
||||
const parent = path.dirname(cursor);
|
||||
if (parent === cursor) {
|
||||
break;
|
||||
}
|
||||
cursor = parent;
|
||||
}
|
||||
return candidates;
|
||||
}
|
||||
|
||||
const resolvePluginSdkAliasFile = (params: {
|
||||
srcFile: string;
|
||||
distFile: string;
|
||||
modulePath?: string;
|
||||
}): string | null => {
|
||||
try {
|
||||
const modulePath = params.modulePath ?? fileURLToPath(import.meta.url);
|
||||
for (const candidate of listPluginSdkAliasCandidates({
|
||||
srcFile: params.srcFile,
|
||||
distFile: params.distFile,
|
||||
modulePath,
|
||||
})) {
|
||||
if (fs.existsSync(candidate)) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const resolvePluginSdkAlias = (): string | null =>
|
||||
resolvePluginSdkAliasFile({ srcFile: "root-alias.cjs", distFile: "root-alias.cjs" });
|
||||
|
||||
const resolveExtensionApiAlias = (params: { modulePath?: string } = {}): string | null => {
|
||||
function resolveExtensionApiAlias(params: { modulePath?: string } = {}): string | null {
|
||||
try {
|
||||
const modulePath = params.modulePath ?? fileURLToPath(import.meta.url);
|
||||
const packageRoot = resolveOpenClawPackageRootSync({
|
||||
@@ -133,53 +76,8 @@ const resolveExtensionApiAlias = (params: { modulePath?: string } = {}): string
|
||||
// ignore
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const cachedPluginSdkExportedSubpaths = new Map<string, string[]>();
|
||||
|
||||
function listPluginSdkExportedSubpaths(params: { modulePath?: string } = {}): string[] {
|
||||
const modulePath = params.modulePath ?? fileURLToPath(import.meta.url);
|
||||
const packageRoot = resolveOpenClawPackageRootSync({
|
||||
cwd: path.dirname(modulePath),
|
||||
});
|
||||
if (!packageRoot) {
|
||||
return [];
|
||||
}
|
||||
const cached = cachedPluginSdkExportedSubpaths.get(packageRoot);
|
||||
if (cached) {
|
||||
return cached;
|
||||
}
|
||||
try {
|
||||
const pkgRaw = fs.readFileSync(path.join(packageRoot, "package.json"), "utf-8");
|
||||
const pkg = JSON.parse(pkgRaw) as {
|
||||
exports?: Record<string, unknown>;
|
||||
};
|
||||
const subpaths = Object.keys(pkg.exports ?? {})
|
||||
.filter((key) => key.startsWith("./plugin-sdk/"))
|
||||
.map((key) => key.slice("./plugin-sdk/".length))
|
||||
.filter((subpath) => Boolean(subpath) && !subpath.includes("/"))
|
||||
.toSorted();
|
||||
cachedPluginSdkExportedSubpaths.set(packageRoot, subpaths);
|
||||
return subpaths;
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
const resolvePluginSdkScopedAliasMap = (): Record<string, string> => {
|
||||
const aliasMap: Record<string, string> = {};
|
||||
for (const subpath of listPluginSdkExportedSubpaths()) {
|
||||
const resolved = resolvePluginSdkAliasFile({
|
||||
srcFile: `${subpath}.ts`,
|
||||
distFile: `${subpath}.js`,
|
||||
});
|
||||
if (resolved) {
|
||||
aliasMap[`openclaw/plugin-sdk/${subpath}`] = resolved;
|
||||
}
|
||||
}
|
||||
return aliasMap;
|
||||
};
|
||||
|
||||
export const __testing = {
|
||||
listPluginSdkAliasCandidates,
|
||||
listPluginSdkExportedSubpaths,
|
||||
|
||||
@@ -12,18 +12,12 @@ import { findOverlappingPluginHttpRoute } from "./http-route-overlap.js";
|
||||
import { registerPluginInteractiveHandler } from "./interactive.js";
|
||||
import { normalizeRegisteredProvider } from "./provider-validation.js";
|
||||
import type { PluginRuntime } from "./runtime/types.js";
|
||||
import { defaultSlotIdForKey } from "./slots.js";
|
||||
import {
|
||||
isPromptInjectionHookName,
|
||||
stripPromptMutationFieldsFromLegacyHookResult,
|
||||
} from "./types.js";
|
||||
import type {
|
||||
OpenClawPluginCliRegistrar,
|
||||
OpenClawPluginCommandDefinition,
|
||||
OpenClawPluginHttpRouteAuth,
|
||||
OpenClawPluginHttpRouteMatch,
|
||||
OpenClawPluginHttpRouteHandler,
|
||||
ProviderPlugin,
|
||||
OpenClawPluginHttpRouteMatch,
|
||||
OpenClawPluginService,
|
||||
OpenClawPluginToolFactory,
|
||||
PluginConfigUiHint,
|
||||
@@ -32,8 +26,8 @@ import type {
|
||||
PluginFormat,
|
||||
PluginLogger,
|
||||
PluginOrigin,
|
||||
PluginKind,
|
||||
PluginHookRegistration as TypedPluginHookRegistration,
|
||||
ProviderPlugin,
|
||||
} from "./types.js";
|
||||
|
||||
export type PluginToolRegistration = {
|
||||
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
import {
|
||||
getExtensionHostTtsMaxLength,
|
||||
isExtensionHostTtsEnabled,
|
||||
resolveExtensionHostTtsAutoMode,
|
||||
isExtensionHostTtsSummarizationEnabled,
|
||||
resolveExtensionHostTtsPrefsPath,
|
||||
setExtensionHostTtsAutoMode,
|
||||
@@ -49,6 +50,7 @@ import {
|
||||
summarizeText,
|
||||
} from "./tts-core.js";
|
||||
export { OPENAI_TTS_MODELS, OPENAI_TTS_VOICES } from "./tts-core.js";
|
||||
export type { ResolvedTtsConfig } from "../extension-host/tts-config.js";
|
||||
|
||||
export type TtsDirectiveOverrides = {
|
||||
ttsText?: string;
|
||||
@@ -103,6 +105,8 @@ export const resolveTtsConfig = resolveExtensionHostTtsConfig;
|
||||
|
||||
export const resolveTtsPrefsPath = resolveExtensionHostTtsPrefsPath;
|
||||
|
||||
export const resolveTtsAutoMode = resolveExtensionHostTtsAutoMode;
|
||||
|
||||
export const buildTtsSystemPromptHint = buildExtensionHostTtsSystemPromptHint;
|
||||
|
||||
export const isTtsEnabled = isExtensionHostTtsEnabled;
|
||||
|
||||
Reference in New Issue
Block a user