Enable /search followups

Kaveen Kumarasinghe 1 year ago
parent a105534490
commit a864dea936

@ -24,9 +24,9 @@ SUPPORT SERVER FOR BOT SETUP: https://discord.gg/WvAHXDMS7Q (You can try out the
# Recent Notable Updates
- **AI-Assisted Google Search** - Use GPT3 to browse the internet, you can search the internet for a query and GPT3 will look at the top websites for you automatically and formulate an answer to your query!
- **AI-Assisted Google Search** - Use GPT3 to browse the internet, you can search the internet for a query and GPT3 will look at the top websites for you automatically and formulate an answer to your query! You can also ask follow-up questions, this is kinda like BingGPT, but much better lol!
<p align="center"/>
<img src="https://i.imgur.com/Y3iiRfh.png"/>
<img src="https://i.imgur.com/YxkS0S5.png"/>
</p>
- **CUSTOM INDEXES** - This is a huge update. You can now upload files to your discord server and use them as a source of knowledge when asking GPT3 questions. You can also use webpage links as context, images, full documents, csvs, powerpoints, audio files, and even **youtube videos**! Read more in the 'Custom Indexes' section below.

@ -40,7 +40,7 @@ class SearchService(discord.Cog, name="SearchService"):
self.redo_users = {}
# Make a mapping of all the country codes and their full country names:
async def paginate_embed(self, response_text, user: discord.Member):
async def paginate_embed(self, response_text, user: discord.Member, original_link=None):
"""Given a response text make embed pages and return a list of the pages. Codex makes it a codeblock in the embed"""
response_text = [
@ -53,14 +53,16 @@ class SearchService(discord.Cog, name="SearchService"):
for count, chunk in enumerate(response_text, start=1):
if not first:
page = discord.Embed(
title=f"Search Results",
title=f"Search Results" if not original_link else f"Follow-up results",
description=chunk,
url=original_link,
)
first = True
else:
page = discord.Embed(
title=f"Page {count}",
description=chunk,
url=original_link,
)
if user.avatar:
page.set_footer(
@ -82,6 +84,7 @@ class SearchService(discord.Cog, name="SearchService"):
nodes,
deep,
redo=None,
from_followup=None,
):
"""Command handler for the translation command"""
user_api_key = None
@ -126,19 +129,29 @@ class SearchService(discord.Cog, name="SearchService"):
)
urls = "\n".join(f"<{url}>" for url in urls)
query_response_message = f"**Question:**\n\n`{query.strip()}`\n\n**Google Search Query**\n\n`{refined_text.strip()}`\n\n**Final Answer:**\n\n{response.response.strip()}\n\n**Sources:**\n{urls}"
if from_followup:
original_link, followup_question = from_followup.original_link, from_followup.followup_question
query_response_message = f"**Question:**\n\n`{followup_question}`\n\n**Google Search Query**\n\n`{refined_text.strip()}`\n\n**Final Answer:**\n\n{response.response.strip()}\n\n**Sources:**\n{urls}"
else:
query_response_message = f"**Question:**\n\n`{query.strip()}`\n\n**Google Search Query**\n\n`{refined_text.strip()}`\n\n**Final Answer:**\n\n{response.response.strip()}\n\n**Sources:**\n{urls}"
query_response_message = query_response_message.replace(
"<|endofstatement|>", ""
)
query_response_message = query_response_message.replace(
"Answer to original:\n", ""
)
query_response_message = query_response_message.replace(
"Answer to follow-up:\n", ""
)
# If the response is too long, lets paginate using the discord pagination
# helper
embed_pages = await self.paginate_embed(query_response_message, ctx.user)
embed_pages = await self.paginate_embed(query_response_message, ctx.user, original_link if from_followup else None)
paginator = pages.Paginator(
pages=embed_pages,
timeout=None,
author_check=False,
custom_view=RedoButton(ctx, self),
custom_view=SearchView(ctx, self, query_response_message),
)
self.redo_users[ctx.user.id] = RedoSearchUser(ctx, query, search_scope, nodes)
@ -146,16 +159,47 @@ class SearchService(discord.Cog, name="SearchService"):
await paginator.respond(ctx.interaction)
class SearchView(discord.ui.View):
def __init__(
self,
ctx,
search_cog,
response_text,
):
super().__init__(timeout=3600) # 1 hour interval to redo.
self.search_cog = search_cog
self.ctx = ctx
self.response_text = response_text
self.add_item(RedoButton(self.ctx, self.search_cog))
self.add_item(FollowupButton(self.ctx, self.search_cog, self.response_text))
# A view for a follow-up button
class FollowupButton(discord.ui.Button["SearchView"]):
def __init__(self, ctx, search_cog, response_text):
super().__init__(label="Follow Up", style=discord.ButtonStyle.green)
self.search_cog = search_cog
self.ctx = ctx
self.response_text = response_text
async def callback(self, interaction: discord.Interaction):
"""Send the followup modal"""
await interaction.response.send_modal(modal=FollowupModal(self.ctx, self.search_cog, self.response_text))
# A view for a redo button
class RedoButton(discord.ui.View):
def __init__(self, ctx: discord.ApplicationContext, search_cog):
super().__init__()
class RedoButton(discord.ui.Button["SearchView"]):
def __init__(self, ctx, search_cog):
super().__init__(
style=discord.ButtonStyle.danger,
label="Redo",
custom_id="redo_search_button",
)
self.ctx = ctx
self.search_cog = search_cog
@discord.ui.button(label="Redo", style=discord.ButtonStyle.danger)
async def redo(self, button: discord.ui.Button, interaction: discord.Interaction):
"""Redo the translation"""
async def callback(self, interaction: discord.Interaction):
"""Redo the search"""
await interaction.response.send_message(
"Redoing search...", ephemeral=True, delete_after=15
)
@ -167,3 +211,46 @@ class RedoButton(discord.ui.View):
deep=False,
redo=True,
)
class FollowupData:
def __init__(self, original_link, followup_question):
self.original_link = original_link
self.followup_question = followup_question
# The modal for following up
class FollowupModal(discord.ui.Modal):
def __init__(self, ctx, search_cog, response_text) -> None:
super().__init__(title="Search Follow-up")
# Get the argument named "user_key_db" and save it as USER_KEY_DB
self.search_cog = search_cog
self.ctx = ctx
self.response_text = response_text
self.add_item(
discord.ui.InputText(
label="What other questions do you have?",
placeholder="",
)
)
async def callback(self, interaction: discord.Interaction):
await interaction.response.defer()
query = self.search_cog.redo_users[self.ctx.user.id].query
# In the response text, get only the text between "**Final Answer:**" and "**Sources:**"
self.response_text = self.response_text.split("**Final Answer:**")[1].split("**Sources:**")[0]
# Build the context
context_text = "Original question: "+query+"\n"+"Answer to original: "+self.response_text+"\n"+"Follow-up question: "+self.children[0].value
# Get the link of the message that the user interacted on
message_link = f"https://discord.com/channels/{interaction.guild_id}/{interaction.channel_id}/{interaction.message.id}"
await self.search_cog.search_command(
self.search_cog.redo_users[self.ctx.user.id].ctx,
context_text,
self.search_cog.redo_users[self.ctx.user.id].search_scope,
self.search_cog.redo_users[self.ctx.user.id].nodes,
deep=False,
redo=True,
from_followup=FollowupData(message_link, self.children[0].value),
)

Loading…
Cancel
Save