mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 15:28:27 +00:00
refactor(agent): dedupe harness and command workflows
This commit is contained in:
@@ -1,6 +1,34 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { createWebFetchTool, createWebSearchTool } from "./web-tools.js";
|
||||
|
||||
function installMockFetch(payload: unknown) {
|
||||
const mockFetch = vi.fn(() =>
|
||||
Promise.resolve({
|
||||
ok: true,
|
||||
json: () => Promise.resolve(payload),
|
||||
} as Response),
|
||||
);
|
||||
// @ts-expect-error mock fetch
|
||||
global.fetch = mockFetch;
|
||||
return mockFetch;
|
||||
}
|
||||
|
||||
function createPerplexitySearchTool(perplexityConfig?: { apiKey?: string; baseUrl?: string }) {
|
||||
return createWebSearchTool({
|
||||
config: {
|
||||
tools: {
|
||||
web: {
|
||||
search: {
|
||||
provider: "perplexity",
|
||||
...(perplexityConfig ? { perplexity: perplexityConfig } : {}),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
sandboxed: true,
|
||||
});
|
||||
}
|
||||
|
||||
describe("web tools defaults", () => {
|
||||
it("enables web_fetch by default (non-sandbox)", () => {
|
||||
const tool = createWebFetchTool({ config: {}, sandboxed: false });
|
||||
@@ -35,15 +63,7 @@ describe("web_search country and language parameters", () => {
|
||||
});
|
||||
|
||||
it("should pass country parameter to Brave API", async () => {
|
||||
const mockFetch = vi.fn(() =>
|
||||
Promise.resolve({
|
||||
ok: true,
|
||||
json: () => Promise.resolve({ web: { results: [] } }),
|
||||
} as Response),
|
||||
);
|
||||
// @ts-expect-error mock fetch
|
||||
global.fetch = mockFetch;
|
||||
|
||||
const mockFetch = installMockFetch({ web: { results: [] } });
|
||||
const tool = createWebSearchTool({ config: undefined, sandboxed: true });
|
||||
expect(tool).not.toBeNull();
|
||||
|
||||
@@ -55,15 +75,7 @@ describe("web_search country and language parameters", () => {
|
||||
});
|
||||
|
||||
it("should pass search_lang parameter to Brave API", async () => {
|
||||
const mockFetch = vi.fn(() =>
|
||||
Promise.resolve({
|
||||
ok: true,
|
||||
json: () => Promise.resolve({ web: { results: [] } }),
|
||||
} as Response),
|
||||
);
|
||||
// @ts-expect-error mock fetch
|
||||
global.fetch = mockFetch;
|
||||
|
||||
const mockFetch = installMockFetch({ web: { results: [] } });
|
||||
const tool = createWebSearchTool({ config: undefined, sandboxed: true });
|
||||
await tool?.execute?.(1, { query: "test", search_lang: "de" });
|
||||
|
||||
@@ -72,15 +84,7 @@ describe("web_search country and language parameters", () => {
|
||||
});
|
||||
|
||||
it("should pass ui_lang parameter to Brave API", async () => {
|
||||
const mockFetch = vi.fn(() =>
|
||||
Promise.resolve({
|
||||
ok: true,
|
||||
json: () => Promise.resolve({ web: { results: [] } }),
|
||||
} as Response),
|
||||
);
|
||||
// @ts-expect-error mock fetch
|
||||
global.fetch = mockFetch;
|
||||
|
||||
const mockFetch = installMockFetch({ web: { results: [] } });
|
||||
const tool = createWebSearchTool({ config: undefined, sandboxed: true });
|
||||
await tool?.execute?.(1, { query: "test", ui_lang: "de" });
|
||||
|
||||
@@ -89,15 +93,7 @@ describe("web_search country and language parameters", () => {
|
||||
});
|
||||
|
||||
it("should pass freshness parameter to Brave API", async () => {
|
||||
const mockFetch = vi.fn(() =>
|
||||
Promise.resolve({
|
||||
ok: true,
|
||||
json: () => Promise.resolve({ web: { results: [] } }),
|
||||
} as Response),
|
||||
);
|
||||
// @ts-expect-error mock fetch
|
||||
global.fetch = mockFetch;
|
||||
|
||||
const mockFetch = installMockFetch({ web: { results: [] } });
|
||||
const tool = createWebSearchTool({ config: undefined, sandboxed: true });
|
||||
await tool?.execute?.(1, { query: "test", freshness: "pw" });
|
||||
|
||||
@@ -106,15 +102,7 @@ describe("web_search country and language parameters", () => {
|
||||
});
|
||||
|
||||
it("rejects invalid freshness values", async () => {
|
||||
const mockFetch = vi.fn(() =>
|
||||
Promise.resolve({
|
||||
ok: true,
|
||||
json: () => Promise.resolve({ web: { results: [] } }),
|
||||
} as Response),
|
||||
);
|
||||
// @ts-expect-error mock fetch
|
||||
global.fetch = mockFetch;
|
||||
|
||||
const mockFetch = installMockFetch({ web: { results: [] } });
|
||||
const tool = createWebSearchTool({ config: undefined, sandboxed: true });
|
||||
const result = await tool?.execute?.(1, { query: "test", freshness: "yesterday" });
|
||||
|
||||
@@ -134,19 +122,11 @@ describe("web_search perplexity baseUrl defaults", () => {
|
||||
|
||||
it("defaults to Perplexity direct when PERPLEXITY_API_KEY is set", async () => {
|
||||
vi.stubEnv("PERPLEXITY_API_KEY", "pplx-test");
|
||||
const mockFetch = vi.fn(() =>
|
||||
Promise.resolve({
|
||||
ok: true,
|
||||
json: () => Promise.resolve({ choices: [{ message: { content: "ok" } }], citations: [] }),
|
||||
} as Response),
|
||||
);
|
||||
// @ts-expect-error mock fetch
|
||||
global.fetch = mockFetch;
|
||||
|
||||
const tool = createWebSearchTool({
|
||||
config: { tools: { web: { search: { provider: "perplexity" } } } },
|
||||
sandboxed: true,
|
||||
const mockFetch = installMockFetch({
|
||||
choices: [{ message: { content: "ok" } }],
|
||||
citations: [],
|
||||
});
|
||||
const tool = createPerplexitySearchTool();
|
||||
await tool?.execute?.(1, { query: "test-openrouter" });
|
||||
|
||||
expect(mockFetch).toHaveBeenCalled();
|
||||
@@ -161,19 +141,11 @@ describe("web_search perplexity baseUrl defaults", () => {
|
||||
|
||||
it("passes freshness to Perplexity provider as search_recency_filter", async () => {
|
||||
vi.stubEnv("PERPLEXITY_API_KEY", "pplx-test");
|
||||
const mockFetch = vi.fn(() =>
|
||||
Promise.resolve({
|
||||
ok: true,
|
||||
json: () => Promise.resolve({ choices: [{ message: { content: "ok" } }], citations: [] }),
|
||||
} as Response),
|
||||
);
|
||||
// @ts-expect-error mock fetch
|
||||
global.fetch = mockFetch;
|
||||
|
||||
const tool = createWebSearchTool({
|
||||
config: { tools: { web: { search: { provider: "perplexity" } } } },
|
||||
sandboxed: true,
|
||||
const mockFetch = installMockFetch({
|
||||
choices: [{ message: { content: "ok" } }],
|
||||
citations: [],
|
||||
});
|
||||
const tool = createPerplexitySearchTool();
|
||||
await tool?.execute?.(1, { query: "perplexity-freshness-test", freshness: "pw" });
|
||||
|
||||
expect(mockFetch).toHaveBeenCalledOnce();
|
||||
@@ -184,19 +156,11 @@ describe("web_search perplexity baseUrl defaults", () => {
|
||||
it("defaults to OpenRouter when OPENROUTER_API_KEY is set", async () => {
|
||||
vi.stubEnv("PERPLEXITY_API_KEY", "");
|
||||
vi.stubEnv("OPENROUTER_API_KEY", "sk-or-test");
|
||||
const mockFetch = vi.fn(() =>
|
||||
Promise.resolve({
|
||||
ok: true,
|
||||
json: () => Promise.resolve({ choices: [{ message: { content: "ok" } }], citations: [] }),
|
||||
} as Response),
|
||||
);
|
||||
// @ts-expect-error mock fetch
|
||||
global.fetch = mockFetch;
|
||||
|
||||
const tool = createWebSearchTool({
|
||||
config: { tools: { web: { search: { provider: "perplexity" } } } },
|
||||
sandboxed: true,
|
||||
const mockFetch = installMockFetch({
|
||||
choices: [{ message: { content: "ok" } }],
|
||||
citations: [],
|
||||
});
|
||||
const tool = createPerplexitySearchTool();
|
||||
await tool?.execute?.(1, { query: "test-openrouter-env" });
|
||||
|
||||
expect(mockFetch).toHaveBeenCalled();
|
||||
@@ -212,19 +176,11 @@ describe("web_search perplexity baseUrl defaults", () => {
|
||||
it("prefers PERPLEXITY_API_KEY when both env keys are set", async () => {
|
||||
vi.stubEnv("PERPLEXITY_API_KEY", "pplx-test");
|
||||
vi.stubEnv("OPENROUTER_API_KEY", "sk-or-test");
|
||||
const mockFetch = vi.fn(() =>
|
||||
Promise.resolve({
|
||||
ok: true,
|
||||
json: () => Promise.resolve({ choices: [{ message: { content: "ok" } }], citations: [] }),
|
||||
} as Response),
|
||||
);
|
||||
// @ts-expect-error mock fetch
|
||||
global.fetch = mockFetch;
|
||||
|
||||
const tool = createWebSearchTool({
|
||||
config: { tools: { web: { search: { provider: "perplexity" } } } },
|
||||
sandboxed: true,
|
||||
const mockFetch = installMockFetch({
|
||||
choices: [{ message: { content: "ok" } }],
|
||||
citations: [],
|
||||
});
|
||||
const tool = createPerplexitySearchTool();
|
||||
await tool?.execute?.(1, { query: "test-both-env" });
|
||||
|
||||
expect(mockFetch).toHaveBeenCalled();
|
||||
@@ -233,28 +189,11 @@ describe("web_search perplexity baseUrl defaults", () => {
|
||||
|
||||
it("uses configured baseUrl even when PERPLEXITY_API_KEY is set", async () => {
|
||||
vi.stubEnv("PERPLEXITY_API_KEY", "pplx-test");
|
||||
const mockFetch = vi.fn(() =>
|
||||
Promise.resolve({
|
||||
ok: true,
|
||||
json: () => Promise.resolve({ choices: [{ message: { content: "ok" } }], citations: [] }),
|
||||
} as Response),
|
||||
);
|
||||
// @ts-expect-error mock fetch
|
||||
global.fetch = mockFetch;
|
||||
|
||||
const tool = createWebSearchTool({
|
||||
config: {
|
||||
tools: {
|
||||
web: {
|
||||
search: {
|
||||
provider: "perplexity",
|
||||
perplexity: { baseUrl: "https://example.com/pplx" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
sandboxed: true,
|
||||
const mockFetch = installMockFetch({
|
||||
choices: [{ message: { content: "ok" } }],
|
||||
citations: [],
|
||||
});
|
||||
const tool = createPerplexitySearchTool({ baseUrl: "https://example.com/pplx" });
|
||||
await tool?.execute?.(1, { query: "test-config-baseurl" });
|
||||
|
||||
expect(mockFetch).toHaveBeenCalled();
|
||||
@@ -262,28 +201,11 @@ describe("web_search perplexity baseUrl defaults", () => {
|
||||
});
|
||||
|
||||
it("defaults to Perplexity direct when apiKey looks like Perplexity", async () => {
|
||||
const mockFetch = vi.fn(() =>
|
||||
Promise.resolve({
|
||||
ok: true,
|
||||
json: () => Promise.resolve({ choices: [{ message: { content: "ok" } }], citations: [] }),
|
||||
} as Response),
|
||||
);
|
||||
// @ts-expect-error mock fetch
|
||||
global.fetch = mockFetch;
|
||||
|
||||
const tool = createWebSearchTool({
|
||||
config: {
|
||||
tools: {
|
||||
web: {
|
||||
search: {
|
||||
provider: "perplexity",
|
||||
perplexity: { apiKey: "pplx-config" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
sandboxed: true,
|
||||
const mockFetch = installMockFetch({
|
||||
choices: [{ message: { content: "ok" } }],
|
||||
citations: [],
|
||||
});
|
||||
const tool = createPerplexitySearchTool({ apiKey: "pplx-config" });
|
||||
await tool?.execute?.(1, { query: "test-config-apikey" });
|
||||
|
||||
expect(mockFetch).toHaveBeenCalled();
|
||||
@@ -291,28 +213,11 @@ describe("web_search perplexity baseUrl defaults", () => {
|
||||
});
|
||||
|
||||
it("defaults to OpenRouter when apiKey looks like OpenRouter", async () => {
|
||||
const mockFetch = vi.fn(() =>
|
||||
Promise.resolve({
|
||||
ok: true,
|
||||
json: () => Promise.resolve({ choices: [{ message: { content: "ok" } }], citations: [] }),
|
||||
} as Response),
|
||||
);
|
||||
// @ts-expect-error mock fetch
|
||||
global.fetch = mockFetch;
|
||||
|
||||
const tool = createWebSearchTool({
|
||||
config: {
|
||||
tools: {
|
||||
web: {
|
||||
search: {
|
||||
provider: "perplexity",
|
||||
perplexity: { apiKey: "sk-or-v1-test" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
sandboxed: true,
|
||||
const mockFetch = installMockFetch({
|
||||
choices: [{ message: { content: "ok" } }],
|
||||
citations: [],
|
||||
});
|
||||
const tool = createPerplexitySearchTool({ apiKey: "sk-or-v1-test" });
|
||||
await tool?.execute?.(1, { query: "test-openrouter-config" });
|
||||
|
||||
expect(mockFetch).toHaveBeenCalled();
|
||||
|
||||
Reference in New Issue
Block a user