Spaces:
reon314
/
Runtime error

File size: 3,207 Bytes
3b6afc0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
const { Tool } = require('langchain/tools');
const { google } = require('googleapis');

/**
 * 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';

  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;
      // console.log(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) {
      console.log(`Error searching Google: ${error}`);
      // throw error;
      return 'There was an error searching Google.';
    }
  }
}

module.exports = GoogleSearchAPI;