feat(tools): add Brave LLM Context API mode for web_search#19298
feat(tools): add Brave LLM Context API mode for web_search#19298RoccoFortuna wants to merge 6 commits intoopenclaw:mainfrom
Conversation
Add support for Brave's /res/v1/llm/context endpoint as a configurable mode within the existing Brave web search provider. The LLM Context API returns pre-extracted, relevance-scored web content (full text snippets, tables, code blocks) optimized for LLM consumption. Configuration: - tools.web.search.brave.mode: "llm-context" (default: "web") - tools.web.search.brave.llmContext.maxTokens (1024-32768) - tools.web.search.brave.llmContext.maxUrls (1-50) - tools.web.search.brave.llmContext.thresholdMode (strict/balanced/lenient/disabled) - tools.web.search.brave.llmContext.maxSnippets (1-100) - tools.web.search.brave.llmContext.maxTokensPerUrl (512-8192) - tools.web.search.brave.llmContext.maxSnippetsPerUrl (1-100) Uses the same API key as standard Brave search. Freshness param is rejected in llm-context mode (unsupported by the endpoint). Closes openclaw#14992
|
Pipeline failures don't seem related? CI Test Failures Analysis1. Job 63908368023 - Telegram Media Group Buffering TestFailure: Root Cause: Timing issue in the media group buffering test. The Fix: Increase the sleep duration to allow the async buffering logic to complete: - await sleep(TELEGRAM_TEST_TIMINGS.mediaGroupFlushMs + 80);
+ await sleep(TELEGRAM_TEST_TIMINGS.mediaGroupFlushMs + 200);Location: 2. Job 63908367965 - Slack Allow List Resolution ErrorFailure: Root Cause: Fix: Update export async function resolveSlackEffectiveAllowFrom(ctx: SlackMonitorContext) {
- const storeAllowFrom = await readChannelAllowFromStore("slack").catch(() => []);
+ let storeAllowFrom: string[] = [];
+ try {
+ const result = await readChannelAllowFromStore("slack");
+ storeAllowFrom = result ?? [];
+ } catch {
+ storeAllowFrom = [];
+ }
const allowFrom = normalizeAllowList([...ctx.allowFrom, ...storeAllowFrom]);
const allowFromLower = normalizeAllowListLower(allowFrom);
return { allowFrom, allowFromLower };
}Location: Secondary Issues: Multiple test failures in |
|
This pull request has been automatically marked as stale due to inactivity. |
Summary
/res/v1/llm/context) that returns pre-extracted, relevance-scored web content optimized for LLM consumption, but OpenClaw only supports the standard web search endpoint.brave.modeandbrave.llmContextconfig, a newrunBraveLlmContextSearch()function, and llm-context branches inrunWebSearch()/createWebSearchTool().braveconfig block = existing behavior, zero breaking changes.AI-assisted (Claude Code). Fully tested locally (unit, integration, and live API). I understand what the code does.
This is my first PR on the repo - any feedback on code style, structure, or approach is very welcome. Happy to iterate!
Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
User-visible / Behavior Changes
tools.web.search.brave.mode("web"|"llm-context") andtools.web.search.brave.llmContext.*(maxTokens, maxUrls, thresholdMode, maxSnippets, maxTokensPerUrl, maxSnippetsPerUrl).freshnessparameter returns an error when used in llm-context mode (unsupported by the endpoint).content(joined snippets) instead ofdescription, plusmode,sourceCountfields.Security Impact (required)
NoNo- reuses existingBRAVE_API_KEY/tools.web.search.apiKeyYes- new GET requests tohttps://api.search.brave.com/res/v1/llm/contextNo- sameweb_searchtool, same parametersNoX-Subscription-Token), and all response content is wrapped withwrapWebContent()(matching the existing security pattern for titles and snippet content).Repro + Verification
Environment
tools.web.search.provider: "brave"withbrave.mode: "llm-context"Steps
tools.web.search.brave.mode: "llm-context"in configweb_searchtool with a querymode: "llm-context",contentfields with joined snippetsExpected
Actual
Evidence
Live API tested with Brave Search subscription key:
Human Verification (required)
Compatibility / Migration
YesYes- new optional config keys undertools.web.search.brave.*No- no config = existing behavior unchangedFailure Recovery (if this breaks)
tools.web.search.braveconfig block, or setbrave.mode: "web"to revert to standard Brave web search.Risks and Mitigations
Configuration
Greptile Summary
Adds Brave LLM Context API mode to
web_searchtool, providing pre-extracted LLM-optimized content alongside the existing standard web search. Implementation follows established patterns for provider-specific config (similar to Perplexity/Grok), properly validates config with Zod schemas, and includes comprehensive test coverage (unit, integration, and config validation tests).Key changes:
brave.modeconfig ("web"|"llm-context") with backward compatibility (defaults to"web")runBraveLlmContextSearch()function mirrors standard Brave search structure with proper error handling and content wrappingwrapWebContent()for security consistencyConfidence Score: 5/5
readResponseText, validates inputs with Zod schemas (strict mode), wraps all external content for security, maintains backward compatibility (no config = existing behavior), and differentiates cache keys between modes to prevent pollution.Last reviewed commit: 0cf4da6
(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!