mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-21 15:01:03 +00:00
fix(web-search): share unsupported filter handling
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { Type } from "@sinclair/typebox";
|
||||
import {
|
||||
buildSearchCacheKey,
|
||||
buildUnsupportedSearchFilterResponse,
|
||||
DEFAULT_SEARCH_COUNT,
|
||||
MAX_SEARCH_COUNT,
|
||||
readCachedSearchPayload,
|
||||
@@ -177,22 +178,9 @@ function createGeminiToolDefinition(
|
||||
parameters: createGeminiSchema(),
|
||||
execute: async (args) => {
|
||||
const params = args as Record<string, unknown>;
|
||||
for (const name of ["country", "language", "freshness", "date_after", "date_before"]) {
|
||||
if (readStringParam(params, name)) {
|
||||
const label =
|
||||
name === "country"
|
||||
? "country filtering"
|
||||
: name === "language"
|
||||
? "language filtering"
|
||||
: name === "freshness"
|
||||
? "freshness filtering"
|
||||
: "date_after/date_before filtering";
|
||||
return {
|
||||
error: name.startsWith("date_") ? "unsupported_date_filter" : `unsupported_${name}`,
|
||||
message: `${label} is not supported by the gemini provider. Only Brave and Perplexity support ${name === "country" ? "country filtering" : name === "language" ? "language filtering" : name === "freshness" ? "freshness" : "date filtering"}.`,
|
||||
docs: "https://docs.openclaw.ai/tools/web",
|
||||
};
|
||||
}
|
||||
const unsupportedResponse = buildUnsupportedSearchFilterResponse(params, "gemini");
|
||||
if (unsupportedResponse) {
|
||||
return unsupportedResponse;
|
||||
}
|
||||
|
||||
const geminiConfig = resolveGeminiConfig(searchConfig);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Type } from "@sinclair/typebox";
|
||||
import {
|
||||
buildSearchCacheKey,
|
||||
buildUnsupportedSearchFilterResponse,
|
||||
DEFAULT_SEARCH_COUNT,
|
||||
MAX_SEARCH_COUNT,
|
||||
readCachedSearchPayload,
|
||||
@@ -246,22 +247,9 @@ function createKimiToolDefinition(
|
||||
parameters: createKimiSchema(),
|
||||
execute: async (args) => {
|
||||
const params = args as Record<string, unknown>;
|
||||
for (const name of ["country", "language", "freshness", "date_after", "date_before"]) {
|
||||
if (readStringParam(params, name)) {
|
||||
const label =
|
||||
name === "country"
|
||||
? "country filtering"
|
||||
: name === "language"
|
||||
? "language filtering"
|
||||
: name === "freshness"
|
||||
? "freshness filtering"
|
||||
: "date_after/date_before filtering";
|
||||
return {
|
||||
error: name.startsWith("date_") ? "unsupported_date_filter" : `unsupported_${name}`,
|
||||
message: `${label} is not supported by the kimi provider. Only Brave and Perplexity support ${name === "country" ? "country filtering" : name === "language" ? "language filtering" : name === "freshness" ? "freshness" : "date filtering"}.`,
|
||||
docs: "https://docs.openclaw.ai/tools/web",
|
||||
};
|
||||
}
|
||||
const unsupportedResponse = buildUnsupportedSearchFilterResponse(params, "kimi");
|
||||
if (unsupportedResponse) {
|
||||
return unsupportedResponse;
|
||||
}
|
||||
|
||||
const kimiConfig = resolveKimiConfig(searchConfig);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Type } from "@sinclair/typebox";
|
||||
import {
|
||||
buildSearchCacheKey,
|
||||
buildUnsupportedSearchFilterResponse,
|
||||
DEFAULT_SEARCH_COUNT,
|
||||
MAX_SEARCH_COUNT,
|
||||
readCachedSearchPayload,
|
||||
@@ -188,22 +189,9 @@ function createGrokToolDefinition(
|
||||
parameters: createGrokSchema(),
|
||||
execute: async (args) => {
|
||||
const params = args as Record<string, unknown>;
|
||||
for (const name of ["country", "language", "freshness", "date_after", "date_before"]) {
|
||||
if (readStringParam(params, name)) {
|
||||
const label =
|
||||
name === "country"
|
||||
? "country filtering"
|
||||
: name === "language"
|
||||
? "language filtering"
|
||||
: name === "freshness"
|
||||
? "freshness filtering"
|
||||
: "date_after/date_before filtering";
|
||||
return {
|
||||
error: name.startsWith("date_") ? "unsupported_date_filter" : `unsupported_${name}`,
|
||||
message: `${label} is not supported by the grok provider. Only Brave and Perplexity support ${name === "country" ? "country filtering" : name === "language" ? "language filtering" : name === "freshness" ? "freshness" : "date filtering"}.`,
|
||||
docs: "https://docs.openclaw.ai/tools/web",
|
||||
};
|
||||
}
|
||||
const unsupportedResponse = buildUnsupportedSearchFilterResponse(params, "grok");
|
||||
if (unsupportedResponse) {
|
||||
return unsupportedResponse;
|
||||
}
|
||||
|
||||
const grokConfig = resolveGrokConfig(searchConfig);
|
||||
|
||||
@@ -21,6 +21,13 @@ export type SearchConfigRecord = (NonNullable<OpenClawConfig["tools"]>["web"] ex
|
||||
: never) &
|
||||
Record<string, unknown>;
|
||||
|
||||
type UnsupportedWebSearchFilterName =
|
||||
| "country"
|
||||
| "language"
|
||||
| "freshness"
|
||||
| "date_after"
|
||||
| "date_before";
|
||||
|
||||
export const DEFAULT_SEARCH_COUNT = 5;
|
||||
export const MAX_SEARCH_COUNT = 10;
|
||||
|
||||
@@ -210,3 +217,59 @@ export function writeCachedSearchPayload(
|
||||
): void {
|
||||
writeCache(SEARCH_CACHE, cacheKey, payload, ttlMs);
|
||||
}
|
||||
|
||||
function readUnsupportedSearchFilter(
|
||||
params: Record<string, unknown>,
|
||||
): UnsupportedWebSearchFilterName | undefined {
|
||||
for (const name of ["country", "language", "freshness", "date_after", "date_before"] as const) {
|
||||
const value = params[name];
|
||||
if (typeof value === "string" && value.trim()) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function describeUnsupportedSearchFilter(name: UnsupportedWebSearchFilterName): string {
|
||||
switch (name) {
|
||||
case "country":
|
||||
return "country filtering";
|
||||
case "language":
|
||||
return "language filtering";
|
||||
case "freshness":
|
||||
return "freshness filtering";
|
||||
case "date_after":
|
||||
case "date_before":
|
||||
return "date_after/date_before filtering";
|
||||
}
|
||||
}
|
||||
|
||||
export function buildUnsupportedSearchFilterResponse(
|
||||
params: Record<string, unknown>,
|
||||
provider: string,
|
||||
docs = "https://docs.openclaw.ai/tools/web",
|
||||
):
|
||||
| {
|
||||
error: string;
|
||||
message: string;
|
||||
docs: string;
|
||||
}
|
||||
| undefined {
|
||||
const unsupported = readUnsupportedSearchFilter(params);
|
||||
if (!unsupported) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const label = describeUnsupportedSearchFilter(unsupported);
|
||||
const supportedLabel =
|
||||
unsupported === "date_after" || unsupported === "date_before" ? "date filtering" : label;
|
||||
|
||||
return {
|
||||
error: unsupported.startsWith("date_")
|
||||
? "unsupported_date_filter"
|
||||
: `unsupported_${unsupported}`,
|
||||
message: `${label} is not supported by the ${provider} provider. Only Brave and Perplexity support ${supportedLabel}.`,
|
||||
docs,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { __testing as braveTesting } from "../../../extensions/brave/src/brave-w
|
||||
import { __testing as moonshotTesting } from "../../../extensions/moonshot/src/kimi-web-search-provider.js";
|
||||
import { __testing as perplexityTesting } from "../../../extensions/perplexity/web-search-provider.js";
|
||||
import { __testing as xaiTesting } from "../../../extensions/xai/src/grok-web-search-provider.js";
|
||||
import { buildUnsupportedSearchFilterResponse } from "../../plugin-sdk/provider-web-search.js";
|
||||
import { withEnv } from "../../test-utils/env.js";
|
||||
const {
|
||||
inferPerplexityBaseUrlFromApiKey,
|
||||
@@ -198,6 +199,30 @@ describe("web_search date normalization", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("web_search unsupported filter response", () => {
|
||||
it("returns undefined when no unsupported filter is set", () => {
|
||||
expect(buildUnsupportedSearchFilterResponse({ query: "openclaw" }, "gemini")).toBeUndefined();
|
||||
});
|
||||
|
||||
it("maps non-date filters to provider-specific unsupported errors", () => {
|
||||
expect(buildUnsupportedSearchFilterResponse({ country: "us" }, "grok")).toEqual({
|
||||
error: "unsupported_country",
|
||||
message:
|
||||
"country filtering is not supported by the grok provider. Only Brave and Perplexity support country filtering.",
|
||||
docs: "https://docs.openclaw.ai/tools/web",
|
||||
});
|
||||
});
|
||||
|
||||
it("collapses date filters to unsupported_date_filter", () => {
|
||||
expect(buildUnsupportedSearchFilterResponse({ date_before: "2026-03-19" }, "kimi")).toEqual({
|
||||
error: "unsupported_date_filter",
|
||||
message:
|
||||
"date_after/date_before filtering is not supported by the kimi provider. Only Brave and Perplexity support date filtering.",
|
||||
docs: "https://docs.openclaw.ai/tools/web",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("web_search kimi config resolution", () => {
|
||||
it("uses config apiKey when provided", () => {
|
||||
expect(resolveKimiApiKey({ apiKey: "kimi-test-key" })).toBe("kimi-test-key");
|
||||
|
||||
@@ -9,6 +9,7 @@ export { readNumberParam, readStringArrayParam, readStringParam } from "../agent
|
||||
export { resolveCitationRedirectUrl } from "../agents/tools/web-search-citation-redirect.js";
|
||||
export {
|
||||
buildSearchCacheKey,
|
||||
buildUnsupportedSearchFilterResponse,
|
||||
DEFAULT_SEARCH_COUNT,
|
||||
FRESHNESS_TO_RECENCY,
|
||||
isoToPerplexityDate,
|
||||
|
||||
Reference in New Issue
Block a user