search: introduce serper search provider

This commit is contained in:
yanlong.wang 2025-02-20 13:49:16 +08:00
parent 13cfd57dbb
commit 4decc9a750
No known key found for this signature in database
GPG Key ID: C0A623C0BADF9F37
6 changed files with 71 additions and 1 deletions

View File

@ -6,6 +6,7 @@
"OPENAI_API_KEY": "",
"JINA_API_KEY": "",
"BRAVE_API_KEY": "",
"SERPER_API_KEY": "",
"DEFAULT_MODEL_NAME": ""
},
"defaults": {

View File

@ -9,7 +9,7 @@
"DEFAULT_MODEL_NAME": ""
},
"defaults": {
"search_provider": "brave",
"search_provider": "serper",
"llm_provider": "vertex",
"step_sleep": 0
},

View File

@ -18,6 +18,7 @@ import {search} from "./tools/jina-search";
import {zodToJsonSchema} from "zod-to-json-schema";
import {ObjectGeneratorSafe} from "./utils/safe-generator";
import {CodeSandbox} from "./tools/code-sandbox";
import { serperSearch } from './tools/serper-search';
async function sleep(ms: number) {
const seconds = Math.ceil(ms / 1000);
@ -618,6 +619,22 @@ But then you realized you have asked them before. You decided to to think out of
}
await sleep(STEP_SLEEP)
break;
case 'serper':
try {
const {response} = await serperSearch(query);
results = {
results: response.organic?.map(r => ({
title: r.title,
url: r.link,
description: r.snippet
})) || []
};
} catch (error) {
console.error('Serper search failed:', error);
results = {results: []};
}
await sleep(STEP_SLEEP)
break;
default:
results = {results: []};
}

View File

@ -43,6 +43,7 @@ export const GEMINI_API_KEY = env.GEMINI_API_KEY;
export const OPENAI_API_KEY = env.OPENAI_API_KEY;
export const JINA_API_KEY = env.JINA_API_KEY;
export const BRAVE_API_KEY = env.BRAVE_API_KEY;
export const SERPER_API_KEY = env.SERPER_API_KEY;
export const SEARCH_PROVIDER = configJson.defaults.search_provider;
export const STEP_SLEEP = configJson.defaults.step_sleep;

View File

@ -0,0 +1,21 @@
import axios from 'axios';
import { SERPER_API_KEY } from "../config";
import { SerperSearchResponse } from '../types';
export async function serperSearch(query: string): Promise<{ response: SerperSearchResponse }> {
const response = await axios.post<SerperSearchResponse>('https://google.serper.dev/search', {
data: JSON.stringify({
q: query,
autocorrect: false,
}),
headers: {
'X-API-KEY': SERPER_API_KEY,
'Content-Type': 'application/json'
},
timeout: 10000
});
// Maintain the same return structure as the original code
return { response: response.data };
}

View File

@ -87,6 +87,36 @@ export interface BraveSearchResponse {
};
}
export interface SerperSearchResponse {
knowledgeGraph?: {
title: string;
type: string;
website: string;
imageUrl: string;
description: string;
descriptionSource: string;
descriptionLink: string;
attributes: { [k: string]: string; };
},
organic: {
title: string;
link: string;
snippet: string;
date: string;
siteLinks?: { title: string; link: string; }[];
position: number,
}[];
topStories?: {
title: string;
link: string;
source: string;
data: string;
imageUrl: string;
}[];
relatedSearches?: string[];
credits: number;
}
export type DedupResponse = {
think: string;
unique_queries: string[];