mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
fix: validate firecrawl numeric options
This commit is contained in:
@@ -2,7 +2,8 @@ import { optionalStringEnum } from "openclaw/plugin-sdk/channel-actions";
|
||||
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-runtime";
|
||||
import {
|
||||
jsonResult,
|
||||
readNumberParam,
|
||||
readNonNegativeIntegerParam,
|
||||
readPositiveIntegerParam,
|
||||
readStringParam,
|
||||
} from "openclaw/plugin-sdk/provider-web-search";
|
||||
import { Type } from "typebox";
|
||||
@@ -60,11 +61,9 @@ export function createFirecrawlScrapeTool(api: OpenClawPluginApi) {
|
||||
const url = readStringParam(rawParams, "url", { required: true });
|
||||
const extractMode =
|
||||
readStringParam(rawParams, "extractMode") === "text" ? "text" : "markdown";
|
||||
const maxChars = readNumberParam(rawParams, "maxChars", { positiveInteger: true });
|
||||
const maxAgeMs = readNumberParam(rawParams, "maxAgeMs", { nonNegativeInteger: true });
|
||||
const timeoutSeconds = readNumberParam(rawParams, "timeoutSeconds", {
|
||||
positiveInteger: true,
|
||||
});
|
||||
const maxChars = readPositiveIntegerParam(rawParams, "maxChars");
|
||||
const maxAgeMs = readNonNegativeIntegerParam(rawParams, "maxAgeMs");
|
||||
const timeoutSeconds = readPositiveIntegerParam(rawParams, "timeoutSeconds");
|
||||
const proxyRaw = readStringParam(rawParams, "proxy");
|
||||
const proxy =
|
||||
proxyRaw === "basic" || proxyRaw === "stealth" || proxyRaw === "auto"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-runtime";
|
||||
import {
|
||||
jsonResult,
|
||||
readNumberParam,
|
||||
readPositiveIntegerParam,
|
||||
readStringArrayParam,
|
||||
readStringParam,
|
||||
} from "openclaw/plugin-sdk/provider-web-search";
|
||||
@@ -52,10 +52,11 @@ export function createFirecrawlSearchTool(api: OpenClawPluginApi) {
|
||||
parameters: FirecrawlSearchToolSchema,
|
||||
execute: async (_toolCallId: string, rawParams: Record<string, unknown>) => {
|
||||
const query = readStringParam(rawParams, "query", { required: true });
|
||||
const count = readNumberParam(rawParams, "count", { positiveInteger: true });
|
||||
const timeoutSeconds = readNumberParam(rawParams, "timeoutSeconds", {
|
||||
positiveInteger: true,
|
||||
const count = readPositiveIntegerParam(rawParams, "count", {
|
||||
max: 10,
|
||||
message: "count must be an integer from 1 to 10",
|
||||
});
|
||||
const timeoutSeconds = readPositiveIntegerParam(rawParams, "timeoutSeconds");
|
||||
const sources = readStringArrayParam(rawParams, "sources");
|
||||
const categories = readStringArrayParam(rawParams, "categories");
|
||||
const scrapeResults = rawParams.scrapeResults === true;
|
||||
|
||||
@@ -489,47 +489,52 @@ describe("firecrawl tools", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("drops malformed numeric Firecrawl tool options", async () => {
|
||||
it("rejects malformed numeric Firecrawl search options before dispatch", async () => {
|
||||
const searchTool = createFirecrawlSearchTool({
|
||||
config: { env: "test" },
|
||||
} as never);
|
||||
await searchTool.execute("call-search", {
|
||||
query: "web search",
|
||||
count: 6.5,
|
||||
timeoutSeconds: Number.POSITIVE_INFINITY,
|
||||
});
|
||||
|
||||
expect(runFirecrawlSearch).toHaveBeenLastCalledWith({
|
||||
cfg: { env: "test" },
|
||||
query: "web search",
|
||||
count: undefined,
|
||||
timeoutSeconds: undefined,
|
||||
sources: undefined,
|
||||
categories: undefined,
|
||||
scrapeResults: false,
|
||||
});
|
||||
await expect(
|
||||
searchTool.execute("call-search", {
|
||||
query: "web search",
|
||||
count: 6.5,
|
||||
}),
|
||||
).rejects.toThrow("count must be an integer from 1 to 10");
|
||||
await expect(
|
||||
searchTool.execute("call-search-timeout", {
|
||||
query: "web search",
|
||||
timeoutSeconds: Number.POSITIVE_INFINITY,
|
||||
}),
|
||||
).rejects.toThrow("timeoutSeconds must be a positive integer");
|
||||
|
||||
expect(runFirecrawlSearch).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("rejects malformed numeric Firecrawl scrape options before dispatch", async () => {
|
||||
const scrapeTool = createFirecrawlScrapeTool({
|
||||
config: { env: "test" },
|
||||
} as never);
|
||||
await scrapeTool.execute("call-scrape", {
|
||||
url: "https://docs.openclaw.ai",
|
||||
maxChars: 1500.5,
|
||||
maxAgeMs: -1,
|
||||
timeoutSeconds: 22.5,
|
||||
});
|
||||
|
||||
expect(runFirecrawlScrape).toHaveBeenLastCalledWith({
|
||||
cfg: { env: "test" },
|
||||
url: "https://docs.openclaw.ai",
|
||||
extractMode: "markdown",
|
||||
maxChars: undefined,
|
||||
onlyMainContent: undefined,
|
||||
maxAgeMs: undefined,
|
||||
proxy: undefined,
|
||||
storeInCache: undefined,
|
||||
timeoutSeconds: undefined,
|
||||
});
|
||||
await expect(
|
||||
scrapeTool.execute("call-scrape-max-chars", {
|
||||
url: "https://docs.openclaw.ai",
|
||||
maxChars: 1500.5,
|
||||
}),
|
||||
).rejects.toThrow("maxChars must be a positive integer");
|
||||
await expect(
|
||||
scrapeTool.execute("call-scrape-max-age", {
|
||||
url: "https://docs.openclaw.ai",
|
||||
maxAgeMs: -1,
|
||||
}),
|
||||
).rejects.toThrow("maxAgeMs must be a non-negative integer");
|
||||
await expect(
|
||||
scrapeTool.execute("call-scrape-timeout", {
|
||||
url: "https://docs.openclaw.ai",
|
||||
timeoutSeconds: 22.5,
|
||||
}),
|
||||
).rejects.toThrow("timeoutSeconds must be a positive integer");
|
||||
|
||||
expect(runFirecrawlScrape).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("passes text mode through and ignores invalid proxy values", async () => {
|
||||
|
||||
Reference in New Issue
Block a user