feat(brave-search): Update GPT4Brain tools and add WebSearchTool (#2576)

# Description

Please include a summary of the changes and the related issue. Please
also include relevant motivation and context.

## Checklist before requesting a review

Please delete options that are not relevant.

- [ ] My code follows the style guidelines of this project
- [ ] I have performed a self-review of my code
- [ ] I have commented hard-to-understand areas
- [ ] I have ideally added tests that prove my fix is effective or that
my feature works
- [ ] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged

## Screenshots (if appropriate):
This commit is contained in:
Stan Girard 2024-05-10 12:22:15 +02:00 committed by GitHub
parent 03ebbe70fe
commit a4e2104cad
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 145 additions and 19 deletions

View File

@ -37,9 +37,6 @@ CELEBRY_BROKER_QUEUE_NAME=quivr-preview.fifo
QUIVR_DOMAIN=http://localhost:3000/ QUIVR_DOMAIN=http://localhost:3000/
#COHERE_API_KEY=CHANGE_ME #COHERE_API_KEY=CHANGE_ME
#RESEND #RESEND
RESEND_API_KEY=<change-me> RESEND_API_KEY=<change-me>
RESEND_EMAIL_ADDRESS=onboarding@resend.dev RESEND_EMAIL_ADDRESS=onboarding@resend.dev
@ -48,9 +45,9 @@ RESEND_CONTACT_SALES_TO=<change-me>
CRAWL_DEPTH=1 CRAWL_DEPTH=1
PREMIUM_MAX_BRAIN_NUMBER=30 PREMIUM_MAX_BRAIN_NUMBER=30
PREMIUM_MAX_BRAIN_SIZE=10000000 PREMIUM_MAX_BRAIN_SIZE=10000000
PREMIUM_DAILY_CHAT_CREDIT=100 PREMIUM_DAILY_CHAT_CREDIT=100
# BRAVE SEARCH API KEY
#BRAVE_SEARCH_API_KEY=CHANGE_ME

View File

@ -1,16 +1,9 @@
import json import json
import operator import operator
from typing import Annotated, AsyncIterable, List, Optional, Sequence, Type, TypedDict from typing import Annotated, AsyncIterable, List, Sequence, TypedDict
from uuid import UUID from uuid import UUID
from langchain.callbacks.manager import (
AsyncCallbackManagerForToolRun,
CallbackManagerForToolRun,
)
from langchain.pydantic_v1 import BaseModel as BaseModelV1
from langchain.pydantic_v1 import Field as FieldV1
from langchain.tools import BaseTool from langchain.tools import BaseTool
from langchain_community.tools import DuckDuckGoSearchResults
from langchain_core.messages import BaseMessage, ToolMessage from langchain_core.messages import BaseMessage, ToolMessage
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.tools import BaseTool from langchain_core.tools import BaseTool
@ -22,9 +15,7 @@ from modules.brain.knowledge_brain_qa import KnowledgeBrainQA
from modules.chat.dto.chats import ChatQuestion from modules.chat.dto.chats import ChatQuestion
from modules.chat.dto.outputs import GetChatHistoryOutput from modules.chat.dto.outputs import GetChatHistoryOutput
from modules.chat.service.chat_service import ChatService from modules.chat.service.chat_service import ChatService
from openai import OpenAI from modules.tools import ImageGeneratorTool, WebSearchTool
from pydantic import BaseModel
from modules.tools import ImageGeneratorTool
class AgentState(TypedDict): class AgentState(TypedDict):
@ -37,6 +28,7 @@ logger = get_logger(__name__)
chat_service = ChatService() chat_service = ChatService()
class GPT4Brain(KnowledgeBrainQA): class GPT4Brain(KnowledgeBrainQA):
"""This is the Notion brain class. it is a KnowledgeBrainQA has the data is stored locally. """This is the Notion brain class. it is a KnowledgeBrainQA has the data is stored locally.
It is going to call the Data Store internally to get the data. It is going to call the Data Store internally to get the data.
@ -45,7 +37,7 @@ class GPT4Brain(KnowledgeBrainQA):
KnowledgeBrainQA (_type_): A brain that store the knowledge internaly KnowledgeBrainQA (_type_): A brain that store the knowledge internaly
""" """
tools: List[BaseTool] = [DuckDuckGoSearchResults(), ImageGeneratorTool()] tools: List[BaseTool] = [WebSearchTool(), ImageGeneratorTool()]
tool_executor: ToolExecutor = ToolExecutor(tools) tool_executor: ToolExecutor = ToolExecutor(tools)
model_function: ChatOpenAI = None model_function: ChatOpenAI = None

View File

@ -1,2 +1,3 @@
from .image_generator import ImageGeneratorTool from .image_generator import ImageGeneratorTool
from .web_search import WebSearchTool

View File

@ -0,0 +1,80 @@
import os
from typing import Dict, Optional, Type
import requests
from langchain.callbacks.manager import (
AsyncCallbackManagerForToolRun,
CallbackManagerForToolRun,
)
from langchain.pydantic_v1 import BaseModel as BaseModelV1
from langchain.pydantic_v1 import Field as FieldV1
from langchain_core.tools import BaseTool
from logger import get_logger
from pydantic import BaseModel
logger = get_logger(__name__)
class WebSearchInput(BaseModelV1):
query: str = FieldV1(..., title="query", description="search query to look up")
class WebSearchTool(BaseTool):
name = "brave-web-search"
description = "useful for when you need to search the web for something."
args_schema: Type[BaseModel] = WebSearchInput
api_key = os.getenv("BRAVE_SEARCH_API_KEY")
def _check_environment_variable(self) -> bool:
"""Check if the environment variable is set."""
return os.getenv("BRAVE_SEARCH_API_KEY") is not None
def __init__(self):
if not self._check_environment_variable():
raise ValueError("BRAVE_SEARCH_API_KEY environment variable is not set")
super().__init__()
def _run(
self, query: str, run_manager: Optional[CallbackManagerForToolRun] = None
) -> Dict:
"""Run the tool."""
headers = {
"Accept": "application/json",
"Accept-Encoding": "gzip",
"X-Subscription-Token": self.api_key,
}
response = requests.get(
f"https://api.search.brave.com/res/v1/web/search?q={query}&count=3",
headers=headers,
)
return self._parse_response(response.json())
async def _arun(
self, query: str, run_manager: Optional[AsyncCallbackManagerForToolRun] = None
) -> Dict:
"""Run the tool asynchronously."""
headers = {
"Accept": "application/json",
"Accept-Encoding": "gzip",
"X-Subscription-Token": self.api_key,
}
response = requests.get(
f"https://api.search.brave.com/res/v1/web/search?q={query}&count=3",
headers=headers,
)
return self._parse_response(response.json())
def _parse_response(self, response: Dict) -> str:
"""Parse the response."""
short_results = []
results = response["web"]["results"]
for result in results:
title = result["title"]
url = result["url"]
description = result["description"]
short_results.append(self._format_result(title, description, url))
return "\n".join(short_results)
def _format_result(self, title: str, description: str, url: str) -> str:
return f"**{title}**\n{description}\n{url}"

View File

@ -19,7 +19,6 @@ class CrawlWebsite(BaseModel):
def process(self): def process(self):
# Extract and combine content recursively # Extract and combine content recursively
visited_urls = set()
loader = PlaywrightURLLoader( loader = PlaywrightURLLoader(
urls=[self.url], remove_selectors=["header", "footer"] urls=[self.url], remove_selectors=["header", "footer"]
) )

View File

@ -0,0 +1,42 @@
---
title: Configuring Brave Search in Quivr
description: A guide on how to integrate Brave Search into Quivr by obtaining and configuring the BRAVE_SEARCH_API_KEY.
---
# Configuring Brave Search in Quivr
Integrating Brave Search into Quivr enhances your search capabilities by leveraging the privacy-focused search engine. This guide will walk you through the process of obtaining a Brave Search API key and configuring it in Quivr.
## Step 1: Create a Brave Search Account
To use Brave Search's API, you first need to create an account with Brave Search. Follow these steps:
1. Visit [Brave Search](https://search.brave.com/) and click on the "Sign Up" button.
2. Follow the on-screen instructions to create your account.
## Step 2: Obtain the API Key
Once you have a Brave Search account, you can obtain an API key:
1. Log in to your Brave Search account.
2. Navigate to the API section (this might be located in your account settings or developer settings).
3. Generate a new API key for your application. Note this key as you will need it for the next step.
## Step 3: Configure the BRAVE_SEARCH_API_KEY in Quivr
With your Brave Search API key in hand, you can now configure it in Quivr:
1. Open your Quivr project's `.env` file.
2. Add the following line to the file:
```
BRAVE_SEARCH_API_KEY=your_brave_search_api_key_here
```
Replace `your_brave_search_api_key_here` with the actual API key you obtained from Brave Search.
3. Save the `.env` file.
## Conclusion
You have successfully integrated Brave Search into Quivr. Your searches will now leverage the privacy-focused and efficient search capabilities of Brave Search.
For any issues or further configuration options, refer to the Brave Search API documentation or contact Quivr support.

View File

@ -59,3 +59,17 @@ The frontend environment file is used to configure the frontend application. It
- `NEXT_PUBLIC_STRIPE_MANAGE_PLAN_URL`: The URL for managing Stripe subscription plans. - `NEXT_PUBLIC_STRIPE_MANAGE_PLAN_URL`: The URL for managing Stripe subscription plans.
- `NEXT_PUBLIC_AUTH_MODES`: The authentication modes supported by the application, such as magic link, password-based authentication, and Google Single Sign-On (SSO). - `NEXT_PUBLIC_AUTH_MODES`: The authentication modes supported by the application, such as magic link, password-based authentication, and Google Single Sign-On (SSO).
### Configuring BRAVE_SEARCH_API_KEY
To use the Brave Search functionality within Quivr, you need to configure the `BRAVE_SEARCH_API_KEY` in your environment. Here's how to obtain and set up your API key:
1. **Create a Brave Search Account**: Visit [Brave Search](https://api.search.brave.com/app/keys) and sign up for an account if you haven't already.
2. **Obtain API Key**: Once logged in, navigate to the developer settings or API section to generate a new API key for your application.
3. **Configure .env File**: Add the following line to your `.env` file in the root of the Quivr project:
```
BRAVE_SEARCH_API_KEY=your_brave_search_api_key_here
```
Replace `your_brave_search_api_key_here` with the actual API key you obtained from Brave Search.
By configuring the `BRAVE_SEARCH_API_KEY`, you enable Quivr to perform web searches using Brave Search's capabilities directly from within the application.

View File

@ -70,7 +70,8 @@
"configuring/environment-variables", "configuring/environment-variables",
"configuring/profiler", "configuring/profiler",
"configuring/telemetry", "configuring/telemetry",
"configuring/supabase-setup" "configuring/supabase-setup",
"configuring/brave-search"
] ]
}, },
"tech-design", "tech-design",