mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 07:40:44 +00:00
fix(plugins): clean resolved npm load paths
This commit is contained in:
@@ -75,6 +75,7 @@ Docs: https://docs.openclaw.ai
|
||||
- OpenAI Codex: let SSRF-guarded provider requests inherit OpenClaw's undici IPv4/IPv6 fallback policy, so ChatGPT-backed Codex runs recover on IPv4-working hosts when DNS still returns unreachable IPv6 addresses. Fixes #76857. Thanks @jplavoiemtl and @SymbolStar.
|
||||
- Gateway/systemd: preserve operator-added secrets in the Gateway env file across re-stage while clearing OpenClaw-managed keys (such as `OPENCLAW_GATEWAY_TOKEN`) so a fresh staging value is never shadowed by a stale env-file copy; operator secrets are also retained when the state-dir `.env` is empty. Fixes #76860. Thanks @hclsys.
|
||||
- Plugin updates: do not short-circuit trusted official npm updates as unchanged when the default/latest spec still resolves to an already-installed prerelease that the installer should replace with a stable fallback. Thanks @vincentkoc.
|
||||
- Plugin updates: clean stale bundled load paths for already-externalized npm installs whose legacy install record only preserved the resolved package name. Thanks @vincentkoc.
|
||||
- Plugin tools: keep auth-unavailable optional tools hidden even when another default tool from the same plugin is available and `tools.alsoAllow` names the optional tool. Thanks @vincentkoc.
|
||||
- Realtime transcription: report socket closes before provider readiness as closed-before-ready failures instead of mislabeling them as connection timeouts for OpenAI, xAI, and Deepgram streaming transcription. Thanks @vincentkoc.
|
||||
- OpenAI/Google Meet: fail realtime voice connection attempts when the socket closes before `session.updated`, avoiding stuck Meet joins waiting on a bridge that never became ready. Thanks @vincentkoc.
|
||||
|
||||
@@ -2620,6 +2620,48 @@ describe("syncPluginsForUpdateChannel", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("removes stale bundled load paths for already-externalized resolved-name-only npm installs", async () => {
|
||||
resolveBundledPluginSourcesMock.mockReturnValue(new Map());
|
||||
|
||||
const result = await syncPluginsForUpdateChannel({
|
||||
channel: "stable",
|
||||
externalizedBundledPluginBridges: [
|
||||
{
|
||||
bundledPluginId: "legacy-chat",
|
||||
npmSpec: "@openclaw/legacy-chat",
|
||||
channelIds: ["legacy-chat"],
|
||||
},
|
||||
],
|
||||
config: {
|
||||
channels: {
|
||||
"legacy-chat": {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
load: {
|
||||
paths: [appBundledPluginRoot("legacy-chat"), "/workspace/plugins/other"],
|
||||
},
|
||||
installs: {
|
||||
"legacy-chat": {
|
||||
source: "npm",
|
||||
resolvedName: "@openclaw/legacy-chat",
|
||||
installPath: "/tmp/openclaw-plugins/legacy-chat",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(installPluginFromNpmSpecMock).not.toHaveBeenCalled();
|
||||
expect(result.changed).toBe(true);
|
||||
expect(result.config.plugins?.load?.paths).toEqual(["/workspace/plugins/other"]);
|
||||
expect(result.config.plugins?.installs?.["legacy-chat"]).toMatchObject({
|
||||
source: "npm",
|
||||
resolvedName: "@openclaw/legacy-chat",
|
||||
});
|
||||
});
|
||||
|
||||
it("removes stale bundled load paths for already-externalized pinned npm installs", async () => {
|
||||
resolveBundledPluginSourcesMock.mockReturnValue(new Map());
|
||||
|
||||
|
||||
@@ -580,6 +580,7 @@ function isBridgeAlreadyInstalledFromPreferredSource(params: {
|
||||
if (npmSpec && params.record.source === "npm") {
|
||||
const bridgePackageName = resolveNpmSpecPackageName(npmSpec);
|
||||
const recordPackageName =
|
||||
params.record.resolvedName ??
|
||||
resolveNpmSpecPackageName(params.record.spec) ??
|
||||
resolveNpmSpecPackageName(params.record.resolvedSpec);
|
||||
if (bridgePackageName && recordPackageName === bridgePackageName) {
|
||||
|
||||
Reference in New Issue
Block a user