@kodelyth/brave-plugin 2026.5.42 → 2026.6.2
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/package.json +17 -2
- package/index.ts +0 -11
- package/src/brave-web-search-provider.runtime.ts +0 -570
- package/src/brave-web-search-provider.shared.ts +0 -227
- package/src/brave-web-search-provider.test.ts +0 -756
- package/src/brave-web-search-provider.ts +0 -186
- package/test-api.ts +0 -14
- package/tsconfig.json +0 -16
- package/web-search-contract-api.ts +0 -70
- package/web-search-provider.ts +0 -1
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
import { isDiagnosticFlagEnabled } from "klaw/plugin-sdk/diagnostic-runtime";
|
|
2
|
-
import type {
|
|
3
|
-
SearchConfigRecord,
|
|
4
|
-
WebSearchProviderPlugin,
|
|
5
|
-
WebSearchProviderToolDefinition,
|
|
6
|
-
} from "klaw/plugin-sdk/provider-web-search";
|
|
7
|
-
import { createWebSearchProviderContractFields } from "klaw/plugin-sdk/provider-web-search-config-contract";
|
|
8
|
-
|
|
9
|
-
const BRAVE_CREDENTIAL_PATH = "plugins.entries.brave.config.webSearch.apiKey";
|
|
10
|
-
|
|
11
|
-
type BraveWebSearchRuntime = typeof import("./brave-web-search-provider.runtime.js");
|
|
12
|
-
|
|
13
|
-
let braveWebSearchRuntimePromise: Promise<BraveWebSearchRuntime> | undefined;
|
|
14
|
-
|
|
15
|
-
function loadBraveWebSearchRuntime(): Promise<BraveWebSearchRuntime> {
|
|
16
|
-
braveWebSearchRuntimePromise ??= import("./brave-web-search-provider.runtime.js");
|
|
17
|
-
return braveWebSearchRuntimePromise;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const BraveSearchSchema = {
|
|
21
|
-
type: "object",
|
|
22
|
-
properties: {
|
|
23
|
-
query: { type: "string", description: "Search query string." },
|
|
24
|
-
count: {
|
|
25
|
-
type: "number",
|
|
26
|
-
description: "Number of results to return (1-10).",
|
|
27
|
-
minimum: 1,
|
|
28
|
-
maximum: 10,
|
|
29
|
-
},
|
|
30
|
-
country: {
|
|
31
|
-
type: "string",
|
|
32
|
-
description:
|
|
33
|
-
"2-letter country code for region-specific results (e.g., 'DE', 'US', 'ALL'). Default: 'US'.",
|
|
34
|
-
},
|
|
35
|
-
language: {
|
|
36
|
-
type: "string",
|
|
37
|
-
description: "ISO 639-1 language code for results (e.g., 'en', 'de', 'fr').",
|
|
38
|
-
},
|
|
39
|
-
freshness: {
|
|
40
|
-
type: "string",
|
|
41
|
-
description: "Filter by time: 'day' (24h), 'week', 'month', or 'year'.",
|
|
42
|
-
},
|
|
43
|
-
date_after: {
|
|
44
|
-
type: "string",
|
|
45
|
-
description: "Only results published after this date (YYYY-MM-DD).",
|
|
46
|
-
},
|
|
47
|
-
date_before: {
|
|
48
|
-
type: "string",
|
|
49
|
-
description: "Only results published before this date (YYYY-MM-DD).",
|
|
50
|
-
},
|
|
51
|
-
search_lang: {
|
|
52
|
-
type: "string",
|
|
53
|
-
description:
|
|
54
|
-
"Brave language code for search results (e.g., 'en', 'de', 'en-gb', 'zh-hans', 'zh-hant', 'pt-br').",
|
|
55
|
-
},
|
|
56
|
-
ui_lang: {
|
|
57
|
-
type: "string",
|
|
58
|
-
description:
|
|
59
|
-
"Locale code for UI elements in language-region format (e.g., 'en-US', 'de-DE', 'fr-FR', 'tr-TR'). Must include region subtag.",
|
|
60
|
-
},
|
|
61
|
-
},
|
|
62
|
-
} satisfies Record<string, unknown>;
|
|
63
|
-
|
|
64
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
65
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function resolveProviderWebSearchPluginConfig(
|
|
69
|
-
config: unknown,
|
|
70
|
-
pluginId: string,
|
|
71
|
-
): Record<string, unknown> | undefined {
|
|
72
|
-
if (!isRecord(config)) {
|
|
73
|
-
return undefined;
|
|
74
|
-
}
|
|
75
|
-
const plugins = isRecord(config.plugins) ? config.plugins : undefined;
|
|
76
|
-
const entries = isRecord(plugins?.entries) ? plugins.entries : undefined;
|
|
77
|
-
const entry = isRecord(entries?.[pluginId]) ? entries[pluginId] : undefined;
|
|
78
|
-
const pluginConfig = isRecord(entry?.config) ? entry.config : undefined;
|
|
79
|
-
return isRecord(pluginConfig?.webSearch) ? pluginConfig.webSearch : undefined;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function resolveLegacyTopLevelBraveCredential(
|
|
83
|
-
config: unknown,
|
|
84
|
-
): { path: string; value: unknown } | undefined {
|
|
85
|
-
if (!isRecord(config)) {
|
|
86
|
-
return undefined;
|
|
87
|
-
}
|
|
88
|
-
const tools = isRecord(config.tools) ? config.tools : undefined;
|
|
89
|
-
const web = isRecord(tools?.web) ? tools.web : undefined;
|
|
90
|
-
const search = isRecord(web?.search) ? web.search : undefined;
|
|
91
|
-
if (!search || !("apiKey" in search)) {
|
|
92
|
-
return undefined;
|
|
93
|
-
}
|
|
94
|
-
return { path: "tools.web.search.apiKey", value: search.apiKey };
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
function resolveConfiguredBraveCredential(config: unknown): unknown {
|
|
98
|
-
return (
|
|
99
|
-
resolveProviderWebSearchPluginConfig(config, "brave")?.apiKey ??
|
|
100
|
-
resolveLegacyTopLevelBraveCredential(config)?.value
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function mergeScopedSearchConfig(
|
|
105
|
-
searchConfig: Record<string, unknown> | undefined,
|
|
106
|
-
key: string,
|
|
107
|
-
pluginConfig: Record<string, unknown> | undefined,
|
|
108
|
-
options?: { mirrorApiKeyToTopLevel?: boolean },
|
|
109
|
-
): Record<string, unknown> | undefined {
|
|
110
|
-
if (!pluginConfig) {
|
|
111
|
-
return searchConfig;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
const currentScoped = isRecord(searchConfig?.[key]) ? searchConfig?.[key] : {};
|
|
115
|
-
const next: Record<string, unknown> = {
|
|
116
|
-
...searchConfig,
|
|
117
|
-
[key]: {
|
|
118
|
-
...currentScoped,
|
|
119
|
-
...pluginConfig,
|
|
120
|
-
},
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
if (options?.mirrorApiKeyToTopLevel && pluginConfig.apiKey !== undefined) {
|
|
124
|
-
next.apiKey = pluginConfig.apiKey;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
return next;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
function resolveBraveMode(searchConfig?: Record<string, unknown>): "web" | "llm-context" {
|
|
131
|
-
const brave = isRecord(searchConfig?.brave) ? searchConfig.brave : undefined;
|
|
132
|
-
return brave?.mode === "llm-context" ? "llm-context" : "web";
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
function createBraveToolDefinition(
|
|
136
|
-
searchConfig?: SearchConfigRecord,
|
|
137
|
-
config?: Parameters<typeof isDiagnosticFlagEnabled>[1],
|
|
138
|
-
): WebSearchProviderToolDefinition {
|
|
139
|
-
const braveMode = resolveBraveMode(searchConfig);
|
|
140
|
-
const diagnosticsEnabled = isDiagnosticFlagEnabled("brave.http", config);
|
|
141
|
-
|
|
142
|
-
return {
|
|
143
|
-
description:
|
|
144
|
-
braveMode === "llm-context"
|
|
145
|
-
? "Search the web using Brave Search LLM Context API. Returns pre-extracted page content (text chunks, tables, code blocks) optimized for LLM grounding."
|
|
146
|
-
: "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.",
|
|
147
|
-
parameters: BraveSearchSchema,
|
|
148
|
-
execute: async (args) => {
|
|
149
|
-
const { executeBraveSearch } = await loadBraveWebSearchRuntime();
|
|
150
|
-
return await executeBraveSearch(args, searchConfig, { diagnosticsEnabled });
|
|
151
|
-
},
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
export function createBraveWebSearchProvider(): WebSearchProviderPlugin {
|
|
156
|
-
return {
|
|
157
|
-
id: "brave",
|
|
158
|
-
label: "Brave Search",
|
|
159
|
-
hint: "Structured results · country/language/time filters",
|
|
160
|
-
onboardingScopes: ["text-inference"],
|
|
161
|
-
credentialLabel: "Brave Search API key",
|
|
162
|
-
envVars: ["BRAVE_API_KEY"],
|
|
163
|
-
placeholder: "BSA...",
|
|
164
|
-
signupUrl: "https://brave.com/search/api/",
|
|
165
|
-
docsUrl: "https://klaw.kodelyth.com/tools/brave-search",
|
|
166
|
-
autoDetectOrder: 10,
|
|
167
|
-
credentialPath: BRAVE_CREDENTIAL_PATH,
|
|
168
|
-
...createWebSearchProviderContractFields({
|
|
169
|
-
credentialPath: BRAVE_CREDENTIAL_PATH,
|
|
170
|
-
searchCredential: { type: "top-level" },
|
|
171
|
-
configuredCredential: { pluginId: "brave" },
|
|
172
|
-
}),
|
|
173
|
-
getConfiguredCredentialValue: resolveConfiguredBraveCredential,
|
|
174
|
-
getConfiguredCredentialFallback: resolveLegacyTopLevelBraveCredential,
|
|
175
|
-
createTool: (ctx) =>
|
|
176
|
-
createBraveToolDefinition(
|
|
177
|
-
mergeScopedSearchConfig(
|
|
178
|
-
ctx.searchConfig,
|
|
179
|
-
"brave",
|
|
180
|
-
resolveProviderWebSearchPluginConfig(ctx.config, "brave"),
|
|
181
|
-
{ mirrorApiKeyToTopLevel: true },
|
|
182
|
-
),
|
|
183
|
-
ctx.config,
|
|
184
|
-
),
|
|
185
|
-
};
|
|
186
|
-
}
|
package/test-api.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
mapBraveLlmContextResults,
|
|
3
|
-
normalizeBraveCountry,
|
|
4
|
-
normalizeBraveLanguageParams,
|
|
5
|
-
resolveBraveMode,
|
|
6
|
-
} from "./src/brave-web-search-provider.shared.js";
|
|
7
|
-
|
|
8
|
-
export const testing = {
|
|
9
|
-
normalizeBraveCountry,
|
|
10
|
-
normalizeBraveLanguageParams,
|
|
11
|
-
resolveBraveMode,
|
|
12
|
-
mapBraveLlmContextResults,
|
|
13
|
-
} as const;
|
|
14
|
-
export { testing as __testing };
|
package/tsconfig.json
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": "../tsconfig.package-boundary.base.json",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"rootDir": "."
|
|
5
|
-
},
|
|
6
|
-
"include": ["./*.ts", "./src/**/*.ts"],
|
|
7
|
-
"exclude": [
|
|
8
|
-
"./**/*.test.ts",
|
|
9
|
-
"./dist/**",
|
|
10
|
-
"./node_modules/**",
|
|
11
|
-
"./src/test-support/**",
|
|
12
|
-
"./src/**/*test-helpers.ts",
|
|
13
|
-
"./src/**/*test-harness.ts",
|
|
14
|
-
"./src/**/*test-support.ts"
|
|
15
|
-
]
|
|
16
|
-
}
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createWebSearchProviderContractFields,
|
|
3
|
-
type WebSearchProviderPlugin,
|
|
4
|
-
} from "klaw/plugin-sdk/provider-web-search-config-contract";
|
|
5
|
-
|
|
6
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
7
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
function resolveLegacyTopLevelBraveCredential(
|
|
11
|
-
config: unknown,
|
|
12
|
-
): { path: string; value: unknown } | undefined {
|
|
13
|
-
if (!isRecord(config)) {
|
|
14
|
-
return undefined;
|
|
15
|
-
}
|
|
16
|
-
const tools = isRecord(config.tools) ? config.tools : undefined;
|
|
17
|
-
const web = isRecord(tools?.web) ? tools.web : undefined;
|
|
18
|
-
const search = isRecord(web?.search) ? web.search : undefined;
|
|
19
|
-
if (!search || !("apiKey" in search)) {
|
|
20
|
-
return undefined;
|
|
21
|
-
}
|
|
22
|
-
return { path: "tools.web.search.apiKey", value: search.apiKey };
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function resolveProviderWebSearchPluginConfig(
|
|
26
|
-
config: unknown,
|
|
27
|
-
pluginId: string,
|
|
28
|
-
): Record<string, unknown> | undefined {
|
|
29
|
-
if (!isRecord(config)) {
|
|
30
|
-
return undefined;
|
|
31
|
-
}
|
|
32
|
-
const plugins = isRecord(config.plugins) ? config.plugins : undefined;
|
|
33
|
-
const entries = isRecord(plugins?.entries) ? plugins.entries : undefined;
|
|
34
|
-
const entry = isRecord(entries?.[pluginId]) ? entries[pluginId] : undefined;
|
|
35
|
-
const pluginConfig = isRecord(entry?.config) ? entry.config : undefined;
|
|
36
|
-
return isRecord(pluginConfig?.webSearch) ? pluginConfig.webSearch : undefined;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function resolveConfiguredBraveCredential(config: unknown): unknown {
|
|
40
|
-
return (
|
|
41
|
-
resolveProviderWebSearchPluginConfig(config, "brave")?.apiKey ??
|
|
42
|
-
resolveLegacyTopLevelBraveCredential(config)?.value
|
|
43
|
-
);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export function createBraveWebSearchProvider(): WebSearchProviderPlugin {
|
|
47
|
-
const credentialPath = "plugins.entries.brave.config.webSearch.apiKey";
|
|
48
|
-
|
|
49
|
-
return {
|
|
50
|
-
id: "brave",
|
|
51
|
-
label: "Brave Search",
|
|
52
|
-
hint: "Structured results · country/language/time filters",
|
|
53
|
-
onboardingScopes: ["text-inference"],
|
|
54
|
-
credentialLabel: "Brave Search API key",
|
|
55
|
-
envVars: ["BRAVE_API_KEY"],
|
|
56
|
-
placeholder: "BSA...",
|
|
57
|
-
signupUrl: "https://brave.com/search/api/",
|
|
58
|
-
docsUrl: "https://klaw.kodelyth.com/tools/brave-search",
|
|
59
|
-
autoDetectOrder: 10,
|
|
60
|
-
credentialPath,
|
|
61
|
-
...createWebSearchProviderContractFields({
|
|
62
|
-
credentialPath,
|
|
63
|
-
searchCredential: { type: "top-level" },
|
|
64
|
-
configuredCredential: { pluginId: "brave" },
|
|
65
|
-
}),
|
|
66
|
-
getConfiguredCredentialValue: resolveConfiguredBraveCredential,
|
|
67
|
-
getConfiguredCredentialFallback: resolveLegacyTopLevelBraveCredential,
|
|
68
|
-
createTool: () => null,
|
|
69
|
-
};
|
|
70
|
-
}
|
package/web-search-provider.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { createBraveWebSearchProvider } from "./src/brave-web-search-provider.js";
|