mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-27 12:56:01 -06:00
refactor(perplexity): unify search option validation (#129877)
This commit is contained in:
committed by
GitHub
parent
aa2643d6d3
commit
87ff446588
@@ -6,7 +6,7 @@ import {
|
||||
isoToPerplexityDate,
|
||||
MAX_SEARCH_COUNT,
|
||||
normalizeFreshness,
|
||||
normalizeToIsoDate,
|
||||
parseWebSearchTimeFilters,
|
||||
readCachedSearchPayload,
|
||||
readConfiguredSecretString,
|
||||
readPositiveIntegerParam,
|
||||
@@ -361,45 +361,26 @@ export async function executePerplexitySearch(
|
||||
});
|
||||
|
||||
if (!structured) {
|
||||
if (country) {
|
||||
return {
|
||||
error: "unsupported_country",
|
||||
message:
|
||||
"country filtering is only supported by the native Perplexity Search API path. Remove Perplexity baseUrl/model overrides or use a direct PERPLEXITY_API_KEY to enable it.",
|
||||
docs: "https://docs.openclaw.ai/tools/web",
|
||||
};
|
||||
}
|
||||
if (language) {
|
||||
return {
|
||||
error: "unsupported_language",
|
||||
message:
|
||||
"language filtering is only supported by the native Perplexity Search API path. Remove Perplexity baseUrl/model overrides or use a direct PERPLEXITY_API_KEY to enable it.",
|
||||
docs: "https://docs.openclaw.ai/tools/web",
|
||||
};
|
||||
}
|
||||
if (rawDateAfter || rawDateBefore) {
|
||||
return {
|
||||
error: "unsupported_date_filter",
|
||||
message:
|
||||
"date_after/date_before are only supported by the native Perplexity Search API path. Remove Perplexity baseUrl/model overrides or use a direct PERPLEXITY_API_KEY to enable them.",
|
||||
docs: "https://docs.openclaw.ai/tools/web",
|
||||
};
|
||||
}
|
||||
if (domainFilter?.length) {
|
||||
return {
|
||||
error: "unsupported_domain_filter",
|
||||
message:
|
||||
"domain_filter is only supported by the native Perplexity Search API path. Remove Perplexity baseUrl/model overrides or use a direct PERPLEXITY_API_KEY to enable it.",
|
||||
docs: "https://docs.openclaw.ai/tools/web",
|
||||
};
|
||||
}
|
||||
if (maxTokens !== undefined || maxTokensPerPage !== undefined) {
|
||||
return {
|
||||
error: "unsupported_content_budget",
|
||||
message:
|
||||
"max_tokens and max_tokens_per_page are only supported by the native Perplexity Search API path. Remove Perplexity baseUrl/model overrides or use a direct PERPLEXITY_API_KEY to enable them.",
|
||||
docs: "https://docs.openclaw.ai/tools/web",
|
||||
};
|
||||
const unsupportedOptions = [
|
||||
[country, "unsupported_country", "country filtering", "it"],
|
||||
[language, "unsupported_language", "language filtering", "it"],
|
||||
[rawDateAfter || rawDateBefore, "unsupported_date_filter", "date_after/date_before", "them"],
|
||||
[domainFilter?.length, "unsupported_domain_filter", "domain_filter", "it"],
|
||||
[
|
||||
maxTokens !== undefined || maxTokensPerPage !== undefined,
|
||||
"unsupported_content_budget",
|
||||
"max_tokens and max_tokens_per_page",
|
||||
"them",
|
||||
],
|
||||
] as const;
|
||||
for (const [value, error, option, pronoun] of unsupportedOptions) {
|
||||
if (value) {
|
||||
return {
|
||||
error,
|
||||
message: `${option} ${pronoun === "them" ? "are" : "is"} only supported by the native Perplexity Search API path. Remove Perplexity baseUrl/model overrides or use a direct PERPLEXITY_API_KEY to enable ${pronoun}.`,
|
||||
docs: "https://docs.openclaw.ai/tools/web",
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -410,37 +391,20 @@ export async function executePerplexitySearch(
|
||||
docs: "https://docs.openclaw.ai/tools/web",
|
||||
};
|
||||
}
|
||||
if (rawFreshness && (rawDateAfter || rawDateBefore)) {
|
||||
return {
|
||||
error: "conflicting_time_filters",
|
||||
message:
|
||||
"freshness and date_after/date_before cannot be used together. Use either freshness (day/week/month/year) or a date range (date_after/date_before), not both.",
|
||||
docs: "https://docs.openclaw.ai/tools/web",
|
||||
};
|
||||
}
|
||||
const dateAfter = rawDateAfter ? normalizeToIsoDate(rawDateAfter) : undefined;
|
||||
const dateBefore = rawDateBefore ? normalizeToIsoDate(rawDateBefore) : undefined;
|
||||
if (rawDateAfter && !dateAfter) {
|
||||
return {
|
||||
error: "invalid_date",
|
||||
message: "date_after must be YYYY-MM-DD format.",
|
||||
docs: "https://docs.openclaw.ai/tools/web",
|
||||
};
|
||||
}
|
||||
if (rawDateBefore && !dateBefore) {
|
||||
return {
|
||||
error: "invalid_date",
|
||||
message: "date_before must be YYYY-MM-DD format.",
|
||||
docs: "https://docs.openclaw.ai/tools/web",
|
||||
};
|
||||
}
|
||||
if (dateAfter && dateBefore && dateAfter > dateBefore) {
|
||||
return {
|
||||
error: "invalid_date_range",
|
||||
message: "date_after must be before date_before.",
|
||||
docs: "https://docs.openclaw.ai/tools/web",
|
||||
};
|
||||
const parsedTimeFilters = parseWebSearchTimeFilters({
|
||||
rawFreshness,
|
||||
rawDateAfter,
|
||||
rawDateBefore,
|
||||
freshnessProvider: "perplexity",
|
||||
invalidFreshnessMessage: "freshness must be day, week, month, or year.",
|
||||
invalidDateAfterMessage: "date_after must be YYYY-MM-DD format.",
|
||||
invalidDateBeforeMessage: "date_before must be YYYY-MM-DD format.",
|
||||
invalidDateRangeMessage: "date_after must be before date_before.",
|
||||
});
|
||||
if ("error" in parsedTimeFilters) {
|
||||
return parsedTimeFilters;
|
||||
}
|
||||
const { dateAfter, dateBefore } = parsedTimeFilters;
|
||||
if (domainFilter?.length) {
|
||||
const hasDeny = domainFilter.some((entry) => entry.startsWith("-"));
|
||||
const hasAllow = domainFilter.some((entry) => !entry.startsWith("-"));
|
||||
|
||||
@@ -69,6 +69,149 @@ describe("perplexity web search provider", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it.each([
|
||||
{
|
||||
name: "country before every other unsupported chat option",
|
||||
structured: false,
|
||||
args: {
|
||||
country: "US",
|
||||
language: "en",
|
||||
date_after: "2024-01-01",
|
||||
domain_filter: ["a.test"],
|
||||
max_tokens: 1,
|
||||
},
|
||||
error: "unsupported_country",
|
||||
message:
|
||||
"country filtering is only supported by the native Perplexity Search API path. Remove Perplexity baseUrl/model overrides or use a direct PERPLEXITY_API_KEY to enable it.",
|
||||
},
|
||||
{
|
||||
name: "language before unsupported chat dates, domains, and budget",
|
||||
structured: false,
|
||||
args: { language: "en", date_after: "2024-01-01", domain_filter: ["a.test"], max_tokens: 1 },
|
||||
error: "unsupported_language",
|
||||
message:
|
||||
"language filtering is only supported by the native Perplexity Search API path. Remove Perplexity baseUrl/model overrides or use a direct PERPLEXITY_API_KEY to enable it.",
|
||||
},
|
||||
{
|
||||
name: "date before unsupported chat domains and budget",
|
||||
structured: false,
|
||||
args: { date_after: "2024-01-01", domain_filter: ["a.test"], max_tokens: 1 },
|
||||
error: "unsupported_date_filter",
|
||||
message:
|
||||
"date_after/date_before are only supported by the native Perplexity Search API path. Remove Perplexity baseUrl/model overrides or use a direct PERPLEXITY_API_KEY to enable them.",
|
||||
},
|
||||
{
|
||||
name: "unsupported chat language before language validation and dates",
|
||||
structured: false,
|
||||
args: { language: "invalid", date_after: "2024-01-01" },
|
||||
error: "unsupported_language",
|
||||
message:
|
||||
"language filtering is only supported by the native Perplexity Search API path. Remove Perplexity baseUrl/model overrides or use a direct PERPLEXITY_API_KEY to enable it.",
|
||||
},
|
||||
{
|
||||
name: "unsupported chat date before a valid freshness conflict",
|
||||
structured: false,
|
||||
args: { freshness: "day", date_after: "2024-01-01" },
|
||||
error: "unsupported_date_filter",
|
||||
message:
|
||||
"date_after/date_before are only supported by the native Perplexity Search API path. Remove Perplexity baseUrl/model overrides or use a direct PERPLEXITY_API_KEY to enable them.",
|
||||
},
|
||||
{
|
||||
name: "domain before unsupported chat content budget",
|
||||
structured: false,
|
||||
args: { domain_filter: ["a.test"], max_tokens: 1 },
|
||||
error: "unsupported_domain_filter",
|
||||
message:
|
||||
"domain_filter is only supported by the native Perplexity Search API path. Remove Perplexity baseUrl/model overrides or use a direct PERPLEXITY_API_KEY to enable it.",
|
||||
},
|
||||
{
|
||||
name: "unsupported chat content budget",
|
||||
structured: false,
|
||||
args: { max_tokens_per_page: 1 },
|
||||
error: "unsupported_content_budget",
|
||||
message:
|
||||
"max_tokens and max_tokens_per_page are only supported by the native Perplexity Search API path. Remove Perplexity baseUrl/model overrides or use a direct PERPLEXITY_API_KEY to enable them.",
|
||||
},
|
||||
{
|
||||
name: "invalid freshness before reading an invalid native budget",
|
||||
structured: true,
|
||||
args: { freshness: "invalid", max_tokens: 0 },
|
||||
error: "invalid_freshness",
|
||||
message: "freshness must be day, week, month, or year.",
|
||||
},
|
||||
{
|
||||
name: "invalid freshness before reading an invalid chat budget",
|
||||
structured: false,
|
||||
args: { freshness: "invalid", country: "US", max_tokens: 0 },
|
||||
error: "invalid_freshness",
|
||||
message: "freshness must be day, week, month, or year.",
|
||||
},
|
||||
{
|
||||
name: "invalid native language before conflicting date filters",
|
||||
structured: true,
|
||||
args: { language: "invalid", freshness: "day", date_after: "invalid" },
|
||||
error: "invalid_language",
|
||||
message: "language must be a 2-letter ISO 639-1 code like 'en', 'de', or 'fr'.",
|
||||
},
|
||||
{
|
||||
name: "conflicting freshness before invalid date format",
|
||||
structured: true,
|
||||
args: { freshness: "day", date_after: "invalid" },
|
||||
error: "conflicting_time_filters",
|
||||
message:
|
||||
"freshness and date_after/date_before cannot be used together. Use either freshness (day/week/month/year) or a date range (date_after/date_before), not both.",
|
||||
},
|
||||
{
|
||||
name: "invalid date_after before invalid date_before",
|
||||
structured: true,
|
||||
args: { date_after: "invalid", date_before: "also-invalid" },
|
||||
error: "invalid_date",
|
||||
message: "date_after must be YYYY-MM-DD format.",
|
||||
},
|
||||
{
|
||||
name: "invalid date_before after valid date_after",
|
||||
structured: true,
|
||||
args: { date_after: "2024-01-01", date_before: "invalid" },
|
||||
error: "invalid_date",
|
||||
message: "date_before must be YYYY-MM-DD format.",
|
||||
},
|
||||
{
|
||||
name: "invalid chronological date range",
|
||||
structured: true,
|
||||
args: { date_after: "2024-06-01", date_before: "2024-01-01" },
|
||||
error: "invalid_date_range",
|
||||
message: "date_after must be before date_before.",
|
||||
},
|
||||
{
|
||||
name: "invalid date before mixed native domain filters",
|
||||
structured: true,
|
||||
args: { date_after: "invalid", domain_filter: ["allowed.test", "-denied.test"] },
|
||||
error: "invalid_date",
|
||||
message: "date_after must be YYYY-MM-DD format.",
|
||||
},
|
||||
])(
|
||||
"preserves provider validation precedence: $name",
|
||||
async ({ structured, args, error, message }) => {
|
||||
await expect(
|
||||
createConfiguredPerplexityTool(structured).execute({ query: "validation", ...args }),
|
||||
).resolves.toEqual({
|
||||
error,
|
||||
message,
|
||||
docs: "https://docs.openclaw.ai/tools/web",
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
it("validates chat token budgets before unsupported country precedence", async () => {
|
||||
await expect(
|
||||
createConfiguredPerplexityTool(false).execute({
|
||||
query: "validation",
|
||||
country: "US",
|
||||
max_tokens: 0,
|
||||
}),
|
||||
).rejects.toThrow("max_tokens must be a positive integer.");
|
||||
});
|
||||
|
||||
it.each([
|
||||
{ name: "native Search API", webSearch: { apiKey: "pplx-test" } },
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user