

























@@ -62,6 +62,9 @@ const {
6262)[value],
6363),
6464}));
65+const { loadPluginInstallRecordsSyncMock } = vi.hoisted(() => ({
66+loadPluginInstallRecordsSyncMock: vi.fn(() => ({})),
67+}));
6568let secretResolve: typeof import("./resolve.js");
6669let createResolverContext: typeof import("./runtime-shared.js").createResolverContext;
6770let resolveRuntimeWebTools: typeof import("./runtime-web-tools.js").resolveRuntimeWebTools;
@@ -102,6 +105,16 @@ vi.mock("./runtime-web-tools-manifest.runtime.js", () => ({
102105resolveManifestContractPluginIdsByCompatibilityRuntimePathMock,
103106}));
104107108+vi.mock("../plugins/install-ledger-store.js", async () => {
109+const actual = await vi.importActual<typeof import("../plugins/install-ledger-store.js")>(
110+"../plugins/install-ledger-store.js",
111+);
112+return {
113+ ...actual,
114+loadPluginInstallRecordsSync: loadPluginInstallRecordsSyncMock,
115+};
116+});
117+105118function asConfig(value: unknown): OpenClawConfig {
106119return value as OpenClawConfig;
107120}
@@ -322,6 +335,8 @@ describe("runtime web tools resolution", () => {
322335resolveManifestContractOwnerPluginIdMock.mockClear();
323336resolveManifestContractPluginIdsMock.mockClear();
324337resolveManifestContractPluginIdsByCompatibilityRuntimePathMock.mockClear();
338+loadPluginInstallRecordsSyncMock.mockReset();
339+loadPluginInstallRecordsSyncMock.mockReturnValue({});
325340});
326341327342afterEach(() => {
@@ -1074,6 +1089,38 @@ describe("runtime web tools resolution", () => {
10741089expect(resolvePluginWebSearchProvidersMock).not.toHaveBeenCalled();
10751090});
107610911092+it("uses runtime web search discovery when the managed plugin install ledger is populated", async () => {
1093+loadPluginInstallRecordsSyncMock.mockReturnValue({
1094+"external-search": {
1095+source: "npm",
1096+spec: "@openclaw/external-search",
1097+},
1098+});
1099+1100+const { metadata } = await runRuntimeWebTools({
1101+config: asConfig({
1102+tools: {
1103+web: {
1104+search: {
1105+enabled: true,
1106+},
1107+},
1108+},
1109+}),
1110+env: {
1111+BRAVE_API_KEY: "brave-key", // pragma: allowlist secret
1112+},
1113+});
1114+1115+expect(metadata.search.selectedProvider).toBe("brave");
1116+expect(resolveBundledWebSearchProvidersFromPublicArtifactsMock).not.toHaveBeenCalled();
1117+expect(resolvePluginWebSearchProvidersMock).toHaveBeenCalledWith(
1118+expect.objectContaining({
1119+bundledAllowlistCompat: true,
1120+}),
1121+);
1122+});
1123+10771124it("uses bundled public artifacts for bundled web fetch provider discovery", async () => {
10781125const { metadata } = await runRuntimeWebTools({
10791126config: asConfig({
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。