





















@@ -2,6 +2,7 @@ import fs from "node:fs";
22import os from "node:os";
33import path from "node:path";
44import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
5+import type { OpenClawConfig } from "../config/types.openclaw.js";
56import {
67clearCurrentPluginMetadataSnapshot,
78resolvePluginMetadataControlPlaneFingerprint,
@@ -11,6 +12,7 @@ import { resolveInstalledPluginIndexPolicyHash } from "./installed-plugin-index-
1112import type { InstalledPluginIndex } from "./installed-plugin-index.js";
1213import { listOpenClawPluginManifestMetadata } from "./manifest-metadata-scan.js";
1314import { normalizeProviderModelIdWithManifest } from "./manifest-model-id-normalization.js";
15+import { clearPluginMetadataLifecycleCaches } from "./plugin-metadata-lifecycle.js";
1416import type { PluginMetadataSnapshot } from "./plugin-metadata-snapshot.js";
1517import { createEmptyPluginRegistry } from "./registry-empty.js";
1618import { resetPluginRuntimeStateForTest, setActivePluginRegistry } from "./runtime.js";
@@ -87,8 +89,10 @@ function createCurrentSnapshot(params: {
8789manifestHash: string;
8890prefix: string;
8991workspaceDir?: string;
92+config?: OpenClawConfig;
9093}): PluginMetadataSnapshot {
91-const policyHash = resolveInstalledPluginIndexPolicyHash({});
94+const config = params.config ?? {};
95+const policyHash = resolveInstalledPluginIndexPolicyHash(config);
9296const index: InstalledPluginIndex = {
9397version: 1,
9498hostContractVersion: "test-host",
@@ -119,15 +123,12 @@ function createCurrentSnapshot(params: {
119123};
120124return {
121125 policyHash,
122-configFingerprint: resolvePluginMetadataControlPlaneFingerprint(
123-{},
124-{
125-env: process.env,
126- index,
127- policyHash,
128-workspaceDir: params.workspaceDir,
129-},
130-),
126+configFingerprint: resolvePluginMetadataControlPlaneFingerprint(config, {
127+env: process.env,
128+ index,
129+ policyHash,
130+workspaceDir: params.workspaceDir,
131+}),
131132workspaceDir: params.workspaceDir,
132133 index,
133134registryDiagnostics: [],
@@ -153,6 +154,17 @@ function normalizeDemoModel(modelId = "demo-model"): string | undefined {
153154});
154155}
155156157+function normalizeDemoModelWithEnv(
158+env: NodeJS.ProcessEnv,
159+modelId = "demo-model",
160+): string | undefined {
161+return normalizeProviderModelIdWithManifest({
162+provider: "demo",
163+ env,
164+context: { provider: "demo", modelId },
165+});
166+}
167+156168describe("manifest model id normalization", () => {
157169beforeEach(() => {
158170resetPluginRuntimeStateForTest();
@@ -234,6 +246,45 @@ describe("manifest model id normalization", () => {
234246expect(normalizeDemoModel()).toBe("alpha/demo-model");
235247});
236248249+it("reuses current metadata when callers omit config", () => {
250+const config: OpenClawConfig = { plugins: { allow: ["normalizer"] } };
251+setCurrentPluginMetadataSnapshot(
252+createCurrentSnapshot({
253+manifestHash: "alpha",
254+prefix: "alpha",
255+ config,
256+}),
257+{ config, env: process.env },
258+);
259+260+expect(normalizeDemoModel()).toBe("alpha/demo-model");
261+});
262+263+it("validates explicit env before reusing current metadata", () => {
264+setCurrentPluginMetadataSnapshot(
265+createCurrentSnapshot({
266+manifestHash: "alpha",
267+prefix: "alpha",
268+}),
269+{ config: {}, env: process.env },
270+);
271+272+const stateDir = makeTempDir();
273+const pluginDir = path.join(stateDir, "extensions", "normalizer");
274+writeInstallIndex({ stateDir, pluginDir });
275+writeNormalizerManifest({ pluginDir, prefix: "bravo" });
276+277+const env = {
278+ ...process.env,
279+OPENCLAW_STATE_DIR: stateDir,
280+OPENCLAW_HOME: undefined,
281+OPENCLAW_DISABLE_BUNDLED_PLUGINS: "1",
282+OPENCLAW_BUNDLED_PLUGINS_DIR: undefined,
283+};
284+285+expect(normalizeDemoModelWithEnv(env)).toBe("bravo/demo-model");
286+});
287+237288it("reflects manifest edits and state-dir changes on the next lookup", () => {
238289const stateDirA = makeTempDir();
239290const pluginDirA = path.join(stateDirA, "extensions", "normalizer");
@@ -248,6 +299,7 @@ describe("manifest model id normalization", () => {
248299expect(normalizeDemoModel()).toBe("alpha/demo-model");
249300250301writeNormalizerManifest({ pluginDir: pluginDirA, prefix: "bravo-local" });
302+clearPluginMetadataLifecycleCaches();
251303expect(normalizeDemoModel()).toBe("bravo-local/demo-model");
252304253305const stateDirB = makeTempDir();
@@ -256,6 +308,7 @@ describe("manifest model id normalization", () => {
256308writeNormalizerManifest({ pluginDir: pluginDirB, prefix: "charlie" });
257309258310process.env.OPENCLAW_STATE_DIR = stateDirB;
311+clearPluginMetadataLifecycleCaches();
259312expect(normalizeDemoModel()).toBe("charlie/demo-model");
260313});
261314此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。