Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions docs/cli/configuration-v1.md
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,8 @@ If you are experiencing performance issues with file searching (e.g., with `@` c
```

- **`tavilyApiKey`** (string):
- **Description:** API key for Tavily web search service. Required to enable the `web_search` tool functionality. If not configured, the web search tool will be disabled and skipped.
- **Description:** API key for Tavily web search service. Used to enable the `web_search` tool functionality.
- **Note:** This is a legacy configuration format. For Qwen OAuth users, DashScope provider is automatically available without any configuration. For other authentication types, configure Tavily or Google providers using the new `webSearch` configuration format.
- **Default:** `undefined` (web search disabled)
- **Example:** `"tavilyApiKey": "tvly-your-api-key-here"`
- **`chatCompression`** (object):
Expand Down Expand Up @@ -465,8 +466,8 @@ The CLI automatically loads environment variables from an `.env` file. The loadi
- This is useful for development and testing.
- **`TAVILY_API_KEY`**:
- Your API key for the Tavily web search service.
- Required to enable the `web_search` tool functionality.
- If not configured, the web search tool will be disabled and skipped.
- Used to enable the `web_search` tool functionality.
- **Note:** For Qwen OAuth users, DashScope provider is automatically available without any configuration. For other authentication types, configure Tavily or Google providers to enable web search.
- Example: `export TAVILY_API_KEY="tvly-your-api-key-here"`

## Command-Line Arguments
Expand Down
7 changes: 4 additions & 3 deletions docs/cli/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,8 @@ Settings are organized into categories. All settings should be placed within the
- **Default:** `undefined`

- **`advanced.tavilyApiKey`** (string):
- **Description:** API key for Tavily web search service. Required to enable the `web_search` tool functionality. If not configured, the web search tool will be disabled and skipped.
- **Description:** API key for Tavily web search service. Used to enable the `web_search` tool functionality.
- **Note:** This is a legacy configuration format. For Qwen OAuth users, DashScope provider is automatically available without any configuration. For other authentication types, configure Tavily or Google providers using the new `webSearch` configuration format.
- **Default:** `undefined`

#### `mcpServers`
Expand Down Expand Up @@ -474,8 +475,8 @@ The CLI automatically loads environment variables from an `.env` file. The loadi
- Set to a string to customize the title of the CLI.
- **`TAVILY_API_KEY`**:
- Your API key for the Tavily web search service.
- Required to enable the `web_search` tool functionality.
- If not configured, the web search tool will be disabled and skipped.
- Used to enable the `web_search` tool functionality.
- **Note:** For Qwen OAuth users, DashScope provider is automatically available without any configuration. For other authentication types, configure Tavily or Google providers to enable web search.
- Example: `export TAVILY_API_KEY="tvly-your-api-key-here"`

## Command-Line Arguments
Expand Down
181 changes: 162 additions & 19 deletions docs/tools/web-search.md
Original file line number Diff line number Diff line change
@@ -1,43 +1,186 @@
# Web Search Tool (`web_search`)

This document describes the `web_search` tool.
This document describes the `web_search` tool for performing web searches using multiple providers.

## Description

Use `web_search` to perform a web search using the Tavily API. The tool returns a concise answer with sources when possible.
Use `web_search` to perform a web search and get information from the internet. The tool supports multiple search providers and returns a concise answer with source citations when available.

### Supported Providers

1. **DashScope** (Official, Free) - Automatically available for Qwen OAuth users (200 requests/minute, 2000 requests/day)
2. **Tavily** - High-quality search API with built-in answer generation
3. **Google Custom Search** - Google's Custom Search JSON API

### Arguments

`web_search` takes one argument:
`web_search` takes two arguments:

- `query` (string, required): The search query
- `provider` (string, optional): Specific provider to use ("dashscope", "tavily", "google")
- If not specified, uses the default provider from configuration

## Configuration

### Method 1: Settings File (Recommended)

Add to your `settings.json`:

```json
{
"webSearch": {
"provider": [
{ "type": "dashscope" },
{ "type": "tavily", "apiKey": "tvly-xxxxx" },
{
"type": "google",
"apiKey": "your-google-api-key",
"searchEngineId": "your-search-engine-id"
}
],
"default": "dashscope"
}
}
```

**Notes:**

- DashScope doesn't require an API key (official, free service)
- **Qwen OAuth users:** DashScope is automatically added to your provider list, even if not explicitly configured
- Configure additional providers (Tavily, Google) if you want to use them alongside DashScope
- Set `default` to specify which provider to use by default (if not set, priority order: Tavily > Google > DashScope)

### Method 2: Environment Variables

Set environment variables in your shell or `.env` file:

```bash
# Tavily
export TAVILY_API_KEY="tvly-xxxxx"

# Google
export GOOGLE_API_KEY="your-api-key"
export GOOGLE_SEARCH_ENGINE_ID="your-engine-id"
```

### Method 3: Command Line Arguments

- `query` (string, required): The search query.
Pass API keys when running Qwen Code:

## How to use `web_search`
```bash
# Tavily
qwen --tavily-api-key tvly-xxxxx

`web_search` calls the Tavily API directly. You must configure the `TAVILY_API_KEY` through one of the following methods:
# Google
qwen --google-api-key your-key --google-search-engine-id your-id

1. **Settings file**: Add `"tavilyApiKey": "your-key-here"` to your `settings.json`
2. **Environment variable**: Set `TAVILY_API_KEY` in your environment or `.env` file
3. **Command line**: Use `--tavily-api-key your-key-here` when running the CLI
# Specify default provider
qwen --web-search-default tavily
```

If the key is not configured, the tool will be disabled and skipped.
### Backward Compatibility (Deprecated)

Usage:
⚠️ **DEPRECATED:** The legacy `tavilyApiKey` configuration is still supported for backward compatibility but is deprecated:

```json
{
"advanced": {
"tavilyApiKey": "tvly-xxxxx" // ⚠️ Deprecated
}
}
```
web_search(query="Your query goes here.")

**Important:** This configuration is deprecated and will be removed in a future version. Please migrate to the new `webSearch` configuration format shown above. The old configuration will automatically configure Tavily as a provider, but we strongly recommend updating your configuration.

## Disabling Web Search

If you want to disable the web search functionality, you can exclude the `web_search` tool in your `settings.json`:

```json
{
"tools": {
"exclude": ["web_search"]
}
}
```

## `web_search` examples
**Note:** This setting requires a restart of Qwen Code to take effect. Once disabled, the `web_search` tool will not be available to the model, even if web search providers are configured.

## Usage Examples

Get information on a topic:
### Basic search (using default provider)

```
web_search(query="latest advancements in AI-powered code generation")
web_search(query="latest advancements in AI")
```

### Search with specific provider

```
web_search(query="latest advancements in AI", provider="tavily")
```

### Real-world examples

```
web_search(query="weather in San Francisco today")
web_search(query="latest Node.js LTS version", provider="google")
web_search(query="best practices for React 19", provider="dashscope")
```

## Provider Details

### DashScope (Official)

- **Cost:** Free
- **Authentication:** Automatically available when using Qwen OAuth authentication
- **Configuration:** No API key required, automatically added to provider list for Qwen OAuth users
- **Quota:** 200 requests/minute, 2000 requests/day
- **Best for:** General queries, always available as fallback for Qwen OAuth users
- **Auto-registration:** If you're using Qwen OAuth, DashScope is automatically added to your provider list even if you don't configure it explicitly

### Tavily

- **Cost:** Requires API key (paid service with free tier)
- **Sign up:** https://tavily.com
- **Features:** High-quality results with AI-generated answers
- **Best for:** Research, comprehensive answers with citations

### Google Custom Search

- **Cost:** Free tier available (100 queries/day)
- **Setup:**
1. Enable Custom Search API in Google Cloud Console
2. Create a Custom Search Engine at https://programmablesearchengine.google.com
- **Features:** Google's search quality
- **Best for:** Specific, factual queries

## Important Notes

- **Response format:** Returns a concise answer with numbered source citations
- **Citations:** Source links are appended as a numbered list: [1], [2], etc.
- **Multiple providers:** If one provider fails, manually specify another using the `provider` parameter
- **DashScope availability:** Automatically available for Qwen OAuth users, no configuration needed
- **Default provider selection:** The system automatically selects a default provider based on availability:
1. Your explicit `default` configuration (highest priority)
2. CLI argument `--web-search-default`
3. First available provider by priority: Tavily > Google > DashScope

## Troubleshooting

**Tool not available?**

- **For Qwen OAuth users:** The tool is automatically registered with DashScope provider, no configuration needed
- **For other authentication types:** Ensure at least one provider (Tavily or Google) is configured
- For Tavily/Google: Verify your API keys are correct

**Provider-specific errors?**

- Use the `provider` parameter to try a different search provider
- Check your API quotas and rate limits
- Verify API keys are properly set in configuration

## Important notes
**Need help?**

- **Response returned:** The `web_search` tool returns a concise answer when available, with a list of source links.
- **Citations:** Source links are appended as a numbered list.
- **API key:** Configure `TAVILY_API_KEY` via settings.json, environment variables, .env files, or command line arguments. If not configured, the tool is not registered.
- Check your configuration: Run `qwen` and use the settings dialog
- View your current settings in `~/.qwen-code/settings.json` (macOS/Linux) or `%USERPROFILE%\.qwen-code\settings.json` (Windows)
47 changes: 43 additions & 4 deletions integration-tests/web_search.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,53 @@ import { TestRig, printDebugInfo, validateModelOutput } from './test-helper.js';

describe('web_search', () => {
it('should be able to search the web', async () => {
// Skip if Tavily key is not configured
if (!process.env['TAVILY_API_KEY']) {
console.warn('Skipping web search test: TAVILY_API_KEY not set');
// Check if any web search provider is available
const hasTavilyKey = !!process.env['TAVILY_API_KEY'];
const hasGoogleKey =
!!process.env['GOOGLE_API_KEY'] &&
!!process.env['GOOGLE_SEARCH_ENGINE_ID'];

// Skip if no provider is configured
// Note: DashScope provider is automatically available for Qwen OAuth users,
// but we can't easily detect that in tests without actual OAuth credentials
if (!hasTavilyKey && !hasGoogleKey) {
console.warn(
'Skipping web search test: No web search provider configured. ' +
'Set TAVILY_API_KEY or GOOGLE_API_KEY+GOOGLE_SEARCH_ENGINE_ID environment variables.',
);
return;
}

const rig = new TestRig();
await rig.setup('should be able to search the web');
// Configure web search in settings if provider keys are available
const webSearchSettings: Record<string, unknown> = {};
const providers: Array<{
type: string;
apiKey?: string;
searchEngineId?: string;
}> = [];

if (hasTavilyKey) {
providers.push({ type: 'tavily', apiKey: process.env['TAVILY_API_KEY'] });
}
if (hasGoogleKey) {
providers.push({
type: 'google',
apiKey: process.env['GOOGLE_API_KEY'],
searchEngineId: process.env['GOOGLE_SEARCH_ENGINE_ID'],
});
}

if (providers.length > 0) {
webSearchSettings.webSearch = {
provider: providers,
default: providers[0]?.type,
};
}

await rig.setup('should be able to search the web', {
settings: webSearchSettings,
});

let result;
try {
Expand Down
28 changes: 23 additions & 5 deletions packages/cli/src/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import { mcpCommand } from '../commands/mcp.js';

import { isWorkspaceTrusted } from './trustedFolders.js';
import type { ExtensionEnablementManager } from './extensions/extensionEnablement.js';
import { buildWebSearchConfig } from './webSearch.js';

// Simple console logger for now - replace with actual logger if available
const logger = {
Expand Down Expand Up @@ -116,6 +117,9 @@ export interface CliArgs {
proxy: string | undefined;
includeDirectories: string[] | undefined;
tavilyApiKey: string | undefined;
googleApiKey: string | undefined;
googleSearchEngineId: string | undefined;
webSearchDefault: string | undefined;
screenReader: boolean | undefined;
vlmSwitchMode: string | undefined;
useSmartEdit: boolean | undefined;
Expand Down Expand Up @@ -323,7 +327,20 @@ export async function parseArguments(settings: Settings): Promise<CliArgs> {
})
.option('tavily-api-key', {
type: 'string',
description: 'Tavily API key for web search functionality',
description: 'Tavily API key for web search',
})
.option('google-api-key', {
type: 'string',
description: 'Google Custom Search API key',
})
.option('google-search-engine-id', {
type: 'string',
description: 'Google Custom Search Engine ID',
})
.option('web-search-default', {
type: 'string',
description:
'Default web search provider (dashscope, tavily, google)',
})
.option('screen-reader', {
type: 'boolean',
Expand Down Expand Up @@ -749,10 +766,11 @@ export async function loadCliConfig(
: argv.openaiLogging) ?? false,
},
cliVersion: await getCliVersion(),
tavilyApiKey:
argv.tavilyApiKey ||
settings.advanced?.tavilyApiKey ||
process.env['TAVILY_API_KEY'],
webSearch: buildWebSearchConfig(
argv,
settings,
settings.security?.auth?.selectedType,
),
summarizeToolOutput: settings.model?.summarizeToolOutput,
ideMode,
chatCompression: settings.model?.chatCompression,
Expand Down
Loading