feat: add web tools config to configure
This commit is contained in:
@@ -14,6 +14,7 @@
|
|||||||
- Docs: document DM history limits for channel DMs. (#883) — thanks @pkrmf.
|
- Docs: document DM history limits for channel DMs. (#883) — thanks @pkrmf.
|
||||||
- Security: add detect-secrets CI scan and baseline guidance. (#227) — thanks @Hyaxia.
|
- Security: add detect-secrets CI scan and baseline guidance. (#227) — thanks @Hyaxia.
|
||||||
- Tools: add `web_search`/`web_fetch` (Brave API), auto-enable `web_fetch` for sandboxed sessions, and remove the `brave-search` skill.
|
- Tools: add `web_search`/`web_fetch` (Brave API), auto-enable `web_fetch` for sandboxed sessions, and remove the `brave-search` skill.
|
||||||
|
- CLI/Docs: add a web tools configure section for storing Brave API keys and update onboarding tips.
|
||||||
- Browser: add Chrome extension relay takeover mode (toolbar button), plus `clawdbot browser extension install/path` and remote browser control via `clawdbot browser serve` + `browser.controlToken`.
|
- Browser: add Chrome extension relay takeover mode (toolbar button), plus `clawdbot browser extension install/path` and remote browser control via `clawdbot browser serve` + `browser.controlToken`.
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
|
|||||||
@@ -1607,7 +1607,7 @@ Legacy: `tools.bash` is still accepted as an alias.
|
|||||||
|
|
||||||
`tools.web` configures web search + fetch tools:
|
`tools.web` configures web search + fetch tools:
|
||||||
- `tools.web.search.enabled` (default: true when key is present)
|
- `tools.web.search.enabled` (default: true when key is present)
|
||||||
- `tools.web.search.apiKey` (or `BRAVE_API_KEY` env var)
|
- `tools.web.search.apiKey` (recommended: set via `clawdbot configure --section web`, or use `BRAVE_API_KEY` env var)
|
||||||
- `tools.web.search.maxResults` (1–10, default 5)
|
- `tools.web.search.maxResults` (1–10, default 5)
|
||||||
- `tools.web.search.timeoutSeconds` (default 30)
|
- `tools.web.search.timeoutSeconds` (default 30)
|
||||||
- `tools.web.search.cacheTtlMinutes` (default 15)
|
- `tools.web.search.cacheTtlMinutes` (default 15)
|
||||||
|
|||||||
@@ -576,7 +576,9 @@ The Gateway watches the config and supports hot‑reload:
|
|||||||
### How do I enable web search (and web fetch)?
|
### How do I enable web search (and web fetch)?
|
||||||
|
|
||||||
`web_fetch` works without an API key. `web_search` requires a Brave Search API
|
`web_fetch` works without an API key. `web_search` requires a Brave Search API
|
||||||
key (`BRAVE_API_KEY` or `tools.web.search.apiKey`).
|
key. **Recommended:** run `clawdbot configure --section web` to store it in
|
||||||
|
`tools.web.search.apiKey`. Environment alternative: set `BRAVE_API_KEY` for the
|
||||||
|
Gateway process.
|
||||||
|
|
||||||
```json5
|
```json5
|
||||||
{
|
{
|
||||||
@@ -584,7 +586,7 @@ key (`BRAVE_API_KEY` or `tools.web.search.apiKey`).
|
|||||||
web: {
|
web: {
|
||||||
search: {
|
search: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
apiKey: "BRAVE_API_KEY_HERE", // or set BRAVE_API_KEY
|
apiKey: "BRAVE_API_KEY_HERE",
|
||||||
maxResults: 5
|
maxResults: 5
|
||||||
},
|
},
|
||||||
fetch: {
|
fetch: {
|
||||||
@@ -598,6 +600,7 @@ key (`BRAVE_API_KEY` or `tools.web.search.apiKey`).
|
|||||||
Notes:
|
Notes:
|
||||||
- If you use allowlists, add `web_search`/`web_fetch` or `group:web`.
|
- If you use allowlists, add `web_search`/`web_fetch` or `group:web`.
|
||||||
- In sandboxed sessions, `web_fetch` auto-enables unless explicitly disabled.
|
- In sandboxed sessions, `web_fetch` auto-enables unless explicitly disabled.
|
||||||
|
- Daemons read env vars from `~/.clawdbot/.env` (or the service environment).
|
||||||
|
|
||||||
Docs: [Web tools](/tools/web).
|
Docs: [Web tools](/tools/web).
|
||||||
|
|
||||||
|
|||||||
@@ -40,8 +40,9 @@ run on host, set an explicit per-agent override:
|
|||||||
|
|
||||||
- Node `>=22`
|
- Node `>=22`
|
||||||
- `pnpm` (optional; recommended if you build from source)
|
- `pnpm` (optional; recommended if you build from source)
|
||||||
- **Recommended:** Brave Search API key for web search. Set `BRAVE_API_KEY` or
|
- **Recommended:** Brave Search API key for web search. Easiest path:
|
||||||
`tools.web.search.apiKey`. See [Web tools](/tools/web).
|
`clawdbot configure --section web` (stores `tools.web.search.apiKey`).
|
||||||
|
See [Web tools](/tools/web).
|
||||||
|
|
||||||
macOS: if you plan to build the apps, install Xcode / CLT. For the CLI + gateway only, Node is enough.
|
macOS: if you plan to build the apps, install Xcode / CLT. For the CLI + gateway only, Node is enough.
|
||||||
Windows: use **WSL2** (Ubuntu recommended). WSL2 is strongly recommended; native Windows is untested and more problematic. Install WSL2 first, then run the Linux steps inside WSL. See [Windows (WSL2)](/platforms/windows).
|
Windows: use **WSL2** (Ubuntu recommended). WSL2 is strongly recommended; native Windows is untested and more problematic. Install WSL2 first, then run the Linux steps inside WSL. See [Windows (WSL2)](/platforms/windows).
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ clawdbot configure
|
|||||||
```
|
```
|
||||||
|
|
||||||
Recommended: set up a Brave Search API key so the agent can use `web_search`
|
Recommended: set up a Brave Search API key so the agent can use `web_search`
|
||||||
(`web_fetch` works without a key). Set `BRAVE_API_KEY` or
|
(`web_fetch` works without a key). Easiest path: `clawdbot configure --section web`
|
||||||
`tools.web.search.apiKey`. Docs: [Web tools](/tools/web).
|
which stores `tools.web.search.apiKey`. Docs: [Web tools](/tools/web).
|
||||||
|
|
||||||
## QuickStart vs Advanced
|
## QuickStart vs Advanced
|
||||||
|
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ Core parameters:
|
|||||||
- `count` (1–10; default from `tools.web.search.maxResults`)
|
- `count` (1–10; default from `tools.web.search.maxResults`)
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
- Requires `BRAVE_API_KEY` or `tools.web.search.apiKey`.
|
- Requires a Brave API key (recommended: `clawdbot configure --section web`, or set `BRAVE_API_KEY`).
|
||||||
- Enable via `tools.web.search.enabled`.
|
- Enable via `tools.web.search.enabled`.
|
||||||
- Responses are cached (default 15 min).
|
- Responses are cached (default 15 min).
|
||||||
- See [Web tools](/tools/web) for setup.
|
- See [Web tools](/tools/web) for setup.
|
||||||
|
|||||||
@@ -28,11 +28,20 @@ These are **not** browser automation. For JS-heavy sites or logins, use the
|
|||||||
|
|
||||||
1) Create a Brave Search API account at https://brave.com/search/api/
|
1) Create a Brave Search API account at https://brave.com/search/api/
|
||||||
2) Generate an API key in the dashboard.
|
2) Generate an API key in the dashboard.
|
||||||
3) Set `BRAVE_API_KEY` in your environment or paste it into `tools.web.search.apiKey`.
|
3) Run `clawdbot configure --section web` to store the key in config (recommended), or set `BRAVE_API_KEY` in your environment.
|
||||||
|
|
||||||
Brave provides a free tier plus paid plans; check the Brave API portal for the
|
Brave provides a free tier plus paid plans; check the Brave API portal for the
|
||||||
current limits and pricing.
|
current limits and pricing.
|
||||||
|
|
||||||
|
### Where to set the key (recommended)
|
||||||
|
|
||||||
|
**Recommended:** run `clawdbot configure --section web`. It stores the key in
|
||||||
|
`~/.clawdbot/clawdbot.json` under `tools.web.search.apiKey`.
|
||||||
|
|
||||||
|
**Environment alternative:** set `BRAVE_API_KEY` in the Gateway process
|
||||||
|
environment. For a daemon install, put it in `~/.clawdbot/.env` (or your
|
||||||
|
service environment). See [Env vars](/start/faq#how-does-clawdbot-load-environment-variables).
|
||||||
|
|
||||||
## web_search
|
## web_search
|
||||||
|
|
||||||
Search the web with Brave’s API.
|
Search the web with Brave’s API.
|
||||||
@@ -40,7 +49,7 @@ Search the web with Brave’s API.
|
|||||||
### Requirements
|
### Requirements
|
||||||
|
|
||||||
- `tools.web.search.enabled: true`
|
- `tools.web.search.enabled: true`
|
||||||
- Brave API key via `BRAVE_API_KEY` **or** `tools.web.search.apiKey`
|
- Brave API key (recommended: `clawdbot configure --section web`, or set `BRAVE_API_KEY`)
|
||||||
|
|
||||||
### Config
|
### Config
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ vi.mock("../commands/configure.js", () => ({
|
|||||||
CONFIGURE_WIZARD_SECTIONS: [
|
CONFIGURE_WIZARD_SECTIONS: [
|
||||||
"workspace",
|
"workspace",
|
||||||
"model",
|
"model",
|
||||||
|
"web",
|
||||||
"gateway",
|
"gateway",
|
||||||
"daemon",
|
"daemon",
|
||||||
"channels",
|
"channels",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ vi.mock("../commands/configure.js", () => ({
|
|||||||
CONFIGURE_WIZARD_SECTIONS: [
|
CONFIGURE_WIZARD_SECTIONS: [
|
||||||
"workspace",
|
"workspace",
|
||||||
"model",
|
"model",
|
||||||
|
"web",
|
||||||
"gateway",
|
"gateway",
|
||||||
"daemon",
|
"daemon",
|
||||||
"channels",
|
"channels",
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ vi.mock("../commands/configure.js", () => ({
|
|||||||
CONFIGURE_WIZARD_SECTIONS: [
|
CONFIGURE_WIZARD_SECTIONS: [
|
||||||
"workspace",
|
"workspace",
|
||||||
"model",
|
"model",
|
||||||
|
"web",
|
||||||
"gateway",
|
"gateway",
|
||||||
"daemon",
|
"daemon",
|
||||||
"channels",
|
"channels",
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import { stylePromptHint, stylePromptMessage, stylePromptTitle } from "../termin
|
|||||||
export const CONFIGURE_WIZARD_SECTIONS = [
|
export const CONFIGURE_WIZARD_SECTIONS = [
|
||||||
"workspace",
|
"workspace",
|
||||||
"model",
|
"model",
|
||||||
|
"web",
|
||||||
"gateway",
|
"gateway",
|
||||||
"daemon",
|
"daemon",
|
||||||
"channels",
|
"channels",
|
||||||
@@ -34,6 +35,7 @@ export const CONFIGURE_SECTION_OPTIONS: Array<{
|
|||||||
}> = [
|
}> = [
|
||||||
{ value: "workspace", label: "Workspace", hint: "Set workspace + sessions" },
|
{ value: "workspace", label: "Workspace", hint: "Set workspace + sessions" },
|
||||||
{ value: "model", label: "Model", hint: "Pick provider + credentials" },
|
{ value: "model", label: "Model", hint: "Pick provider + credentials" },
|
||||||
|
{ value: "web", label: "Web tools", hint: "Configure Brave search + fetch" },
|
||||||
{ value: "gateway", label: "Gateway", hint: "Port, bind, auth, tailscale" },
|
{ value: "gateway", label: "Gateway", hint: "Port, bind, auth, tailscale" },
|
||||||
{
|
{
|
||||||
value: "daemon",
|
value: "daemon",
|
||||||
|
|||||||
@@ -21,7 +21,14 @@ import type {
|
|||||||
ConfigureWizardParams,
|
ConfigureWizardParams,
|
||||||
WizardSection,
|
WizardSection,
|
||||||
} from "./configure.shared.js";
|
} from "./configure.shared.js";
|
||||||
import { CONFIGURE_SECTION_OPTIONS, intro, outro, select, text } from "./configure.shared.js";
|
import {
|
||||||
|
CONFIGURE_SECTION_OPTIONS,
|
||||||
|
confirm,
|
||||||
|
intro,
|
||||||
|
outro,
|
||||||
|
select,
|
||||||
|
text,
|
||||||
|
} from "./configure.shared.js";
|
||||||
import { healthCommand } from "./health.js";
|
import { healthCommand } from "./health.js";
|
||||||
import { formatHealthCheckFailure } from "./health-format.js";
|
import { formatHealthCheckFailure } from "./health-format.js";
|
||||||
import { setupChannels } from "./onboard-channels.js";
|
import { setupChannels } from "./onboard-channels.js";
|
||||||
@@ -83,6 +90,77 @@ async function promptChannelMode(runtime: RuntimeEnv): Promise<ChannelsWizardMod
|
|||||||
) as ChannelsWizardMode;
|
) as ChannelsWizardMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function promptWebToolsConfig(
|
||||||
|
nextConfig: ClawdbotConfig,
|
||||||
|
runtime: RuntimeEnv,
|
||||||
|
): Promise<ClawdbotConfig> {
|
||||||
|
const existingSearch = nextConfig.tools?.web?.search;
|
||||||
|
const existingFetch = nextConfig.tools?.web?.fetch;
|
||||||
|
const hasSearchKey = Boolean(existingSearch?.apiKey);
|
||||||
|
|
||||||
|
const enableSearch = guardCancel(
|
||||||
|
await confirm({
|
||||||
|
message: "Enable web_search (Brave Search API)?",
|
||||||
|
initialValue: existingSearch?.enabled ?? hasSearchKey,
|
||||||
|
}),
|
||||||
|
runtime,
|
||||||
|
);
|
||||||
|
|
||||||
|
let nextSearch = {
|
||||||
|
...existingSearch,
|
||||||
|
enabled: enableSearch,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (enableSearch) {
|
||||||
|
const keyInput = guardCancel(
|
||||||
|
await text({
|
||||||
|
message: hasSearchKey
|
||||||
|
? "Brave Search API key (leave blank to keep current or use BRAVE_API_KEY)"
|
||||||
|
: "Brave Search API key (leave blank to use BRAVE_API_KEY)",
|
||||||
|
placeholder: hasSearchKey ? "Leave blank to keep current" : "BSA...",
|
||||||
|
}),
|
||||||
|
runtime,
|
||||||
|
);
|
||||||
|
const key = String(keyInput ?? "").trim();
|
||||||
|
if (key) {
|
||||||
|
nextSearch = { ...nextSearch, apiKey: key };
|
||||||
|
} else if (!hasSearchKey) {
|
||||||
|
note(
|
||||||
|
[
|
||||||
|
"No key stored. web_search needs BRAVE_API_KEY or tools.web.search.apiKey.",
|
||||||
|
"Docs: https://docs.clawd.bot/tools/web",
|
||||||
|
].join("\n"),
|
||||||
|
"Web search",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const enableFetch = guardCancel(
|
||||||
|
await confirm({
|
||||||
|
message: "Enable web_fetch (keyless HTTP fetch)?",
|
||||||
|
initialValue: existingFetch?.enabled ?? true,
|
||||||
|
}),
|
||||||
|
runtime,
|
||||||
|
);
|
||||||
|
|
||||||
|
const nextFetch = {
|
||||||
|
...existingFetch,
|
||||||
|
enabled: enableFetch,
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
...nextConfig,
|
||||||
|
tools: {
|
||||||
|
...nextConfig.tools,
|
||||||
|
web: {
|
||||||
|
...nextConfig.tools?.web,
|
||||||
|
search: nextSearch,
|
||||||
|
fetch: nextFetch,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export async function runConfigureWizard(
|
export async function runConfigureWizard(
|
||||||
opts: ConfigureWizardParams,
|
opts: ConfigureWizardParams,
|
||||||
runtime: RuntimeEnv = defaultRuntime,
|
runtime: RuntimeEnv = defaultRuntime,
|
||||||
@@ -219,6 +297,10 @@ export async function runConfigureWizard(
|
|||||||
nextConfig = await promptAuthConfig(nextConfig, runtime, prompter);
|
nextConfig = await promptAuthConfig(nextConfig, runtime, prompter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (selected.includes("web")) {
|
||||||
|
nextConfig = await promptWebToolsConfig(nextConfig, runtime);
|
||||||
|
}
|
||||||
|
|
||||||
if (selected.includes("gateway")) {
|
if (selected.includes("gateway")) {
|
||||||
const gateway = await promptGatewayConfig(nextConfig, runtime);
|
const gateway = await promptGatewayConfig(nextConfig, runtime);
|
||||||
nextConfig = gateway.config;
|
nextConfig = gateway.config;
|
||||||
@@ -314,6 +396,11 @@ export async function runConfigureWizard(
|
|||||||
await persistConfig();
|
await persistConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (choice === "web") {
|
||||||
|
nextConfig = await promptWebToolsConfig(nextConfig, runtime);
|
||||||
|
await persistConfig();
|
||||||
|
}
|
||||||
|
|
||||||
if (choice === "gateway") {
|
if (choice === "gateway") {
|
||||||
const gateway = await promptGatewayConfig(nextConfig, runtime);
|
const gateway = await promptGatewayConfig(nextConfig, runtime);
|
||||||
nextConfig = gateway.config;
|
nextConfig = gateway.config;
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ export async function runNonInteractiveOnboardingLocal(params: {
|
|||||||
|
|
||||||
if (!opts.json) {
|
if (!opts.json) {
|
||||||
runtime.log(
|
runtime.log(
|
||||||
"Tip: set BRAVE_API_KEY (or tools.web.search.apiKey) to enable web_search. Docs: https://docs.clawd.bot/tools/web",
|
"Tip: run `clawdbot configure --section web` to store your Brave API key for web_search. Docs: https://docs.clawd.bot/tools/web",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ export async function runNonInteractiveOnboardingRemote(params: {
|
|||||||
runtime.log(`Remote gateway: ${remoteUrl}`);
|
runtime.log(`Remote gateway: ${remoteUrl}`);
|
||||||
runtime.log(`Auth: ${payload.auth}`);
|
runtime.log(`Auth: ${payload.auth}`);
|
||||||
runtime.log(
|
runtime.log(
|
||||||
"Tip: set BRAVE_API_KEY (or tools.web.search.apiKey) to enable web_search. Docs: https://docs.clawd.bot/tools/web",
|
"Tip: run `clawdbot configure --section web` to store your Brave API key for web_search. Docs: https://docs.clawd.bot/tools/web",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,8 +77,9 @@ export async function runOnboardingWizard(
|
|||||||
await prompter.intro("Clawdbot onboarding");
|
await prompter.intro("Clawdbot onboarding");
|
||||||
await prompter.note(
|
await prompter.note(
|
||||||
[
|
[
|
||||||
"Recommended: get a Brave Search API key to enable web_search.",
|
"Recommended: set up a Brave Search API key for web_search.",
|
||||||
"Set BRAVE_API_KEY or tools.web.search.apiKey.",
|
"Easiest: clawdbot configure --section web (stores tools.web.search.apiKey).",
|
||||||
|
"Env alternative: BRAVE_API_KEY (gateway environment).",
|
||||||
"Docs: https://docs.clawd.bot/tools/web",
|
"Docs: https://docs.clawd.bot/tools/web",
|
||||||
].join("\n"),
|
].join("\n"),
|
||||||
"Web search (optional)",
|
"Web search (optional)",
|
||||||
|
|||||||
Reference in New Issue
Block a user