mirror of
http://192.168.0.88:13333/lywsvip/openclaw-zero-token.git
synced 2026-06-03 15:40:59 +08:00
Major upgrade from e26988a38 to upstream v2026.3.28 (f9b107928).
Key changes:
- Upstream src/, ui/, extensions/ (89 bundled extensions)
- Zero-token web providers preserved in src/zero-token/
- AskOnce plugin restored and registered as CLI command
- Added missing packages: @anthropic-ai/vertex-sdk, @modelcontextprotocol/sdk
- Fixed tsconfig rootDir, skipLibCheck for plugin-sdk DTS build
- Added askonce to bundled plugin metadata and package.json exports
- Fixed AskOnce CLI command registration (missing commands metadata)
- Restored AskOnce adapter imports (correct 5-level relative paths)
- Removed stale migration artifacts from root directory
193 lines
5.6 KiB
TypeScript
193 lines
5.6 KiB
TypeScript
import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../../agents/agent-scope.js";
|
|
import {
|
|
getChannelPluginCatalogEntry,
|
|
listChannelPluginCatalogEntries,
|
|
type ChannelPluginCatalogEntry,
|
|
} from "../../channels/plugins/catalog.js";
|
|
import { getChannelPlugin, normalizeChannelId } from "../../channels/plugins/index.js";
|
|
import type { ChannelId, ChannelPlugin } from "../../channels/plugins/types.js";
|
|
import type { OpenClawConfig } from "../../config/config.js";
|
|
import type { RuntimeEnv } from "../../runtime.js";
|
|
import { createClackPrompter } from "../../wizard/clack-prompter.js";
|
|
import type { WizardPrompter } from "../../wizard/prompts.js";
|
|
import {
|
|
ensureChannelSetupPluginInstalled,
|
|
loadChannelSetupPluginRegistrySnapshotForChannel,
|
|
} from "./plugin-install.js";
|
|
|
|
type ChannelPluginSnapshot = {
|
|
channels: Array<{ plugin: ChannelPlugin }>;
|
|
channelSetups: Array<{ plugin: ChannelPlugin }>;
|
|
};
|
|
|
|
type ResolveInstallableChannelPluginResult = {
|
|
cfg: OpenClawConfig;
|
|
channelId?: ChannelId;
|
|
plugin?: ChannelPlugin;
|
|
catalogEntry?: ChannelPluginCatalogEntry;
|
|
configChanged: boolean;
|
|
};
|
|
|
|
function resolveWorkspaceDir(cfg: OpenClawConfig) {
|
|
return resolveAgentWorkspaceDir(cfg, resolveDefaultAgentId(cfg));
|
|
}
|
|
|
|
function resolveResolvedChannelId(params: {
|
|
rawChannel?: string | null;
|
|
catalogEntry?: ChannelPluginCatalogEntry;
|
|
}): ChannelId | undefined {
|
|
const normalized = normalizeChannelId(params.rawChannel);
|
|
if (normalized) {
|
|
return normalized;
|
|
}
|
|
if (!params.catalogEntry) {
|
|
return undefined;
|
|
}
|
|
return normalizeChannelId(params.catalogEntry.id) ?? (params.catalogEntry.id as ChannelId);
|
|
}
|
|
|
|
export function resolveCatalogChannelEntry(raw: string, cfg: OpenClawConfig | null) {
|
|
const trimmed = raw.trim().toLowerCase();
|
|
if (!trimmed) {
|
|
return undefined;
|
|
}
|
|
const workspaceDir = cfg ? resolveWorkspaceDir(cfg) : undefined;
|
|
return listChannelPluginCatalogEntries({ workspaceDir }).find((entry) => {
|
|
if (entry.id.toLowerCase() === trimmed) {
|
|
return true;
|
|
}
|
|
return (entry.meta.aliases ?? []).some((alias) => alias.trim().toLowerCase() === trimmed);
|
|
});
|
|
}
|
|
|
|
function findScopedChannelPlugin(
|
|
snapshot: ChannelPluginSnapshot,
|
|
channelId: ChannelId,
|
|
): ChannelPlugin | undefined {
|
|
return (
|
|
snapshot.channels.find((entry) => entry.plugin.id === channelId)?.plugin ??
|
|
snapshot.channelSetups.find((entry) => entry.plugin.id === channelId)?.plugin
|
|
);
|
|
}
|
|
|
|
function loadScopedChannelPlugin(params: {
|
|
cfg: OpenClawConfig;
|
|
runtime: RuntimeEnv;
|
|
channelId: ChannelId;
|
|
pluginId?: string;
|
|
workspaceDir?: string;
|
|
}): ChannelPlugin | undefined {
|
|
const snapshot = loadChannelSetupPluginRegistrySnapshotForChannel({
|
|
cfg: params.cfg,
|
|
runtime: params.runtime,
|
|
channel: params.channelId,
|
|
...(params.pluginId ? { pluginId: params.pluginId } : {}),
|
|
workspaceDir: params.workspaceDir,
|
|
});
|
|
return findScopedChannelPlugin(snapshot, params.channelId);
|
|
}
|
|
|
|
export async function resolveInstallableChannelPlugin(params: {
|
|
cfg: OpenClawConfig;
|
|
runtime: RuntimeEnv;
|
|
rawChannel?: string | null;
|
|
channelId?: ChannelId;
|
|
allowInstall?: boolean;
|
|
prompter?: WizardPrompter;
|
|
supports?: (plugin: ChannelPlugin) => boolean;
|
|
}): Promise<ResolveInstallableChannelPluginResult> {
|
|
const supports = params.supports ?? (() => true);
|
|
let nextCfg = params.cfg;
|
|
const workspaceDir = resolveWorkspaceDir(nextCfg);
|
|
const catalogEntry =
|
|
(params.rawChannel ? resolveCatalogChannelEntry(params.rawChannel, nextCfg) : undefined) ??
|
|
(params.channelId
|
|
? getChannelPluginCatalogEntry(params.channelId, {
|
|
workspaceDir,
|
|
})
|
|
: undefined);
|
|
const channelId =
|
|
params.channelId ??
|
|
resolveResolvedChannelId({
|
|
rawChannel: params.rawChannel,
|
|
catalogEntry,
|
|
});
|
|
if (!channelId) {
|
|
return {
|
|
cfg: nextCfg,
|
|
catalogEntry,
|
|
configChanged: false,
|
|
};
|
|
}
|
|
|
|
const existing = getChannelPlugin(channelId);
|
|
if (existing && supports(existing)) {
|
|
return {
|
|
cfg: nextCfg,
|
|
channelId,
|
|
plugin: existing,
|
|
catalogEntry,
|
|
configChanged: false,
|
|
};
|
|
}
|
|
|
|
const resolvedPluginId = catalogEntry?.pluginId;
|
|
if (catalogEntry) {
|
|
const scoped = loadScopedChannelPlugin({
|
|
cfg: nextCfg,
|
|
runtime: params.runtime,
|
|
channelId,
|
|
pluginId: resolvedPluginId,
|
|
workspaceDir,
|
|
});
|
|
if (scoped && supports(scoped)) {
|
|
return {
|
|
cfg: nextCfg,
|
|
channelId,
|
|
plugin: scoped,
|
|
catalogEntry,
|
|
configChanged: false,
|
|
};
|
|
}
|
|
|
|
if (params.allowInstall !== false) {
|
|
const installResult = await ensureChannelSetupPluginInstalled({
|
|
cfg: nextCfg,
|
|
entry: catalogEntry,
|
|
prompter: params.prompter ?? createClackPrompter(),
|
|
runtime: params.runtime,
|
|
workspaceDir,
|
|
});
|
|
nextCfg = installResult.cfg;
|
|
const installedPluginId = installResult.pluginId ?? resolvedPluginId;
|
|
const installedPlugin = installResult.installed
|
|
? loadScopedChannelPlugin({
|
|
cfg: nextCfg,
|
|
runtime: params.runtime,
|
|
channelId,
|
|
pluginId: installedPluginId,
|
|
workspaceDir: resolveWorkspaceDir(nextCfg),
|
|
})
|
|
: undefined;
|
|
return {
|
|
cfg: nextCfg,
|
|
channelId,
|
|
plugin: installedPlugin ?? existing,
|
|
catalogEntry:
|
|
installedPluginId && catalogEntry.pluginId !== installedPluginId
|
|
? { ...catalogEntry, pluginId: installedPluginId }
|
|
: catalogEntry,
|
|
configChanged: nextCfg !== params.cfg,
|
|
};
|
|
}
|
|
}
|
|
|
|
return {
|
|
cfg: nextCfg,
|
|
channelId,
|
|
plugin: existing,
|
|
catalogEntry,
|
|
configChanged: false,
|
|
};
|
|
}
|