


























@@ -0,0 +1,144 @@
1+import { beforeEach, describe, expect, it, vi } from "vitest";
2+3+const mocks = vi.hoisted(() => ({
4+getActiveRuntimeWebToolsMetadata: vi.fn(),
5+getActiveSecretsRuntimeSnapshot: vi.fn(),
6+resolveManifestContractOwnerPluginId: vi.fn(),
7+}));
8+9+vi.mock("../../plugins/plugin-registry.js", () => ({
10+resolveManifestContractOwnerPluginId: mocks.resolveManifestContractOwnerPluginId,
11+}));
12+13+vi.mock("../../secrets/runtime-web-tools-state.js", () => ({
14+getActiveRuntimeWebToolsMetadata: mocks.getActiveRuntimeWebToolsMetadata,
15+}));
16+17+vi.mock("../../secrets/runtime.js", () => ({
18+getActiveSecretsRuntimeSnapshot: mocks.getActiveSecretsRuntimeSnapshot,
19+}));
20+21+describe("web tool runtime context", () => {
22+beforeEach(() => {
23+mocks.getActiveRuntimeWebToolsMetadata.mockReset();
24+mocks.getActiveRuntimeWebToolsMetadata.mockReturnValue(null);
25+mocks.getActiveSecretsRuntimeSnapshot.mockReset();
26+mocks.getActiveSecretsRuntimeSnapshot.mockReturnValue(null);
27+mocks.resolveManifestContractOwnerPluginId.mockReset();
28+mocks.resolveManifestContractOwnerPluginId.mockReturnValue(undefined);
29+});
30+31+it("late-binds search config and metadata from active runtime before captured options", async () => {
32+const runtimeConfig = {
33+tools: { web: { search: { provider: "perplexity" } } },
34+};
35+mocks.getActiveSecretsRuntimeSnapshot.mockReturnValue({ config: runtimeConfig });
36+mocks.getActiveRuntimeWebToolsMetadata.mockReturnValue({
37+search: {
38+providerConfigured: "perplexity",
39+providerSource: "configured",
40+selectedProvider: "perplexity",
41+selectedProviderKeySource: "config",
42+diagnostics: [],
43+},
44+fetch: {
45+providerSource: "none",
46+diagnostics: [],
47+},
48+diagnostics: [],
49+});
50+const { resolveWebSearchToolRuntimeContext } = await import("./web-tool-runtime-context.js");
51+52+const resolved = resolveWebSearchToolRuntimeContext({
53+config: { tools: { web: { search: { provider: "brave" } } } },
54+lateBindRuntimeConfig: true,
55+runtimeWebSearch: {
56+providerConfigured: "brave",
57+providerSource: "configured",
58+selectedProvider: "brave",
59+selectedProviderKeySource: "config",
60+diagnostics: [],
61+},
62+});
63+64+expect(resolved.config).toBe(runtimeConfig);
65+expect(resolved.runtimeWebSearch).toMatchObject({ selectedProvider: "perplexity" });
66+expect(mocks.resolveManifestContractOwnerPluginId).toHaveBeenCalledWith(
67+expect.objectContaining({
68+contract: "webSearchProviders",
69+value: "perplexity",
70+}),
71+);
72+});
73+74+it("falls back to captured search config and runtime metadata when active globals are missing", async () => {
75+const capturedConfig = {
76+tools: { web: { search: { provider: "brave" } } },
77+};
78+const { resolveWebSearchToolRuntimeContext } = await import("./web-tool-runtime-context.js");
79+80+const resolved = resolveWebSearchToolRuntimeContext({
81+config: capturedConfig,
82+lateBindRuntimeConfig: true,
83+runtimeWebSearch: {
84+providerConfigured: "brave",
85+providerSource: "configured",
86+selectedProvider: "brave",
87+selectedProviderKeySource: "config",
88+diagnostics: [],
89+},
90+});
91+92+expect(resolved.config).toBe(capturedConfig);
93+expect(resolved.runtimeWebSearch).toMatchObject({ selectedProvider: "brave" });
94+expect(mocks.resolveManifestContractOwnerPluginId).toHaveBeenCalledWith(
95+expect.objectContaining({
96+contract: "webSearchProviders",
97+value: "brave",
98+}),
99+);
100+});
101+102+it("uses configured provider ids when runtime metadata is absent", async () => {
103+const { resolveWebSearchToolRuntimeContext } = await import("./web-tool-runtime-context.js");
104+105+resolveWebSearchToolRuntimeContext({
106+config: { tools: { web: { search: { provider: "Brave" } } } },
107+});
108+109+expect(mocks.resolveManifestContractOwnerPluginId).toHaveBeenCalledWith(
110+expect.objectContaining({
111+contract: "webSearchProviders",
112+value: "brave",
113+}),
114+);
115+});
116+117+it("keeps runtime providers disabled for bundled fetch owners", async () => {
118+mocks.resolveManifestContractOwnerPluginId.mockReturnValue("firecrawl");
119+const { resolveWebFetchToolRuntimeContext } = await import("./web-tool-runtime-context.js");
120+121+const resolved = resolveWebFetchToolRuntimeContext({
122+config: { tools: { web: { fetch: { provider: "firecrawl" } } } },
123+});
124+125+expect(resolved.preferRuntimeProviders).toBe(false);
126+expect(mocks.resolveManifestContractOwnerPluginId).toHaveBeenCalledWith(
127+expect.objectContaining({
128+contract: "webFetchProviders",
129+value: "firecrawl",
130+}),
131+);
132+});
133+134+it("keeps runtime provider discovery enabled when no provider is selected", async () => {
135+const { resolveWebFetchToolRuntimeContext } = await import("./web-tool-runtime-context.js");
136+137+const resolved = resolveWebFetchToolRuntimeContext({
138+config: {},
139+});
140+141+expect(resolved.preferRuntimeProviders).toBe(true);
142+expect(mocks.resolveManifestContractOwnerPluginId).not.toHaveBeenCalled();
143+});
144+});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。