@openclaw/brave-plugin 2026.9.6 → 2026.9.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/assets/icon.png CHANGED
Binary file
@@ -1,14 +1,14 @@
1
- import { buildBraveWebSearchProviderBase } from "../web-search-shared.js";
1
+ import { buildBraveWebSearchProviderBase, resolveBraveMode } from "../web-search-shared.js";
2
2
  import { isDiagnosticFlagEnabled } from "openclaw/plugin-sdk/diagnostic-flags";
3
3
  import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
4
4
  import { mergeScopedSearchConfig, resolveProviderWebSearchPluginConfig } from "openclaw/plugin-sdk/provider-web-search-config-contract";
5
- import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
5
+ import { asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
6
6
  //#region extensions/brave/src/brave-web-search-provider.ts
7
7
  /**
8
8
  * Brave web-search provider factory. It builds the agent tool definition and
9
9
  * lazy-loads HTTP execution only when a search is run.
10
10
  */
11
- const loadBraveWebSearchRuntime = createLazyRuntimeModule(() => import("./brave-web-search-provider.runtime-h1k4SAtG.mjs"));
11
+ const loadBraveWebSearchRuntime = createLazyRuntimeModule(() => import("./brave-web-search-provider.runtime-B7NtRbBA.mjs"));
12
12
  const BraveSearchSchema = {
13
13
  type: "object",
14
14
  properties: {
@@ -52,11 +52,8 @@ const BraveSearchSchema = {
52
52
  }
53
53
  }
54
54
  };
55
- function resolveBraveMode(searchConfig) {
56
- return (isRecord(searchConfig?.brave) ? searchConfig.brave : void 0)?.mode === "llm-context" ? "llm-context" : "web";
57
- }
58
55
  function createBraveToolDefinition(searchConfig, config) {
59
- const braveMode = resolveBraveMode(searchConfig);
56
+ const braveMode = resolveBraveMode(asOptionalRecord(searchConfig?.brave));
60
57
  const diagnosticsEnabled = isDiagnosticFlagEnabled("brave.http", config);
61
58
  return {
62
59
  description: braveMode === "llm-context" ? "Search the web using Brave Search LLM Context API. Returns pre-extracted page content (text chunks, tables, code blocks) optimized for LLM grounding." : "Search the web using Brave Search API. Supports region-specific and localized search via country and language parameters. Returns titles, URLs, and snippets for fast research.",
@@ -1,4 +1,5 @@
1
- import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
1
+ import { resolveBraveMode } from "../web-search-shared.js";
2
+ import { asNonArrayRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
2
3
  import { buildTimeoutAbortSignal } from "openclaw/plugin-sdk/extension-shared";
3
4
  import { assertOkOrThrowProviderError, readProviderJsonResponse } from "openclaw/plugin-sdk/provider-http";
4
5
  import { DEFAULT_SEARCH_COUNT, MAX_SEARCH_COUNT, buildSearchCacheKey, formatCliCommand, parseWebSearchTimeFilters, readCachedSearchPayload, readConfiguredSecretString, readPositiveIntegerParam, readProviderEnvValue, readStringParam, resolveSearchCacheTtlMs, resolveSearchCount, resolveSearchTimeoutSeconds, resolveSiteName, withSelfHostedWebToolsEndpoint, withTrustedWebToolsEndpoint, wrapWebContent, writeCachedSearchPayload } from "openclaw/plugin-sdk/provider-web-search";
@@ -112,41 +113,24 @@ const BRAVE_SEARCH_LANG_ALIASES = {
112
113
  };
113
114
  const BRAVE_UI_LANG_LOCALE = /^([a-z]{2})-([a-z]{2})$/i;
114
115
  function normalizeBraveSearchLang(value) {
115
- if (!value) return;
116
- const trimmed = value.trim();
117
- if (!trimmed) return;
118
- const lower = normalizeLowercaseStringOrEmpty(trimmed);
116
+ const lower = normalizeLowercaseStringOrEmpty(value);
119
117
  const canonical = BRAVE_SEARCH_LANG_ALIASES[lower] ?? lower;
120
- if (!BRAVE_SEARCH_LANG_CODES.has(canonical)) return;
121
- return canonical;
118
+ return BRAVE_SEARCH_LANG_CODES.has(canonical) ? canonical : void 0;
122
119
  }
123
120
  /** Normalize Brave country filter values. */
124
121
  function normalizeBraveCountry(value) {
125
- if (!value) return;
126
- const trimmed = value.trim();
122
+ const trimmed = normalizeOptionalString(value);
127
123
  if (!trimmed) return;
128
124
  const canonical = trimmed.toUpperCase();
129
125
  return BRAVE_COUNTRY_CODES.has(canonical) ? canonical : "ALL";
130
126
  }
131
127
  function normalizeBraveUiLang(value) {
132
- if (!value) return;
133
- const trimmed = value.trim();
134
- if (!trimmed) return;
135
- const match = trimmed.match(BRAVE_UI_LANG_LOCALE);
128
+ const match = normalizeOptionalString(value)?.match(BRAVE_UI_LANG_LOCALE);
136
129
  if (!match) return;
137
130
  const [, language, region] = match;
138
131
  if (!language || !region) return;
139
132
  return `${normalizeLowercaseStringOrEmpty(language)}-${region.toUpperCase()}`;
140
133
  }
141
- /** Resolve Brave-specific web-search config from scoped search config. */
142
- function resolveBraveConfig(searchConfig) {
143
- const brave = searchConfig?.brave;
144
- return brave && typeof brave === "object" && !Array.isArray(brave) ? brave : {};
145
- }
146
- /** Resolve whether Brave should use web search or LLM Context API mode. */
147
- function resolveBraveMode(brave) {
148
- return brave?.mode === "llm-context" ? "llm-context" : "web";
149
- }
150
134
  /** Normalize Brave search and UI language params, detecting swapped fields. */
151
135
  function normalizeBraveLanguageParams(params) {
152
136
  const rawSearchLang = normalizeOptionalString(params.search_lang);
@@ -313,7 +297,7 @@ async function runBraveWebSearch(params) {
313
297
  if (params.ui_lang) url.searchParams.set("ui_lang", params.ui_lang);
314
298
  }
315
299
  }, "Brave Search API error");
316
- return (Array.isArray(data.web?.results) ? data.web?.results ?? [] : []).slice(0, params.count).map((entry) => {
300
+ return (Array.isArray(data.web?.results) ? data.web.results : []).slice(0, params.count).map((entry) => {
317
301
  const description = entry.description ?? "";
318
302
  const title = entry.title ?? "";
319
303
  const url = entry.url ?? "";
@@ -330,7 +314,7 @@ async function runBraveWebSearch(params) {
330
314
  async function executeBraveSearch(args, searchConfig, options) {
331
315
  const apiKey = resolveBraveApiKey(searchConfig);
332
316
  if (!apiKey) return missingBraveKeyPayload();
333
- const braveConfig = resolveBraveConfig(searchConfig);
317
+ const braveConfig = asNonArrayRecord(searchConfig?.brave);
334
318
  const braveMode = resolveBraveMode(braveConfig);
335
319
  const braveBaseUrl = resolveBraveBaseUrl(braveConfig);
336
320
  const { signal, cleanup } = buildTimeoutAbortSignal({
@@ -401,7 +385,7 @@ async function executeBraveSearch(args, searchConfig, options) {
401
385
  }
402
386
  const llmContextDateEnd = braveMode === "llm-context" && dateAfter ? dateBefore ?? (/* @__PURE__ */ new Date()).toISOString().slice(0, 10) : dateBefore;
403
387
  const requestedCount = resolveSearchCount(count, DEFAULT_SEARCH_COUNT);
404
- const cacheKey = buildSearchCacheKey(braveMode === "llm-context" ? [
388
+ const cacheKey = buildSearchCacheKey([
405
389
  "brave",
406
390
  braveMode,
407
391
  braveBaseUrl,
@@ -409,21 +393,10 @@ async function executeBraveSearch(args, searchConfig, options) {
409
393
  requestedCount,
410
394
  country,
411
395
  normalizedLanguage.search_lang,
396
+ ...braveMode === "web" ? [normalizedLanguage.ui_lang] : [],
412
397
  freshness,
413
398
  dateAfter,
414
399
  llmContextDateEnd
415
- ] : [
416
- "brave",
417
- braveMode,
418
- braveBaseUrl,
419
- query,
420
- requestedCount,
421
- country,
422
- normalizedLanguage.search_lang,
423
- normalizedLanguage.ui_lang,
424
- freshness,
425
- dateAfter,
426
- dateBefore
427
400
  ]);
428
401
  const diagnostics = { enabled: options?.diagnosticsEnabled === true };
429
402
  const cacheTtlMs = resolveSearchCacheTtlMs(searchConfig);
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as createBraveWebSearchProvider } from "./.setup/brave-web-search-provider-DEK9TtrN.mjs";
1
+ import { t as createBraveWebSearchProvider } from "./.setup/brave-web-search-provider-DJmw8wv_.mjs";
2
2
  import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
3
3
  //#region extensions/brave/index.ts
4
4
  /**
@@ -1,3 +1,3 @@
1
- import { t as createBraveWebSearchProvider } from "./.setup/brave-web-search-provider-DEK9TtrN.mjs";
1
+ import { t as createBraveWebSearchProvider } from "./.setup/brave-web-search-provider-DJmw8wv_.mjs";
2
2
  import "./web-search-provider.js";
3
3
  export { createBraveWebSearchProvider };
@@ -1,2 +1,2 @@
1
- import { t as createBraveWebSearchProvider } from "./.setup/brave-web-search-provider-DEK9TtrN.mjs";
1
+ import { t as createBraveWebSearchProvider } from "./.setup/brave-web-search-provider-DJmw8wv_.mjs";
2
2
  export { createBraveWebSearchProvider };
@@ -1,23 +1,12 @@
1
1
  import { createWebSearchProviderContractFields } from "openclaw/plugin-sdk/provider-web-search-config-contract";
2
- import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
3
2
  //#region extensions/brave/web-search-shared.ts
4
3
  /**
5
4
  * Shared Brave Search provider metadata and credential lookup. Contract tests
6
5
  * and runtime provider creation both use this lightweight descriptor.
7
6
  */
8
- /** Canonical config path for the Brave Search API key. */
9
7
  const BRAVE_CREDENTIAL_PATH = "plugins.entries.brave.config.webSearch.apiKey";
10
- function resolveBraveWebSearchPluginConfig(config) {
11
- if (!isRecord(config)) return;
12
- const plugins = isRecord(config.plugins) ? config.plugins : void 0;
13
- const entries = isRecord(plugins?.entries) ? plugins.entries : void 0;
14
- const entry = isRecord(entries?.brave) ? entries.brave : void 0;
15
- const pluginConfig = isRecord(entry?.config) ? entry.config : void 0;
16
- return isRecord(pluginConfig?.webSearch) ? pluginConfig.webSearch : void 0;
17
- }
18
- /** Resolve Brave credentials from current plugin config. */
19
- function resolveConfiguredBraveCredential(config) {
20
- return resolveBraveWebSearchPluginConfig(config)?.apiKey;
8
+ function resolveBraveMode(brave) {
9
+ return brave?.mode === "llm-context" ? "llm-context" : "web";
21
10
  }
22
11
  /** Build the common Brave provider metadata without the runtime tool executor. */
23
12
  function buildBraveWebSearchProviderBase() {
@@ -37,9 +26,8 @@ function buildBraveWebSearchProviderBase() {
37
26
  credentialPath: BRAVE_CREDENTIAL_PATH,
38
27
  searchCredential: { type: "top-level" },
39
28
  configuredCredential: { pluginId: "brave" }
40
- }),
41
- getConfiguredCredentialValue: resolveConfiguredBraveCredential
29
+ })
42
30
  };
43
31
  }
44
32
  //#endregion
45
- export { buildBraveWebSearchProviderBase };
33
+ export { buildBraveWebSearchProviderBase, resolveBraveMode };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/brave-plugin",
3
- "version": "2026.9.6",
3
+ "version": "2026.9.8",
4
4
  "description": "OpenClaw Brave Search provider plugin for web search.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -19,10 +19,10 @@
19
19
  "allowInvalidConfigRecovery": true
20
20
  },
21
21
  "compat": {
22
- "pluginApi": ">=2026.9.6"
22
+ "pluginApi": ">=2026.9.8"
23
23
  },
24
24
  "build": {
25
- "openclawVersion": "2026.9.6"
25
+ "openclawVersion": "2026.9.8"
26
26
  },
27
27
  "release": {
28
28
  "publishToClawHub": true,
@@ -40,7 +40,7 @@
40
40
  "assets/activity.svg"
41
41
  ],
42
42
  "peerDependencies": {
43
- "openclaw": ">=2026.9.6"
43
+ "openclaw": ">=2026.9.8"
44
44
  },
45
45
  "peerDependenciesMeta": {
46
46
  "openclaw": {