web_reader / src /services /serp /internal.ts
nomagick's picture
saas(search): switch to internal serp
1e5e94f unverified
import { singleton } from 'tsyringe';
import { GlobalLogger } from '../logger';
import { SecretExposer } from '../../shared/services/secrets';
import { AsyncLocalContext } from '../async-context';
import { SerperSearchQueryParams } from '../../shared/3rd-party/serper-search';
import { BlackHoleDetector } from '../blackhole-detector';
import { AsyncService } from 'civkit/async-service';
import { JinaSerpApiHTTP } from '../../shared/3rd-party/internal-serp';
import { WebSearchEntry } from './compat';
@singleton()
export class InternalJinaSerpService extends AsyncService {
logger = this.globalLogger.child({ service: this.constructor.name });
client!: JinaSerpApiHTTP;
constructor(
protected globalLogger: GlobalLogger,
protected secretExposer: SecretExposer,
protected threadLocal: AsyncLocalContext,
protected blackHoleDetector: BlackHoleDetector,
) {
super(...arguments);
}
override async init() {
await this.dependencyReady();
this.emit('ready');
this.client = new JinaSerpApiHTTP(this.secretExposer.JINA_SERP_API_KEY);
}
async doSearch(variant: 'web' | 'images' | 'news', query: SerperSearchQueryParams) {
this.logger.debug(`Doing external search`, query);
let results;
switch (variant) {
// case 'images': {
// const r = await this.client.imageSearch(query);
// results = r.parsed.images;
// break;
// }
// case 'news': {
// const r = await this.client.newsSearch(query);
// results = r.parsed.news;
// break;
// }
case 'web':
default: {
const r = await this.client.webSearch(query);
results = r.parsed.results?.map((x) => ({ ...x, link: x.url }));
break;
}
}
this.blackHoleDetector.itWorked();
return results as WebSearchEntry[];
}
async webSearch(query: SerperSearchQueryParams) {
return this.doSearch('web', query);
}
async imageSearch(query: SerperSearchQueryParams) {
return this.doSearch('images', query);
}
async newsSearch(query: SerperSearchQueryParams) {
return this.doSearch('news', query);
}
}