mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-16 16:30:15 +01:00
* WIP: initial logging changes add several transports in ~/config/winston omit messages in logs, truncate long strings add short blurb in dotenv for debug logging GoogleClient: using logger OpenAIClient: using logger, handleOpenAIErrors Adding typedef for payload message bumped winston and using winston-daily-rotate-file moved config for server paths to ~/config dir Added `DEBUG_LOGGING=true` to .env.example * WIP: Refactor logging statements in code * WIP: Refactor logging statements and import configurations * WIP: Refactor logging statements and import configurations * refactor: broadcast Redis initialization message with `info` not `debug` * refactor: complete Refactor logging statements and import configurations * chore: delete unused tools * fix: circular dependencies due to accessing logger * refactor(handleText): handle booleans and write tests * refactor: redact sensitive values, better formatting * chore: improve log formatting, avoid passing strings to 2nd arg * fix(ci): fix jest tests due to logger changes * refactor(getAvailablePluginsController): cache plugins as they are static and avoids async addOpenAPISpecs call every time * chore: update docs * chore: update docs * chore: create separate meiliSync logger, clean up logs to avoid being unnecessarily verbose * chore: spread objects where they are commonly logged to allow string truncation * chore: improve error log formatting
121 lines
3.3 KiB
JavaScript
121 lines
3.3 KiB
JavaScript
const { google } = require('googleapis');
|
|
const { Tool } = require('langchain/tools');
|
|
const { logger } = require('~/config');
|
|
|
|
/**
|
|
* Represents a tool that allows an agent to use the Google Custom Search API.
|
|
* @extends Tool
|
|
*/
|
|
class GoogleSearchAPI extends Tool {
|
|
constructor(fields = {}) {
|
|
super();
|
|
this.cx = fields.GOOGLE_CSE_ID || this.getCx();
|
|
this.apiKey = fields.GOOGLE_API_KEY || this.getApiKey();
|
|
this.customSearch = undefined;
|
|
}
|
|
|
|
/**
|
|
* The name of the tool.
|
|
* @type {string}
|
|
*/
|
|
name = 'google';
|
|
|
|
/**
|
|
* A description for the agent to use
|
|
* @type {string}
|
|
*/
|
|
description =
|
|
'Use the \'google\' tool to retrieve internet search results relevant to your input. The results will return links and snippets of text from the webpages';
|
|
description_for_model =
|
|
'Use the \'google\' tool to retrieve internet search results relevant to your input. The results will return links and snippets of text from the webpages';
|
|
|
|
getCx() {
|
|
const cx = process.env.GOOGLE_CSE_ID || '';
|
|
if (!cx) {
|
|
throw new Error('Missing GOOGLE_CSE_ID environment variable.');
|
|
}
|
|
return cx;
|
|
}
|
|
|
|
getApiKey() {
|
|
const apiKey = process.env.GOOGLE_API_KEY || '';
|
|
if (!apiKey) {
|
|
throw new Error('Missing GOOGLE_API_KEY environment variable.');
|
|
}
|
|
return apiKey;
|
|
}
|
|
|
|
getCustomSearch() {
|
|
if (!this.customSearch) {
|
|
const version = 'v1';
|
|
this.customSearch = google.customsearch(version);
|
|
}
|
|
return this.customSearch;
|
|
}
|
|
|
|
resultsToReadableFormat(results) {
|
|
let output = 'Results:\n';
|
|
|
|
results.forEach((resultObj, index) => {
|
|
output += `Title: ${resultObj.title}\n`;
|
|
output += `Link: ${resultObj.link}\n`;
|
|
if (resultObj.snippet) {
|
|
output += `Snippet: ${resultObj.snippet}\n`;
|
|
}
|
|
|
|
if (index < results.length - 1) {
|
|
output += '\n';
|
|
}
|
|
});
|
|
|
|
return output;
|
|
}
|
|
|
|
/**
|
|
* Calls the tool with the provided input and returns a promise that resolves with a response from the Google Custom Search API.
|
|
* @param {string} input - The input to provide to the API.
|
|
* @returns {Promise<String>} A promise that resolves with a response from the Google Custom Search API.
|
|
*/
|
|
async _call(input) {
|
|
try {
|
|
const metadataResults = [];
|
|
const response = await this.getCustomSearch().cse.list({
|
|
q: input,
|
|
cx: this.cx,
|
|
auth: this.apiKey,
|
|
num: 5, // Limit the number of results to 5
|
|
});
|
|
|
|
// return response.data;
|
|
// logger.debug(response.data);
|
|
|
|
if (!response.data.items || response.data.items.length === 0) {
|
|
return this.resultsToReadableFormat([
|
|
{ title: 'No good Google Search Result was found', link: '' },
|
|
]);
|
|
}
|
|
|
|
// const results = response.items.slice(0, numResults);
|
|
const results = response.data.items;
|
|
|
|
for (const result of results) {
|
|
const metadataResult = {
|
|
title: result.title || '',
|
|
link: result.link || '',
|
|
};
|
|
if (result.snippet) {
|
|
metadataResult.snippet = result.snippet;
|
|
}
|
|
metadataResults.push(metadataResult);
|
|
}
|
|
|
|
return this.resultsToReadableFormat(metadataResults);
|
|
} catch (error) {
|
|
logger.error('[GoogleSearchAPI]', error);
|
|
// throw error;
|
|
return 'There was an error searching Google.';
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = GoogleSearchAPI;
|