File

src/star-search/agents/bing-search.agent.ts

Index

Properties
Methods

Constructor

constructor(httpService: HttpService, configService: ConfigService, openAIWrappedService: OpenAIWrappedService)
Parameters :
Name Type Optional
httpService HttpService No
configService ConfigService No
openAIWrappedService OpenAIWrappedService No

Methods

Async bingSearch
bingSearch(undefined: SearchBingParams)
Parameters :
Name Type Optional
SearchBingParams No
Private parseBingSearchResults
parseBingSearchResults(searchResults: BingSearchResponse)
Parameters :
Name Type Optional
searchResults BingSearchResponse No
Async runAgentTools
runAgentTools(agentParams: BingSearchAgentParams)
Parameters :
Name Type Optional
agentParams BingSearchAgentParams No
Returns : Promise<string | null | >

Properties

agentSystemMessage
Type : string
Public bingSearchTool
Default value : this.openAIWrappedService.makeRunnableToolFunction({ function: async (params: SearchBingParams) => this.bingSearch(params), schema: SearchBingParams, name: "bingSearch", description: "Searches the internet using an input query.", })
import { Injectable } from "@nestjs/common";
import { HttpService } from "@nestjs/axios";
import { ConfigService } from "@nestjs/config";
import { AxiosResponse } from "@nestjs/terminus/dist/health-indicator/http/axios.interfaces";
import { BingSearchResultDto } from "../dtos/bing-search-results.dto";
import { BingSearchResponse, BingWebPageResult } from "../interfaces/bing-search-result.interface";
import { BingSearchAgentParams, SearchBingParams } from "../schemas/bing.schema";
import { OpenAIWrappedService } from "../../openai-wrapped/openai-wrapped.service";

@Injectable()
export class BingSearchAgent {
  agentSystemMessage: string;

  constructor(
    private httpService: HttpService,
    private configService: ConfigService,
    private openAIWrappedService: OpenAIWrappedService
  ) {
    this.agentSystemMessage = this.configService.get("starsearch.bingAgentSystemMessage")!;
  }

  async bingSearch({ query }: SearchBingParams): Promise<BingSearchResultDto[]> {
    const subscriptionApiKey: string = this.configService.get("bing.subscriptionApiKey")!;
    const endpoint: string = this.configService.get("bing.endpoint")!;

    try {
      const response: AxiosResponse<BingSearchResponse> | undefined = await this.httpService
        .get(endpoint, {
          params: {
            /*
             * the params to Bing search include:
             *
             * q - the query to send to bing.
             * textDecorations - adds metadata to the search results (such as bolding)
             * textFormat - the return format of the resulting text which an LLM can parse
             * count - The number of results to return
             */

            q: query,
            textDecorations: "True",
            textFormat: "HTML",
            count: 10,
          },
          headers: { "Ocp-Apim-Subscription-Key": subscriptionApiKey },
        })
        .toPromise();

      return this.parseBingSearchResults(response!.data);
    } catch (error: unknown) {
      if (error instanceof Error) {
        /*
         * simply bail out and return nothing (so that the LLM tools loop can continue
         * and possibly recover).
         */
        console.log(error);
        return [];
      }

      return [];
    }
  }

  private parseBingSearchResults(searchResults: BingSearchResponse): BingSearchResultDto[] {
    const cleanResults: BingSearchResultDto[] = [];

    searchResults.webPages.value.forEach((result: BingWebPageResult) => {
      const details: BingSearchResultDto = {
        title: result.name,
        url: result.url,
        displayUrl: result.displayUrl ?? result.url,
        snippet: result.snippet,
        datePublished: result.datePublished ?? "date not available",
      };

      cleanResults.push(details);
    });

    return cleanResults;
  }

  public bingSearchTool = this.openAIWrappedService.makeRunnableToolFunction({
    function: async (params: SearchBingParams) => this.bingSearch(params),
    schema: SearchBingParams,
    name: "bingSearch",
    description: "Searches the internet using an input query.",
  });

  async runAgentTools(agentParams: BingSearchAgentParams): Promise<string | null | unknown> {
    const tools = [this.bingSearchTool];

    const runner = this.openAIWrappedService
      .runTools(this.agentSystemMessage, agentParams.prompt, tools)
      .on("message", (msg) => console.log("bing agent msg", msg))
      .on("functionCall", (functionCall) => console.log("bing agent functionCall", functionCall))
      .on("functionCallResult", (functionCallResult) =>
        console.log("bing agent functionCallResult", functionCallResult)
      );

    return runner.finalContent();
  }
}

results matching ""

    No results matching ""