From 5678a6c25f64d5bea3dc7504a6cd0334291578c7 Mon Sep 17 00:00:00 2001 From: Jacob Bryant Date: Thu, 31 Aug 2023 16:09:14 -0400 Subject: [PATCH 01/17] inital link suggestion work --- config.py | 8 ++ index/dapps.py | 106 +++++++++++++++++++++++++++ scrape/dapp_scraper.py | 162 +++++++++++++++++++++++++++++++++++++++++ tools/index_widget.py | 7 +- 4 files changed, 281 insertions(+), 2 deletions(-) create mode 100644 index/dapps.py create mode 100644 scrape/dapp_scraper.py diff --git a/config.py b/config.py index 557b427e..f1e095e2 100644 --- a/config.py +++ b/config.py @@ -19,6 +19,14 @@ text_key="content", extra_keys=["url"], ) + +dapps_index = dict( + type="index.weaviate.WeaviateIndex", + index_name="ThirdPartyDapps", + text_key="description", + extra_keys=["url","name"], +) + api_docs_index = dict( type="index.weaviate.WeaviateIndex", index_name="APIDocsV1", diff --git a/index/dapps.py b/index/dapps.py new file mode 100644 index 00000000..99c51547 --- /dev/null +++ b/index/dapps.py @@ -0,0 +1,106 @@ +# to build the index for dapps, first scrap them from dapplist.com using the scraper +# then run: python -c "from index.dapps import backfill; backfill()" + + +from langchain.docstore.document import Document +from .weaviate import get_client +import json + +INDEX_NAME = "ThirdPartyDapps" +INDEX_DESCRIPTION = "Index of Third party dapps" +DAPP_DESCRIPTION = "description" +DAPP_NAME = "name" +DAPP_URL = "url" + +def delete_schema() -> None: + try: + client = get_client() + client.schema.delete_class(INDEX_NAME) + except Exception as e: + print(f"Error deleting schmea: {str(e)}") + +def create_schema(delete_first: bool = False) -> None: + try: + client = get_client() + if delete_first: + delete_schema() + client.schema.get() + schema = { + "classes": [ + { + "class": INDEX_NAME, + "description": INDEX_DESCRIPTION, + "vectorizer": "text2vec-openai", + "moduleConfig": { + "text2vec-openai": { + "model": "ada", + "modelVersion": "002", + "type": "text" + } + }, + "properties": [ + {"name": DAPP_NAME, "dataType": ["string"]}, + {"name": DAPP_DESCRIPTION, "dataType": ["string"]}, + {"name": DAPP_URL, "dataType": ["string"]}, + { + "name": "twitterHandle", + "dataType": ["string"], + "description": "The Twitter handle of the Dapp" + }, + { + "name": "blogLinks", + "dataType": ["string[]"], + "description": "Links to the blog posts related to the Dapp" + }, + { + "name": "discord", + "dataType": ["string"], + "description": "The Discord server link of the Dapp" + }, + { + "name": "facebook", + "dataType": ["string"], + "description": "The Facebook page link of the Dapp" + }, + { + "name": "instagram", + "dataType": ["string"], + "description": "The Instagram profile link of the Dapp" + }, + { + "name": "telegram", + "dataType": ["string"], + "description": "The Telegram channel link of the Dapp" + } + ] + } + + ] + } + client.schema.create(schema) + except Exception as e: + print(f"Error creating schema: {str(e)}") + +def backfill(): + try: + from langchain.vectorstores import Weaviate + + with open('./knowledge_base/dapp-list.json') as f: + dapp_list = json.load(f) + + # Extract the 'id' field from each dapp and store it in the 'documents' list + documents = [d.pop("name") for d in dapp_list] + + # Use the remaining fields in each dapp to populate the 'metadatas' list + # is this the best 'metadatas' to use? + metadatas = dapp_list + + create_schema(delete_first=True) + + client = get_client() + w = Weaviate(client, INDEX_NAME, DAPP_NAME) # is this a proper 3rd argument? + w.add_texts(documents, metadatas) + except Exception as e: + print(f"Error during backfill in dapps.py {str(e)}") + + diff --git a/scrape/dapp_scraper.py b/scrape/dapp_scraper.py new file mode 100644 index 00000000..85b32b4d --- /dev/null +++ b/scrape/dapp_scraper.py @@ -0,0 +1,162 @@ +import requests +import json +import os +from typing import List + +BROWSERLESS_API_KEY = os.getenv('BROWSERLESS_API_KEY', '') +SCRAPE_API_URL = f'https://chrome.browserless.io/scrape?token={BROWSERLESS_API_KEY}' + +# scrape a URL for IPFS links, return +def get_ipfs_links_from_url(url: str) -> List[str]: + + # specify what elements to return - in this case IFPS links + payload = json.dumps({ + "url": url, + "elements": [ + { + "selector": "a[href*='ipfs.io']", + }, + ], + }) + + # make the request + r = requests.post(SCRAPE_API_URL, headers={ + 'Cache-Control': 'no-cache', + 'Content-Type': 'application/json', + }, data=payload) + + # response text + response = r.text + + # Parse the JSON string into a dictionary + data = json.loads(response) + + # Access the items in the 'results' key + results = data['data'][0]['results'] + + # instantiate array to hold cleaned URLs + cleaned_ipfs_urls = [] + + # loop through response data, build array of just the IPFS links + for result in results: + href_value = None + for attribute in result["attributes"]: + if attribute["name"] == "href": + href_value = attribute["value"] + break + + if href_value: + cleaned_ipfs_urls.append(href_value) + + # return links arr + return cleaned_ipfs_urls + + +def scrape_ipfs_links(url: str = 'https://thedapplist.com/curate?status=All&q=') -> str: + + payload = json.dumps({ + "url": url, + "elements": [ + { + "selector": "a[href*='ipfs.io']", + }, + ], + }) + + r = requests.post(SCRAPE_API_URL, headers={ + 'Cache-Control': 'no-cache', + 'Content-Type': 'application/json', + }, data=payload) + + # Assuming the value from r.text is stored in the 'response' variable + response = r.text + + # Parse the JSON string into a dictionary + data = json.loads(response) + + # Access the items in the 'results' key from the browserless response + results = data['data'][0]['results'] + cleaned_ipfs_urls = [] + + for result in results: + href_value = None + for attribute in result["attributes"]: + if attribute["name"] == "href": + href_value = attribute["value"] + break + + if href_value: + cleaned_ipfs_urls.append(href_value) + + headers = { + 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', + 'Accept-Language': 'en-US,en;q=0.9', + 'Cache-Control': 'no-cache', + 'Pragma': 'no-cache', + 'Sec-Ch-Ua': '"Not.A/Brand";v="8", "Chromium";v="114", "Google Chrome";v="114"', + 'Sec-Ch-Ua-Mobile': '?0', + 'Sec-Ch-Ua-Platform': '"macOS"', + 'Sec-Fetch-Dest': 'document', + 'Sec-Fetch-Mode': 'navigate', + 'Sec-Fetch-Site': 'cross-site', + 'Sec-Fetch-User': '?1', + 'Upgrade-Insecure-Requests': '1', + 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' + } + + responses = [] + + # here we take the scraped CIDs and pull info for each dapp + # from cloudflare's public IPFS gateway + with requests.Session() as session: + for url in cleaned_ipfs_urls: + CID = get_url_suffix(url) + IPFS_URL = f"https://cloudflare-ipfs.com/ipfs/{CID}" + try: + response = session.get(IPFS_URL, headers=headers, timeout=30) + if response.status_code == 200: + # process the response + responses.append(response.content) + pass + else: + print(f"Failed to retrieve {url}. Status code: {response.status_code}") + except requests.RequestException as e: + print(f"Error fetching {url}: {e}") + + # convert bytes objects to strings and load them as JSON + responses_str = [json.loads(response.decode()) for response in responses] + + # Save the responses array to a new json file called 'dapp-list.json' + with open('dapp-list.json', 'w') as f: + json.dump(clean_payload_data(responses_str), f, ensure_ascii=False) + + + +# a util function that, in this case, will get us the IPFS CID +def get_url_suffix(url: str) -> str: + return url.rsplit('/', 1)[-1] + +# Function to further clean the original JSON data by focusing only on the 'payload' property of 'msg' +def clean_payload_data(original_data): + # Extract and parse the 'msg' fields, then extract the 'payload' property + cleaned_payload_data = [json.loads(item.get('msg', '{}')).get('payload', {}) for item in original_data] + + # reduce each obj to just a few properties that we need + reduced_data = [] + for dapp in cleaned_payload_data: + cleaned_dapp = { + "name": dapp["name"], + "description": dapp["description"], + "url": dapp["url"], + "twitterHandle": dapp["twitterHandle"], + "blogLinks": dapp["blogLinks"], + "discord": dapp["socialLinks"]["discord"], + "facebook": dapp["socialLinks"]["facebook"], + "instagram": dapp["socialLinks"]["instagram"], + "telegram": dapp["socialLinks"]["telegram"] + } + reduced_data.append(cleaned_dapp) + + return reduced_data + + diff --git a/tools/index_widget.py b/tools/index_widget.py index d2bc86e6..7375a93d 100644 --- a/tools/index_widget.py +++ b/tools/index_widget.py @@ -355,13 +355,16 @@ def fn(token_handler): @error_wrap def fetch_scraped_sites(query: str) -> Callable: def fn(token_handler): - scraped_sites_index = config.initialize(config.scraped_sites_index) + # below is the old index used previously for scraped sites - do we still use this? + # if so, should we make a different function for the new dapps_index? + # scraped_sites_index = config.initialize(config.scraped_sites_index) + dapps_index = config.initialize(config.dapps_index) tool = dict( type="tools.index_answer.IndexAnswerTool", _streaming=True, name="ScrapedSitesIndexAnswer", content_description="", # not used - index=scraped_sites_index, + index=dapps_index, top_k=3, source_key="url", ) From e3d055f3777ce0965ed5ac6eed407aa4eb67ada9 Mon Sep 17 00:00:00 2001 From: Jacob Bryant Date: Thu, 31 Aug 2023 16:52:19 -0400 Subject: [PATCH 02/17] updates --- scrape/dapp_scraper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scrape/dapp_scraper.py b/scrape/dapp_scraper.py index 85b32b4d..ddbac251 100644 --- a/scrape/dapp_scraper.py +++ b/scrape/dapp_scraper.py @@ -52,7 +52,7 @@ def get_ipfs_links_from_url(url: str) -> List[str]: return cleaned_ipfs_urls -def scrape_ipfs_links(url: str = 'https://thedapplist.com/curate?status=All&q=') -> str: +def scrape_ipfs_links(url: str) -> str: payload = json.dumps({ "url": url, From 5fe112edddf6a5c8c9c690a8c2b59663a2d19a7c Mon Sep 17 00:00:00 2001 From: Jacob Bryant Date: Fri, 15 Sep 2023 11:21:44 -0400 Subject: [PATCH 03/17] link suggestions functionality --- index/dapps.py | 26 +++++++++++++------------- scrape/dapp_scraper.py | 31 +++++++++++++++++++++++++++++++ scrape/models.py | 18 +++++++++++++++++- tools/index_answer.py | 2 +- 4 files changed, 62 insertions(+), 15 deletions(-) diff --git a/index/dapps.py b/index/dapps.py index 99c51547..eb98b426 100644 --- a/index/dapps.py +++ b/index/dapps.py @@ -1,5 +1,5 @@ -# to build the index for dapps, first scrap them from dapplist.com using the scraper -# then run: python -c "from index.dapps import backfill; backfill()" +# to build the index for dapps, first scrape them using the scraper +# then run: python3 -c "from index.dapps import backfill; backfill()" from langchain.docstore.document import Document @@ -39,37 +39,37 @@ def create_schema(delete_first: bool = False) -> None: } }, "properties": [ - {"name": DAPP_NAME, "dataType": ["string"]}, - {"name": DAPP_DESCRIPTION, "dataType": ["string"]}, - {"name": DAPP_URL, "dataType": ["string"]}, + {"name": DAPP_NAME, "dataType": ["text"]}, + {"name": DAPP_DESCRIPTION, "dataType": ["text"]}, + {"name": DAPP_URL, "dataType": ["text"]}, { "name": "twitterHandle", - "dataType": ["string"], + "dataType": ["text"], "description": "The Twitter handle of the Dapp" }, { "name": "blogLinks", - "dataType": ["string[]"], + "dataType": ["text[]"], "description": "Links to the blog posts related to the Dapp" }, { "name": "discord", - "dataType": ["string"], + "dataType": ["text"], "description": "The Discord server link of the Dapp" }, { "name": "facebook", - "dataType": ["string"], + "dataType": ["text"], "description": "The Facebook page link of the Dapp" }, { "name": "instagram", - "dataType": ["string"], + "dataType": ["text"], "description": "The Instagram profile link of the Dapp" }, { "name": "telegram", - "dataType": ["string"], + "dataType": ["text"], "description": "The Telegram channel link of the Dapp" } ] @@ -85,10 +85,10 @@ def backfill(): try: from langchain.vectorstores import Weaviate - with open('./knowledge_base/dapp-list.json') as f: + with open('./knowledge_base/dapps_ranked.json') as f: dapp_list = json.load(f) - # Extract the 'id' field from each dapp and store it in the 'documents' list + # Extract the 'name' field from each dapp and store it in the 'documents' list documents = [d.pop("name") for d in dapp_list] # Use the remaining fields in each dapp to populate the 'metadatas' list diff --git a/scrape/dapp_scraper.py b/scrape/dapp_scraper.py index ddbac251..867fc4c1 100644 --- a/scrape/dapp_scraper.py +++ b/scrape/dapp_scraper.py @@ -160,3 +160,34 @@ def clean_payload_data(original_data): return reduced_data +def load_data_from_json_to_db(session, json_path): + # 1. Setup + # If the table doesn't exist, create it + # Base.metadata.create_all(session.bind) Dont need this - jacob b + + # 2. Data Loading + + # Read the JSON data + with open(json_path, "r") as file: + dapps_data = json.load(file) + + # Loop through the JSON data and insert each entry into the database + for dapp in dapps_data: + dapp_instance = DApp( + description=dapp["description"], + name=dapp["name"], + url=dapp["url"], + twitter_handle=dapp["twitterHandle"], + blog_links=dapp["blogLinks"], + discord=dapp["discord"], + facebook=dapp["facebook"], + instagram=dapp["instagram"], + telegram=dapp["telegram"] + ) + session.add(dapp_instance) + + # 3. Finalization + + # Commit the transactions + session.commit() + diff --git a/scrape/models.py b/scrape/models.py index 7681d369..aaf0b35d 100644 --- a/scrape/models.py +++ b/scrape/models.py @@ -12,7 +12,7 @@ from sqlalchemy.orm import ( # type: ignore scoped_session, sessionmaker, relationship, backref) -from sqlalchemy.dialects.postgresql import UUID, JSONB +from sqlalchemy.dialects.postgresql import UUID, JSONB, ARRAY, TEXT from sqlalchemy.ext.declarative import declarative_base # type: ignore from sqlalchemy_utils import ChoiceType, Timestamp # type: ignore @@ -35,3 +35,19 @@ class ScrapedUrl(Base, Timestamp): # type: ignore data = Column(JSONB, nullable=False) Index('scraped_url_lookup', url, unique=True) + +class Dapp(Base): + __tablename__ = 'dapps' + + id = Column(Integer, primary_key=True, autoincrement=True) + description = Column(TEXT, nullable=False) + name = Column(String(255), nullable=False, unique=True) + url = Column(String(255), nullable=False) + twitter_handle = Column(String(255), nullable=True) + blog_links = Column(ARRAY(String(255)), nullable=True) + discord = Column(String(255), nullable=True) + facebook = Column(String(255), nullable=True) + instagram = Column(String(255), nullable=True) + telegram = Column(String(255), nullable=True) + + Index('dapp_name_url_index', 'name', 'url', unique=True) diff --git a/tools/index_answer.py b/tools/index_answer.py index 84c48a85..319d1141 100644 --- a/tools/index_answer.py +++ b/tools/index_answer.py @@ -12,7 +12,7 @@ TEMPLATE = '''You are a web3 assistant. You help users with answering web3-related questions. Your responses should sound natural, helpful, cheerful, and engaging, and you should use easy to understand language with explanations for jargon. -Information to help complete your task is below. Only use information below to answer the question, and create a final answer with inline citations linked to the provided source URLs. If you don't know the answer, just say that you don't know. Don't try to make up an answer. ALWAYS return a "SOURCES" part in your answer corresponding to the numbered inline citations. +Information to help complete your task is below. Only use information below to answer the question, and create a final answer with inline citations linked to the provided source URLs. If you don't know the answer, just say that you don't know. Don't try to make up an answer. ALWAYS return a "SOURCES" part in your answer corresponding to the numbered inline citations. ALWAYS provide a link to each citation in SOURCES. --- {task_info} --- From 3bc769927a2e3afba6a38f63fd6d6b733f9b1fee Mon Sep 17 00:00:00 2001 From: Jacob Bryant Date: Mon, 18 Sep 2023 11:41:51 -0400 Subject: [PATCH 04/17] updating Dapp class --- scrape/models.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scrape/models.py b/scrape/models.py index aaf0b35d..5a504c60 100644 --- a/scrape/models.py +++ b/scrape/models.py @@ -36,10 +36,10 @@ class ScrapedUrl(Base, Timestamp): # type: ignore Index('scraped_url_lookup', url, unique=True) -class Dapp(Base): - __tablename__ = 'dapps' +class Dapp(Base, Timestamp): + __tablename__ = 'dapp' - id = Column(Integer, primary_key=True, autoincrement=True) + id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) description = Column(TEXT, nullable=False) name = Column(String(255), nullable=False, unique=True) url = Column(String(255), nullable=False) @@ -50,4 +50,4 @@ class Dapp(Base): instagram = Column(String(255), nullable=True) telegram = Column(String(255), nullable=True) - Index('dapp_name_url_index', 'name', 'url', unique=True) + Index('dapp_by_name', 'name', unique=True) From d616276e880c1a12a90e621629a70f4b72469778 Mon Sep 17 00:00:00 2001 From: Jacob Bryant Date: Tue, 19 Sep 2023 08:28:46 -0400 Subject: [PATCH 05/17] skip vectorizing certain fields --- index/dapps.py | 48 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/index/dapps.py b/index/dapps.py index eb98b426..b64d3762 100644 --- a/index/dapps.py +++ b/index/dapps.py @@ -45,32 +45,68 @@ def create_schema(delete_first: bool = False) -> None: { "name": "twitterHandle", "dataType": ["text"], - "description": "The Twitter handle of the Dapp" + "description": "The Twitter handle of the Dapp", + "moduleConfig": { + "text2vec-openai": { + "skip": False, + "vectorizePropertyName": False + } + } }, { "name": "blogLinks", "dataType": ["text[]"], - "description": "Links to the blog posts related to the Dapp" + "description": "Links to the blog posts related to the Dapp", + "moduleConfig": { + "text2vec-openai": { + "skip": False, + "vectorizePropertyName": False + } + } }, { "name": "discord", "dataType": ["text"], - "description": "The Discord server link of the Dapp" + "description": "The Discord server link of the Dapp", + "moduleConfig": { + "text2vec-openai": { + "skip": False, + "vectorizePropertyName": False + } + } }, { "name": "facebook", "dataType": ["text"], - "description": "The Facebook page link of the Dapp" + "description": "The Facebook page link of the Dapp", + "moduleConfig": { + "text2vec-openai": { + "skip": False, + "vectorizePropertyName": False + } + } }, { "name": "instagram", "dataType": ["text"], - "description": "The Instagram profile link of the Dapp" + "description": "The Instagram profile link of the Dapp", + "moduleConfig": { + "text2vec-openai": { + "skip": False, + "vectorizePropertyName": False + } + } }, { "name": "telegram", "dataType": ["text"], - "description": "The Telegram channel link of the Dapp" + "description": "The Telegram channel link of the Dapp", + "moduleConfig": { + "text2vec-openai": { + "skip": False, + "vectorizePropertyName": False + } + } } ] } From 929b66128ccab24d6dfe81c3f901be82693535b5 Mon Sep 17 00:00:00 2001 From: Jacob Bryant Date: Tue, 19 Sep 2023 08:30:11 -0400 Subject: [PATCH 06/17] updated index name --- config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.py b/config.py index f1e095e2..67d16e53 100644 --- a/config.py +++ b/config.py @@ -22,7 +22,7 @@ dapps_index = dict( type="index.weaviate.WeaviateIndex", - index_name="ThirdPartyDapps", + index_name="Web3Apps", text_key="description", extra_keys=["url","name"], ) From e1f2c2dd0cc9630c05dbb6ca889fdae0d3ae30fd Mon Sep 17 00:00:00 2001 From: Jacob Bryant Date: Tue, 19 Sep 2023 21:21:39 -0400 Subject: [PATCH 07/17] updating db load function --- scrape/dapp_scraper.py | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/scrape/dapp_scraper.py b/scrape/dapp_scraper.py index 867fc4c1..2950a3ea 100644 --- a/scrape/dapp_scraper.py +++ b/scrape/dapp_scraper.py @@ -1,11 +1,24 @@ +import os +import argparse + +# Change the current working directory to the parent directory of the script +os.chdir(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + import requests import json -import os from typing import List +from scrape.models import ( + db_session, + Dapp +) + BROWSERLESS_API_KEY = os.getenv('BROWSERLESS_API_KEY', '') SCRAPE_API_URL = f'https://chrome.browserless.io/scrape?token={BROWSERLESS_API_KEY}' +# Construct the path to the dapps_ranked.json file +dapps_json_path = os.path.join(os.getcwd(), "scrape", "dapps_ranked_unique.json") + # scrape a URL for IPFS links, return def get_ipfs_links_from_url(url: str) -> List[str]: @@ -160,7 +173,8 @@ def clean_payload_data(original_data): return reduced_data -def load_data_from_json_to_db(session, json_path): +def load_data_from_json_to_db(session=db_session, json_path=dapps_json_path): + print("Loading data from JSON to DB") # 1. Setup # If the table doesn't exist, create it # Base.metadata.create_all(session.bind) Dont need this - jacob b @@ -173,7 +187,8 @@ def load_data_from_json_to_db(session, json_path): # Loop through the JSON data and insert each entry into the database for dapp in dapps_data: - dapp_instance = DApp( + print(f'adding {dapp["name"]}') + dapp_instance = Dapp( description=dapp["description"], name=dapp["name"], url=dapp["url"], @@ -191,3 +206,21 @@ def load_data_from_json_to_db(session, json_path): # Commit the transactions session.commit() + print("Finished loading data from JSON to DB") + + + +if __name__ == "__main__": + + # create an ArgumentParser instance + parser = argparse.ArgumentParser(description='Run functions in the dapp_scraper module.') + + # Add an argument for the load_data_from_json_to_db function + parser.add_argument('--load', action='store_true', help='Run the load_data_from_json_to_db function.') + + # Parse the command line arguments + args = parser.parse_args() + + # If the --load argument is present, call the load_data_from_json_to_db function + if args.load: + load_data_from_json_to_db() \ No newline at end of file From 34bbbfaf574d668bc2b23a3185aad6e161cdf1e0 Mon Sep 17 00:00:00 2001 From: Jacob Bryant Date: Wed, 20 Sep 2023 10:19:14 -0400 Subject: [PATCH 08/17] adding changes to keep scraped sites and add link suggestion --- index/dapps.py | 2 +- knowledge_base/widgets.yaml | 300 +++++++++++++++++++++--------------- tools/index_widget.py | 23 ++- 3 files changed, 194 insertions(+), 131 deletions(-) diff --git a/index/dapps.py b/index/dapps.py index b64d3762..f648355f 100644 --- a/index/dapps.py +++ b/index/dapps.py @@ -6,7 +6,7 @@ from .weaviate import get_client import json -INDEX_NAME = "ThirdPartyDapps" +INDEX_NAME = "Web3Apps" INDEX_DESCRIPTION = "Index of Third party dapps" DAPP_DESCRIPTION = "description" DAPP_NAME = "name" diff --git a/knowledge_base/widgets.yaml b/knowledge_base/widgets.yaml index 5bf628f3..df9b8e85 100644 --- a/knowledge_base/widgets.yaml +++ b/knowledge_base/widgets.yaml @@ -12,13 +12,14 @@ description: Symbol of the token being transferred. type: string required: - - token - - amount - - address + - token + - amount + - address type: object - return_value_description: '' + return_value_description: "" - _name_: fetch_nft_buy_asset - description: Buy an NFT asset of a collection on the OpenSea marketplace, given + description: + Buy an NFT asset of a collection on the OpenSea marketplace, given its network, address, and token ID. Don't use this if we don't have the collection network and address and token ID of the asset we want to purchase. parameters: @@ -33,26 +34,29 @@ description: Token ID of the asset. type: string required: - - network - - address - - tokenID + - network + - address + - tokenID type: object return_value_description: a transaction dialog for purchase of the NFT - _name_: fetch_nft_search - description: Search for NFT collections given a query phrase, a description, or + description: + Search for NFT collections given a query phrase, a description, or a name parameters: properties: query: - description: String of keywords to describe the kind of NFT collections to + description: + String of keywords to describe the kind of NFT collections to find. type: string required: - - query + - query type: object return_value_description: a list of text describing NFT collections that were found - _name_: fetch_nft_collection_assets_by_trait - description: List assets with a particular trait name and value from a specific + description: + List assets with a particular trait name and value from a specific NFT collection given its network and address. Don't use this if we don't have the collection network and address. Don't use this without first fetching the valid list of trait names or trait values with the fetch_nft_collection_traits @@ -73,15 +77,17 @@ description: Value of trait (case-sensitive). type: string required: - - network - - address - - traitName - - traitValue + - network + - address + - traitName + - traitValue type: object - return_value_description: a list of text describing NFT assets that match the trait + return_value_description: + a list of text describing NFT assets that match the trait value - _name_: fetch_nft_collection_assets_for_sale_by_trait - description: List assets available for purchase with a particular trait name and + description: + List assets available for purchase with a particular trait name and value from a specific NFT collection given its network and address. Don't use this if we don't have the collection network and address. parameters: @@ -99,15 +105,17 @@ description: Value of trait. type: string required: - - network - - address - - traitName - - traitValue + - network + - address + - traitName + - traitValue type: object - return_value_description: a list of text describing NFT assets for sale/available + return_value_description: + a list of text describing NFT assets for sale/available for purchase that match the trait value - _name_: fetch_nft_collection_info - description: Retrieve data and assets of an NFT collection given its network and + description: + Retrieve data and assets of an NFT collection given its network and address. parameters: properties: @@ -118,12 +126,13 @@ description: network of the NFT collection. type: string required: - - network - - address + - network + - address type: object return_value_description: text with data and some assets of the NFT collection - _name_: fetch_nft_collection_assets_for_sale - description: Retrieve assets available for purchase of an NFT collection given its + description: + Retrieve assets available for purchase of an NFT collection given its network and address. parameters: properties: @@ -134,10 +143,11 @@ description: network of the NFT collection. type: string required: - - network - - address + - network + - address type: object - return_value_description: text with assets of the NFT collection that are for sale/available + return_value_description: + text with assets of the NFT collection that are for sale/available for purchase - _name_: fetch_nft_collection_traits description: Retrieve traits of an NFT collection given its network and address. @@ -150,12 +160,13 @@ description: Network of the NFT collection. type: string required: - - network - - address + - network + - address type: object return_value_description: a list of text describing traits of the NFT collection - _name_: fetch_nft_collection_trait_values - description: Retrieve trait values of a trait of an NFT collection given its network + description: + Retrieve trait values of a trait of an NFT collection given its network and address. parameters: properties: @@ -169,14 +180,16 @@ description: Name of trait to fetch values of. type: string required: - - network - - address - - traitName + - network + - address + - traitName type: object - return_value_description: a list of text describing values of the trait of the NFT + return_value_description: + a list of text describing values of the trait of the NFT collection - _name_: fetch_nft_asset_traits - description: Retrieve data and traits of an NFT asset in a collection given its + description: + Retrieve data and traits of an NFT asset in a collection given its network, address, and token ID. parameters: properties: @@ -190,14 +203,16 @@ description: Token ID of the asset. type: string required: - - network - - address - - tokenID + - network + - address + - tokenID type: object - return_value_description: text with data and list of trait names and values of the + return_value_description: + text with data and list of trait names and values of the NFT asset - _name_: fetch_yields - description: Get the yields for crypto assets. The user may not specify all parameters + description: + Get the yields for crypto assets. The user may not specify all parameters so do not guess any parameter. parameters: properties: @@ -205,23 +220,26 @@ description: Number of yield sources. Use '*' when parameter not available. type: string network: - description: Blockchain to get the yield for. Normalize the network name to + description: + Blockchain to get the yield for. Normalize the network name to its popular representation in the ecosystem. Use '*' when parameter not available or the user wants all networks. type: string token: - description: Token to get the yield for. Normalize the token name to its popular + description: + Token to get the yield for. Normalize the token name to its popular symbol representation in the ecoystem. Use '*' when parameter not available or the user wants all tokens. type: string required: - - token - - network - - count + - token + - network + - count type: object return_value_description: JSON object with yield information - _name_: fetch_price - description: Get the price of a token. Note, when the quoteToken isn't explicitly + description: + Get the price of a token. Note, when the quoteToken isn't explicitly specified assume it to be USD parameters: properties: @@ -232,8 +250,8 @@ description: Token to use as units for price. type: string required: - - basetoken - - quotetoken + - basetoken + - quotetoken type: object return_value_description: price of a base token in units of a quote token. - _name_: ens_from_address @@ -244,7 +262,7 @@ description: Address of the account or wallet. type: string required: - - address + - address type: object return_value_description: a humanreadable string with ENS domain - _name_: address_from_ens @@ -255,7 +273,7 @@ description: Domain name of the account or wallet. type: string required: - - domain + - domain type: object return_value_description: a humanreadable string with wallet address - _name_: register_ens_domain @@ -266,11 +284,12 @@ description: Domain name to register. type: string required: - - domain + - domain type: object - return_value_description: '' + return_value_description: "" - _name_: set_ens_text - description: Set the text record for an ENS domain that ends with *.eth in a key + description: + Set the text record for an ENS domain that ends with *.eth in a key value pair format. parameters: properties: @@ -284,11 +303,11 @@ description: Value of the text record. type: string required: - - domain - - key - - value + - domain + - key + - value type: object - return_value_description: '' + return_value_description: "" - _name_: set_ens_primary_name description: Set a primary ENS name for their connected wallet account. parameters: @@ -297,11 +316,12 @@ description: Domain name to use as primary ENS name. type: string required: - - domain + - domain type: object - return_value_description: '' + return_value_description: "" - _name_: set_ens_avatar_nft - description: Set an nft as their ENS domain's avatar. Do not guess any parameter, + description: + Set an nft as their ENS domain's avatar. Do not guess any parameter, if any parameter is missing, set the default value as 'None'. parameters: properties: @@ -318,12 +338,12 @@ description: Name of NFT collection. Use an empty string if the input parameter value is unknown but do not ask user to input empty string. type: string required: - - domain - - nftContractAddress - - nftId - - collectionName + - domain + - nftContractAddress + - nftId + - collectionName type: object - return_value_description: '' + return_value_description: "" - _name_: aave_supply description: Deposit or supply tokens into Aave project parameters: @@ -335,10 +355,10 @@ description: Token to supply. type: string required: - - token - - amount + - token + - amount type: object - return_value_description: '' + return_value_description: "" - _name_: aave_borrow description: Borrow tokens from Aave project parameters: @@ -350,10 +370,10 @@ description: Token to borrow. type: string required: - - token - - amount + - token + - amount type: object - return_value_description: '' + return_value_description: "" - _name_: aave_repay description: Repay back borrowed tokens from Aave project parameters: @@ -365,10 +385,10 @@ description: Token to repay. type: string required: - - token - - amount + - token + - amount type: object - return_value_description: '' + return_value_description: "" - _name_: aave_withdraw description: Withdraw deposited tokens from Aave project parameters: @@ -380,12 +400,13 @@ description: Token to withdraw. type: string required: - - token - - amount + - token + - amount type: object - return_value_description: '' + return_value_description: "" - _name_: fetch_balance - description: Get the balance of a token in an account or wallet. Don't use this + description: + Get the balance of a token in an account or wallet. Don't use this if we don't have the address. parameters: properties: @@ -396,13 +417,15 @@ description: Token to get the balance of. type: string required: - - token - - address + - token + - address type: object - return_value_description: balance of a token in an account or wallet, in decimal + return_value_description: + balance of a token in an account or wallet, in decimal units - _name_: display_yield_farm - description: Used for the Compound project to allow the user to yield farm by putting + description: + Used for the Compound project to allow the user to yield farm by putting tokens or depositing tokens of a certain amount into the Compound project. parameters: properties: @@ -410,7 +433,8 @@ description: Amount of token to deposit in the project. type: string network: - description: Network or blockchain of the project. Default to Ethereum if + description: + Network or blockchain of the project. Default to Ethereum if not specified. type: string project: @@ -420,14 +444,15 @@ description: Token to deposit in the project. type: string required: - - project - - network - - token - - amount + - project + - network + - token + - amount type: object - return_value_description: '' + return_value_description: "" - _name_: fetch_app_info - description: Used when we need to handle common questions and answers about the + description: + Used when we need to handle common questions and answers about the chat assistant app, what it can do, how to interact with it, at a high-level. Only useful for questions about the chat app experience. It does not know specific information about the web3 ecosystem, of tokens or NFTs or contracts, or access @@ -435,28 +460,48 @@ parameters: properties: query: - description: a standalone query with all relevant contextual details pertaining + description: + a standalone query with all relevant contextual details pertaining to the chat web application. type: string required: - - query + - query type: object - return_value_description: an answer to the question, with suggested followup questions + return_value_description: + an answer to the question, with suggested followup questions if available - _name_: fetch_scraped_sites - description: Answer questions using general content scraped from web3 sites. It + description: + Answer questions using general content scraped from web3 sites. It does not know about this app or about widget magic commands for invoking transactions or fetching data about specific things like NFTs or balances. parameters: properties: query: - description: a standalone question representing information to be retrieved + description: + a standalone question representing information to be retrieved from the index. type: string required: - - query + - query type: object return_value_description: a summarized answer with source citations +- _name_: fetch_link_suggestion + description: + Answer questions using general content scraped from web3 sites. It + does not know about this app or about widget magic commands for invoking transactions + or fetching data about specific things like NFTs or balances. + parameters: + properties: + query: + description: + a standalone question representing information to be retrieved + from the index. + type: string + required: + - query + type: object + return_value_description: a summarized answer with source citations and links - _name_: display_zksync_deposit description: Used to bridge and deposit tokens from mainnet L1 to zksync L2. parameters: @@ -468,10 +513,10 @@ description: token to deposit type: string required: - - token - - amount + - token + - amount type: object - return_value_description: '' + return_value_description: "" - _name_: display_zksync_withdraw description: Used to withdraw tokens from zksync L2 to mainnet L1 parameters: @@ -483,10 +528,10 @@ description: token to deposit type: string required: - - token - - amount + - token + - amount type: object - return_value_description: '' + return_value_description: "" - _name_: fetch_my_balance description: Get the balance of a token in the user's connected wallet parameters: @@ -495,7 +540,7 @@ description: Token to get the balance of. type: string required: - - token + - token type: object return_value_description: balance of a token in connected wallet, in decimal units - _name_: fetch_gas @@ -506,7 +551,7 @@ description: Address of the account or wallet to check the gas of. type: string required: - - address + - address type: object return_value_description: the gas amount used - _name_: fetch_eth_in @@ -517,7 +562,7 @@ description: Address of the account or wallet to check the inflow ETH. type: string required: - - address + - address type: object return_value_description: the inflow ETH amount - _name_: fetch_eth_out @@ -528,11 +573,12 @@ description: Address of the account or wallet to check the outflow ETH. type: string required: - - address + - address type: object return_value_description: the outflow ETH amount - _name_: display_uniswap - description: 'use the Uniswap decentralized application for trading one token for + description: + 'use the Uniswap decentralized application for trading one token for another. To create a Uniswap transaction, you need either: 1.) A token to sell, a token to buy, the transaction keyword "SELLAMOUNT", and @@ -543,7 +589,8 @@ parameters: properties: amount: - description: Amount of token described by transaction keyword that we are + description: + Amount of token described by transaction keyword that we are trying to buy or sell. type: string tokenToBuy: @@ -553,16 +600,17 @@ description: Token to sell in the swap transaction. type: string transactionKeyword: - description: Either SELLAMOUNT if amount refers to token to sell or BUYAMOUNT + description: + Either SELLAMOUNT if amount refers to token to sell or BUYAMOUNT if amount refers to token to buy. type: string required: - - tokenToSell - - tokenToBuy - - transactionKeyword - - amount + - tokenToSell + - tokenToBuy + - transactionKeyword + - amount type: object - return_value_description: '' + return_value_description: "" - _name_: fetch_nfts_owned_by_address_or_domain description: Used to fetch NFTs owned by a wallet address or ENS domain on a particular network parameters: @@ -590,7 +638,7 @@ type: object return_value_description: List of NFT Assets - _name_: display_stake_sfrxeth - description: 'Exchange ETH for sfrxETH using the frxETHMinter contract' + description: "Exchange ETH for sfrxETH using the frxETHMinter contract" parameters: properties: receiver: @@ -600,10 +648,10 @@ description: Amount of ETH to exchange for sfrxETH type: string required: - - receiver - - value + - receiver + - value type: object - return_value_description: '' + return_value_description: "" - _name_: display_arbitrum_deposit description: Used to bridge/deposit ETH or token from mainnet L1 to arbitrum L2. parameters: @@ -615,10 +663,10 @@ description: amount to deposit type: string required: - - token - - amount + - token + - amount type: object - return_value_description: '' + return_value_description: "" - _name_: display_arbitrum_withdraw description: Used to withdraw ETH from arbitrum L2 to mainnet L1 parameters: @@ -630,10 +678,10 @@ description: amount to withdraw type: string required: - - token - - amount + - token + - amount type: object - return_value_description: '' + return_value_description: "" - _name_: display_yield_protocol_lend description: use the yield protocol to lend tokens at a fixed rate parameters: diff --git a/tools/index_widget.py b/tools/index_widget.py index 7375a93d..232cc79a 100644 --- a/tools/index_widget.py +++ b/tools/index_widget.py @@ -248,6 +248,8 @@ def replace_match(m: re.Match) -> Union[str, Generator, Callable]: return fetch_app_info(*params) elif command == 'fetch-scraped-sites': return fetch_scraped_sites(*params) + elif command == 'fetch-link-suggestion': + return fetch_link_suggestion(*params) elif command == aave.AaveSupplyContractWorkflow.WORKFLOW_TYPE: return str(exec_aave_operation(*params, operation='supply')) elif command == aave.AaveBorrowContractWorkflow.WORKFLOW_TYPE: @@ -351,13 +353,26 @@ def fn(token_handler): tool._run(query) return fn - @error_wrap def fetch_scraped_sites(query: str) -> Callable: def fn(token_handler): - # below is the old index used previously for scraped sites - do we still use this? - # if so, should we make a different function for the new dapps_index? - # scraped_sites_index = config.initialize(config.scraped_sites_index) + scraped_sites_index = config.initialize(config.scraped_sites_index) + tool = dict( + type="tools.index_answer.IndexAnswerTool", + _streaming=True, + name="ScrapedSitesIndexAnswer", + content_description="", # not used + index=scraped_sites_index, + top_k=3, + source_key="url", + ) + tool = streaming.get_streaming_tools([tool], token_handler)[0] + tool._run(query) + return fn + +@error_wrap +def fetch_link_suggestion(query: str) -> Callable: + def fn(token_handler): dapps_index = config.initialize(config.dapps_index) tool = dict( type="tools.index_answer.IndexAnswerTool", From dce09b703e8b050e1e3feef56823e177870cabf8 Mon Sep 17 00:00:00 2001 From: Jacob Bryant Date: Thu, 21 Sep 2023 09:37:52 -0400 Subject: [PATCH 09/17] commenting out scraped sites, new tool for link suggestion with improved prompt --- eval/eval_widgets.txt | 1 + knowledge_base/widgets.yaml | 36 +++++++++++--------- tools/__init__.py | 3 +- tools/index_link_suggestion.py | 61 ++++++++++++++++++++++++++++++++++ tools/index_widget.py | 43 +++++++++++++----------- 5 files changed, 107 insertions(+), 37 deletions(-) create mode 100644 tools/index_link_suggestion.py diff --git a/eval/eval_widgets.txt b/eval/eval_widgets.txt index d3696715..cccf34c9 100644 --- a/eval/eval_widgets.txt +++ b/eval/eval_widgets.txt @@ -33,3 +33,4 @@ fetch_eth_out display_uniswap fetch_nfts_owned_by_address_or_domain fetch_nfts_owned_by_user +fetch_link_suggestion diff --git a/knowledge_base/widgets.yaml b/knowledge_base/widgets.yaml index df9b8e85..f566c565 100644 --- a/knowledge_base/widgets.yaml +++ b/knowledge_base/widgets.yaml @@ -470,22 +470,26 @@ return_value_description: an answer to the question, with suggested followup questions if available -- _name_: fetch_scraped_sites - description: - Answer questions using general content scraped from web3 sites. It - does not know about this app or about widget magic commands for invoking transactions - or fetching data about specific things like NFTs or balances. - parameters: - properties: - query: - description: - a standalone question representing information to be retrieved - from the index. - type: string - required: - - query - type: object - return_value_description: a summarized answer with source citations +# +# deprecating scraped sites in favor of link suggestion - leaving for future reference +# in case we ever want to revive +# +# - _name_: fetch_scraped_sites +# description: +# Answer questions using general content scraped from web3 sites. It +# does not know about this app or about widget magic commands for invoking transactions +# or fetching data about specific things like NFTs or balances. +# parameters: +# properties: +# query: +# description: +# a standalone question representing information to be retrieved +# from the index. +# type: string +# required: +# - query +# type: object +# return_value_description: a summarized answer with source citations - _name_: fetch_link_suggestion description: Answer questions using general content scraped from web3 sites. It diff --git a/tools/__init__.py b/tools/__init__.py index 496a1ee3..426db12c 100644 --- a/tools/__init__.py +++ b/tools/__init__.py @@ -5,4 +5,5 @@ from . import index_widget from . import index_app_info from . import index_api_tool -from . import app_usage_guide \ No newline at end of file +from . import app_usage_guide +from . import index_link_suggestion \ No newline at end of file diff --git a/tools/index_link_suggestion.py b/tools/index_link_suggestion.py new file mode 100644 index 00000000..67c59d58 --- /dev/null +++ b/tools/index_link_suggestion.py @@ -0,0 +1,61 @@ +from typing import Any, Optional + +from langchain.llms import OpenAI +from langchain.prompts import PromptTemplate +from langchain.chains import LLMChain +from langchain.prompts.base import BaseOutputParser + +import registry +import streaming +from .index_lookup import IndexLookupTool + + +TEMPLATE = '''You are a web3 assistant. You help users with answering web3-related questions. Your responses should sound natural, helpful, cheerful, and engaging, and you should use easy to understand language with explanations for jargon. + +Information to help complete your task is below. Only use the information below to answer the question. If you don't know the answer, just say that you don't know. Don't try to make up an answer. + +When mentioning specific platforms, tools, or technologies, it's crucial to provide a relevant URL. Ensure this URL is seamlessly integrated into the content of the answer using markdown formatting. The link should feel like a natural part of the sentence. + +For example: One of the leading platforms in the web3 space is [Ethereum](https://www.ethereum.org/), which offers a decentralized platform for building smart contracts and dapps." +--- +{task_info} +--- + +User: {question} +Assistant:''' + + +@registry.register_class +class IndexLinkSuggestionTool(IndexLookupTool): + """Tool for searching a document index and summarizing results to answer the question.""" + + _chain: LLMChain + + def __init__( + self, + *args, + **kwargs + ) -> None: + prompt = PromptTemplate( + input_variables=["task_info", "question"], + template=TEMPLATE, + ) + new_token_handler = kwargs.get('new_token_handler') + chain = streaming.get_streaming_chain(prompt, new_token_handler) + super().__init__( + *args, + _chain=chain, + output_description="a summarized answer with source citations", + **kwargs + ) + + def _run(self, query: str) -> str: + """Query index and answer question using document chunks.""" + task_info = super()._run(query) + example = { + "task_info": task_info, + "question": query, + "stop": "User", + } + result = self._chain.run(example) + return result.strip() diff --git a/tools/index_widget.py b/tools/index_widget.py index 232cc79a..62740886 100644 --- a/tools/index_widget.py +++ b/tools/index_widget.py @@ -246,8 +246,8 @@ def replace_match(m: re.Match) -> Union[str, Generator, Callable]: return str(fetch_yields(*params)) elif command == 'fetch-app-info': return fetch_app_info(*params) - elif command == 'fetch-scraped-sites': - return fetch_scraped_sites(*params) + # elif command == 'fetch-scraped-sites': + # return fetch_scraped_sites(*params) elif command == 'fetch-link-suggestion': return fetch_link_suggestion(*params) elif command == aave.AaveSupplyContractWorkflow.WORKFLOW_TYPE: @@ -353,31 +353,34 @@ def fn(token_handler): tool._run(query) return fn -@error_wrap -def fetch_scraped_sites(query: str) -> Callable: - def fn(token_handler): - scraped_sites_index = config.initialize(config.scraped_sites_index) - tool = dict( - type="tools.index_answer.IndexAnswerTool", - _streaming=True, - name="ScrapedSitesIndexAnswer", - content_description="", # not used - index=scraped_sites_index, - top_k=3, - source_key="url", - ) - tool = streaming.get_streaming_tools([tool], token_handler)[0] - tool._run(query) - return fn +# deprating this in favor of link suggestion as the 2 seem to clash a lot +# leaving here for future reference in case we ever want to revive +# +# @error_wrap +# def fetch_scraped_sites(query: str) -> Callable: +# def fn(token_handler): +# scraped_sites_index = config.initialize(config.scraped_sites_index) +# tool = dict( +# type="tools.index_answer.IndexAnswerTool", +# _streaming=True, +# name="ScrapedSitesIndexAnswer", +# content_description="", # not used +# index=scraped_sites_index, +# top_k=3, +# source_key="url", +# ) +# tool = streaming.get_streaming_tools([tool], token_handler)[0] +# tool._run(query) +# return fn @error_wrap def fetch_link_suggestion(query: str) -> Callable: def fn(token_handler): dapps_index = config.initialize(config.dapps_index) tool = dict( - type="tools.index_answer.IndexAnswerTool", + type="tools.index_link_suggestion.IndexLinkSuggestionTool", _streaming=True, - name="ScrapedSitesIndexAnswer", + name="LinkSuggestionIndexAnswer", content_description="", # not used index=dapps_index, top_k=3, From 42ccfcbebaeb4084d7853272962671374d447d40 Mon Sep 17 00:00:00 2001 From: Jacob Bryant Date: Thu, 21 Sep 2023 15:10:45 -0400 Subject: [PATCH 10/17] skip vectorization fix --- index/dapps.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/index/dapps.py b/index/dapps.py index f648355f..f35fa26b 100644 --- a/index/dapps.py +++ b/index/dapps.py @@ -48,7 +48,7 @@ def create_schema(delete_first: bool = False) -> None: "description": "The Twitter handle of the Dapp", "moduleConfig": { "text2vec-openai": { - "skip": False, + "skip": True, "vectorizePropertyName": False } } @@ -59,7 +59,7 @@ def create_schema(delete_first: bool = False) -> None: "description": "Links to the blog posts related to the Dapp", "moduleConfig": { "text2vec-openai": { - "skip": False, + "skip": True, "vectorizePropertyName": False } } @@ -70,7 +70,7 @@ def create_schema(delete_first: bool = False) -> None: "description": "The Discord server link of the Dapp", "moduleConfig": { "text2vec-openai": { - "skip": False, + "skip": True, "vectorizePropertyName": False } } @@ -81,7 +81,7 @@ def create_schema(delete_first: bool = False) -> None: "description": "The Facebook page link of the Dapp", "moduleConfig": { "text2vec-openai": { - "skip": False, + "skip": True, "vectorizePropertyName": False } } @@ -92,7 +92,7 @@ def create_schema(delete_first: bool = False) -> None: "description": "The Instagram profile link of the Dapp", "moduleConfig": { "text2vec-openai": { - "skip": False, + "skip": True, "vectorizePropertyName": False } } @@ -103,7 +103,7 @@ def create_schema(delete_first: bool = False) -> None: "description": "The Telegram channel link of the Dapp", "moduleConfig": { "text2vec-openai": { - "skip": False, + "skip": True, "vectorizePropertyName": False } } From 6554609a69f611c89eb22d733ce377c354978e99 Mon Sep 17 00:00:00 2001 From: Jacob Bryant Date: Thu, 21 Sep 2023 16:02:15 -0400 Subject: [PATCH 11/17] revert previous changes to index_answer --- tools/index_answer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/index_answer.py b/tools/index_answer.py index 319d1141..84c48a85 100644 --- a/tools/index_answer.py +++ b/tools/index_answer.py @@ -12,7 +12,7 @@ TEMPLATE = '''You are a web3 assistant. You help users with answering web3-related questions. Your responses should sound natural, helpful, cheerful, and engaging, and you should use easy to understand language with explanations for jargon. -Information to help complete your task is below. Only use information below to answer the question, and create a final answer with inline citations linked to the provided source URLs. If you don't know the answer, just say that you don't know. Don't try to make up an answer. ALWAYS return a "SOURCES" part in your answer corresponding to the numbered inline citations. ALWAYS provide a link to each citation in SOURCES. +Information to help complete your task is below. Only use information below to answer the question, and create a final answer with inline citations linked to the provided source URLs. If you don't know the answer, just say that you don't know. Don't try to make up an answer. ALWAYS return a "SOURCES" part in your answer corresponding to the numbered inline citations. --- {task_info} --- From 9f04c10e2763cb4f0a2b375dc0442773bb44dafc Mon Sep 17 00:00:00 2001 From: Jacob Bryant Date: Fri, 22 Sep 2023 09:51:54 -0400 Subject: [PATCH 12/17] revert formatting changes in widget.yaml --- knowledge_base/widgets.yaml | 308 +++++++++++++++--------------------- 1 file changed, 128 insertions(+), 180 deletions(-) diff --git a/knowledge_base/widgets.yaml b/knowledge_base/widgets.yaml index f566c565..5bf628f3 100644 --- a/knowledge_base/widgets.yaml +++ b/knowledge_base/widgets.yaml @@ -12,14 +12,13 @@ description: Symbol of the token being transferred. type: string required: - - token - - amount - - address + - token + - amount + - address type: object - return_value_description: "" + return_value_description: '' - _name_: fetch_nft_buy_asset - description: - Buy an NFT asset of a collection on the OpenSea marketplace, given + description: Buy an NFT asset of a collection on the OpenSea marketplace, given its network, address, and token ID. Don't use this if we don't have the collection network and address and token ID of the asset we want to purchase. parameters: @@ -34,29 +33,26 @@ description: Token ID of the asset. type: string required: - - network - - address - - tokenID + - network + - address + - tokenID type: object return_value_description: a transaction dialog for purchase of the NFT - _name_: fetch_nft_search - description: - Search for NFT collections given a query phrase, a description, or + description: Search for NFT collections given a query phrase, a description, or a name parameters: properties: query: - description: - String of keywords to describe the kind of NFT collections to + description: String of keywords to describe the kind of NFT collections to find. type: string required: - - query + - query type: object return_value_description: a list of text describing NFT collections that were found - _name_: fetch_nft_collection_assets_by_trait - description: - List assets with a particular trait name and value from a specific + description: List assets with a particular trait name and value from a specific NFT collection given its network and address. Don't use this if we don't have the collection network and address. Don't use this without first fetching the valid list of trait names or trait values with the fetch_nft_collection_traits @@ -77,17 +73,15 @@ description: Value of trait (case-sensitive). type: string required: - - network - - address - - traitName - - traitValue + - network + - address + - traitName + - traitValue type: object - return_value_description: - a list of text describing NFT assets that match the trait + return_value_description: a list of text describing NFT assets that match the trait value - _name_: fetch_nft_collection_assets_for_sale_by_trait - description: - List assets available for purchase with a particular trait name and + description: List assets available for purchase with a particular trait name and value from a specific NFT collection given its network and address. Don't use this if we don't have the collection network and address. parameters: @@ -105,17 +99,15 @@ description: Value of trait. type: string required: - - network - - address - - traitName - - traitValue + - network + - address + - traitName + - traitValue type: object - return_value_description: - a list of text describing NFT assets for sale/available + return_value_description: a list of text describing NFT assets for sale/available for purchase that match the trait value - _name_: fetch_nft_collection_info - description: - Retrieve data and assets of an NFT collection given its network and + description: Retrieve data and assets of an NFT collection given its network and address. parameters: properties: @@ -126,13 +118,12 @@ description: network of the NFT collection. type: string required: - - network - - address + - network + - address type: object return_value_description: text with data and some assets of the NFT collection - _name_: fetch_nft_collection_assets_for_sale - description: - Retrieve assets available for purchase of an NFT collection given its + description: Retrieve assets available for purchase of an NFT collection given its network and address. parameters: properties: @@ -143,11 +134,10 @@ description: network of the NFT collection. type: string required: - - network - - address + - network + - address type: object - return_value_description: - text with assets of the NFT collection that are for sale/available + return_value_description: text with assets of the NFT collection that are for sale/available for purchase - _name_: fetch_nft_collection_traits description: Retrieve traits of an NFT collection given its network and address. @@ -160,13 +150,12 @@ description: Network of the NFT collection. type: string required: - - network - - address + - network + - address type: object return_value_description: a list of text describing traits of the NFT collection - _name_: fetch_nft_collection_trait_values - description: - Retrieve trait values of a trait of an NFT collection given its network + description: Retrieve trait values of a trait of an NFT collection given its network and address. parameters: properties: @@ -180,16 +169,14 @@ description: Name of trait to fetch values of. type: string required: - - network - - address - - traitName + - network + - address + - traitName type: object - return_value_description: - a list of text describing values of the trait of the NFT + return_value_description: a list of text describing values of the trait of the NFT collection - _name_: fetch_nft_asset_traits - description: - Retrieve data and traits of an NFT asset in a collection given its + description: Retrieve data and traits of an NFT asset in a collection given its network, address, and token ID. parameters: properties: @@ -203,16 +190,14 @@ description: Token ID of the asset. type: string required: - - network - - address - - tokenID + - network + - address + - tokenID type: object - return_value_description: - text with data and list of trait names and values of the + return_value_description: text with data and list of trait names and values of the NFT asset - _name_: fetch_yields - description: - Get the yields for crypto assets. The user may not specify all parameters + description: Get the yields for crypto assets. The user may not specify all parameters so do not guess any parameter. parameters: properties: @@ -220,26 +205,23 @@ description: Number of yield sources. Use '*' when parameter not available. type: string network: - description: - Blockchain to get the yield for. Normalize the network name to + description: Blockchain to get the yield for. Normalize the network name to its popular representation in the ecosystem. Use '*' when parameter not available or the user wants all networks. type: string token: - description: - Token to get the yield for. Normalize the token name to its popular + description: Token to get the yield for. Normalize the token name to its popular symbol representation in the ecoystem. Use '*' when parameter not available or the user wants all tokens. type: string required: - - token - - network - - count + - token + - network + - count type: object return_value_description: JSON object with yield information - _name_: fetch_price - description: - Get the price of a token. Note, when the quoteToken isn't explicitly + description: Get the price of a token. Note, when the quoteToken isn't explicitly specified assume it to be USD parameters: properties: @@ -250,8 +232,8 @@ description: Token to use as units for price. type: string required: - - basetoken - - quotetoken + - basetoken + - quotetoken type: object return_value_description: price of a base token in units of a quote token. - _name_: ens_from_address @@ -262,7 +244,7 @@ description: Address of the account or wallet. type: string required: - - address + - address type: object return_value_description: a humanreadable string with ENS domain - _name_: address_from_ens @@ -273,7 +255,7 @@ description: Domain name of the account or wallet. type: string required: - - domain + - domain type: object return_value_description: a humanreadable string with wallet address - _name_: register_ens_domain @@ -284,12 +266,11 @@ description: Domain name to register. type: string required: - - domain + - domain type: object - return_value_description: "" + return_value_description: '' - _name_: set_ens_text - description: - Set the text record for an ENS domain that ends with *.eth in a key + description: Set the text record for an ENS domain that ends with *.eth in a key value pair format. parameters: properties: @@ -303,11 +284,11 @@ description: Value of the text record. type: string required: - - domain - - key - - value + - domain + - key + - value type: object - return_value_description: "" + return_value_description: '' - _name_: set_ens_primary_name description: Set a primary ENS name for their connected wallet account. parameters: @@ -316,12 +297,11 @@ description: Domain name to use as primary ENS name. type: string required: - - domain + - domain type: object - return_value_description: "" + return_value_description: '' - _name_: set_ens_avatar_nft - description: - Set an nft as their ENS domain's avatar. Do not guess any parameter, + description: Set an nft as their ENS domain's avatar. Do not guess any parameter, if any parameter is missing, set the default value as 'None'. parameters: properties: @@ -338,12 +318,12 @@ description: Name of NFT collection. Use an empty string if the input parameter value is unknown but do not ask user to input empty string. type: string required: - - domain - - nftContractAddress - - nftId - - collectionName + - domain + - nftContractAddress + - nftId + - collectionName type: object - return_value_description: "" + return_value_description: '' - _name_: aave_supply description: Deposit or supply tokens into Aave project parameters: @@ -355,10 +335,10 @@ description: Token to supply. type: string required: - - token - - amount + - token + - amount type: object - return_value_description: "" + return_value_description: '' - _name_: aave_borrow description: Borrow tokens from Aave project parameters: @@ -370,10 +350,10 @@ description: Token to borrow. type: string required: - - token - - amount + - token + - amount type: object - return_value_description: "" + return_value_description: '' - _name_: aave_repay description: Repay back borrowed tokens from Aave project parameters: @@ -385,10 +365,10 @@ description: Token to repay. type: string required: - - token - - amount + - token + - amount type: object - return_value_description: "" + return_value_description: '' - _name_: aave_withdraw description: Withdraw deposited tokens from Aave project parameters: @@ -400,13 +380,12 @@ description: Token to withdraw. type: string required: - - token - - amount + - token + - amount type: object - return_value_description: "" + return_value_description: '' - _name_: fetch_balance - description: - Get the balance of a token in an account or wallet. Don't use this + description: Get the balance of a token in an account or wallet. Don't use this if we don't have the address. parameters: properties: @@ -417,15 +396,13 @@ description: Token to get the balance of. type: string required: - - token - - address + - token + - address type: object - return_value_description: - balance of a token in an account or wallet, in decimal + return_value_description: balance of a token in an account or wallet, in decimal units - _name_: display_yield_farm - description: - Used for the Compound project to allow the user to yield farm by putting + description: Used for the Compound project to allow the user to yield farm by putting tokens or depositing tokens of a certain amount into the Compound project. parameters: properties: @@ -433,8 +410,7 @@ description: Amount of token to deposit in the project. type: string network: - description: - Network or blockchain of the project. Default to Ethereum if + description: Network or blockchain of the project. Default to Ethereum if not specified. type: string project: @@ -444,15 +420,14 @@ description: Token to deposit in the project. type: string required: - - project - - network - - token - - amount + - project + - network + - token + - amount type: object - return_value_description: "" + return_value_description: '' - _name_: fetch_app_info - description: - Used when we need to handle common questions and answers about the + description: Used when we need to handle common questions and answers about the chat assistant app, what it can do, how to interact with it, at a high-level. Only useful for questions about the chat app experience. It does not know specific information about the web3 ecosystem, of tokens or NFTs or contracts, or access @@ -460,52 +435,28 @@ parameters: properties: query: - description: - a standalone query with all relevant contextual details pertaining + description: a standalone query with all relevant contextual details pertaining to the chat web application. type: string required: - - query + - query type: object - return_value_description: - an answer to the question, with suggested followup questions + return_value_description: an answer to the question, with suggested followup questions if available -# -# deprecating scraped sites in favor of link suggestion - leaving for future reference -# in case we ever want to revive -# -# - _name_: fetch_scraped_sites -# description: -# Answer questions using general content scraped from web3 sites. It -# does not know about this app or about widget magic commands for invoking transactions -# or fetching data about specific things like NFTs or balances. -# parameters: -# properties: -# query: -# description: -# a standalone question representing information to be retrieved -# from the index. -# type: string -# required: -# - query -# type: object -# return_value_description: a summarized answer with source citations -- _name_: fetch_link_suggestion - description: - Answer questions using general content scraped from web3 sites. It +- _name_: fetch_scraped_sites + description: Answer questions using general content scraped from web3 sites. It does not know about this app or about widget magic commands for invoking transactions or fetching data about specific things like NFTs or balances. parameters: properties: query: - description: - a standalone question representing information to be retrieved + description: a standalone question representing information to be retrieved from the index. type: string required: - - query + - query type: object - return_value_description: a summarized answer with source citations and links + return_value_description: a summarized answer with source citations - _name_: display_zksync_deposit description: Used to bridge and deposit tokens from mainnet L1 to zksync L2. parameters: @@ -517,10 +468,10 @@ description: token to deposit type: string required: - - token - - amount + - token + - amount type: object - return_value_description: "" + return_value_description: '' - _name_: display_zksync_withdraw description: Used to withdraw tokens from zksync L2 to mainnet L1 parameters: @@ -532,10 +483,10 @@ description: token to deposit type: string required: - - token - - amount + - token + - amount type: object - return_value_description: "" + return_value_description: '' - _name_: fetch_my_balance description: Get the balance of a token in the user's connected wallet parameters: @@ -544,7 +495,7 @@ description: Token to get the balance of. type: string required: - - token + - token type: object return_value_description: balance of a token in connected wallet, in decimal units - _name_: fetch_gas @@ -555,7 +506,7 @@ description: Address of the account or wallet to check the gas of. type: string required: - - address + - address type: object return_value_description: the gas amount used - _name_: fetch_eth_in @@ -566,7 +517,7 @@ description: Address of the account or wallet to check the inflow ETH. type: string required: - - address + - address type: object return_value_description: the inflow ETH amount - _name_: fetch_eth_out @@ -577,12 +528,11 @@ description: Address of the account or wallet to check the outflow ETH. type: string required: - - address + - address type: object return_value_description: the outflow ETH amount - _name_: display_uniswap - description: - 'use the Uniswap decentralized application for trading one token for + description: 'use the Uniswap decentralized application for trading one token for another. To create a Uniswap transaction, you need either: 1.) A token to sell, a token to buy, the transaction keyword "SELLAMOUNT", and @@ -593,8 +543,7 @@ parameters: properties: amount: - description: - Amount of token described by transaction keyword that we are + description: Amount of token described by transaction keyword that we are trying to buy or sell. type: string tokenToBuy: @@ -604,17 +553,16 @@ description: Token to sell in the swap transaction. type: string transactionKeyword: - description: - Either SELLAMOUNT if amount refers to token to sell or BUYAMOUNT + description: Either SELLAMOUNT if amount refers to token to sell or BUYAMOUNT if amount refers to token to buy. type: string required: - - tokenToSell - - tokenToBuy - - transactionKeyword - - amount + - tokenToSell + - tokenToBuy + - transactionKeyword + - amount type: object - return_value_description: "" + return_value_description: '' - _name_: fetch_nfts_owned_by_address_or_domain description: Used to fetch NFTs owned by a wallet address or ENS domain on a particular network parameters: @@ -642,7 +590,7 @@ type: object return_value_description: List of NFT Assets - _name_: display_stake_sfrxeth - description: "Exchange ETH for sfrxETH using the frxETHMinter contract" + description: 'Exchange ETH for sfrxETH using the frxETHMinter contract' parameters: properties: receiver: @@ -652,10 +600,10 @@ description: Amount of ETH to exchange for sfrxETH type: string required: - - receiver - - value + - receiver + - value type: object - return_value_description: "" + return_value_description: '' - _name_: display_arbitrum_deposit description: Used to bridge/deposit ETH or token from mainnet L1 to arbitrum L2. parameters: @@ -667,10 +615,10 @@ description: amount to deposit type: string required: - - token - - amount + - token + - amount type: object - return_value_description: "" + return_value_description: '' - _name_: display_arbitrum_withdraw description: Used to withdraw ETH from arbitrum L2 to mainnet L1 parameters: @@ -682,10 +630,10 @@ description: amount to withdraw type: string required: - - token - - amount + - token + - amount type: object - return_value_description: "" + return_value_description: '' - _name_: display_yield_protocol_lend description: use the yield protocol to lend tokens at a fixed rate parameters: From beb976a7d7c1bcf529aa31f316fa43bdbdfdfcec Mon Sep 17 00:00:00 2001 From: Jacob Bryant Date: Fri, 22 Sep 2023 09:52:49 -0400 Subject: [PATCH 13/17] revert formatting changes in widget.yaml --- knowledge_base/widgets.yaml | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/knowledge_base/widgets.yaml b/knowledge_base/widgets.yaml index 5bf628f3..79708ea9 100644 --- a/knowledge_base/widgets.yaml +++ b/knowledge_base/widgets.yaml @@ -443,20 +443,40 @@ type: object return_value_description: an answer to the question, with suggested followup questions if available -- _name_: fetch_scraped_sites - description: Answer questions using general content scraped from web3 sites. It +# +# deprecating scraped sites in favor of link suggestion - leaving for future reference +# in case we ever want to revive +# +# - _name_: fetch_scraped_sites +# description: Answer questions using general content scraped from web3 sites. It +# does not know about this app or about widget magic commands for invoking transactions +# or fetching data about specific things like NFTs or balances. +# parameters: +# properties: +# query: +# description: a standalone question representing information to be retrieved +# from the index. +# type: string +# required: +# - query +# type: object +# return_value_description: a summarized answer with source citations +- _name_: fetch_link_suggestion + description: + Answer questions using general content scraped from web3 sites. It does not know about this app or about widget magic commands for invoking transactions or fetching data about specific things like NFTs or balances. parameters: properties: query: + description: a standalone question representing information to be retrieved description: a standalone question representing information to be retrieved from the index. type: string required: - query type: object - return_value_description: a summarized answer with source citations + return_value_description: a summarized answer with source citations and links - _name_: display_zksync_deposit description: Used to bridge and deposit tokens from mainnet L1 to zksync L2. parameters: From 1bf18292fbabac1f41c3e71e11cecf3d5bda3654 Mon Sep 17 00:00:00 2001 From: Jacob Bryant Date: Fri, 22 Sep 2023 10:54:22 -0400 Subject: [PATCH 14/17] removing unneeded fields, skip url vectorize --- index/dapps.py | 63 +++----------------------------------------------- 1 file changed, 3 insertions(+), 60 deletions(-) diff --git a/index/dapps.py b/index/dapps.py index f35fa26b..d9bbc308 100644 --- a/index/dapps.py +++ b/index/dapps.py @@ -41,11 +41,10 @@ def create_schema(delete_first: bool = False) -> None: "properties": [ {"name": DAPP_NAME, "dataType": ["text"]}, {"name": DAPP_DESCRIPTION, "dataType": ["text"]}, - {"name": DAPP_URL, "dataType": ["text"]}, { - "name": "twitterHandle", + "name": DAPP_URL, "dataType": ["text"], - "description": "The Twitter handle of the Dapp", + "description": "The URL of the Dapp", "moduleConfig": { "text2vec-openai": { "skip": True, @@ -53,61 +52,6 @@ def create_schema(delete_first: bool = False) -> None: } } }, - { - "name": "blogLinks", - "dataType": ["text[]"], - "description": "Links to the blog posts related to the Dapp", - "moduleConfig": { - "text2vec-openai": { - "skip": True, - "vectorizePropertyName": False - } - } - }, - { - "name": "discord", - "dataType": ["text"], - "description": "The Discord server link of the Dapp", - "moduleConfig": { - "text2vec-openai": { - "skip": True, - "vectorizePropertyName": False - } - } - }, - { - "name": "facebook", - "dataType": ["text"], - "description": "The Facebook page link of the Dapp", - "moduleConfig": { - "text2vec-openai": { - "skip": True, - "vectorizePropertyName": False - } - } - }, - { - "name": "instagram", - "dataType": ["text"], - "description": "The Instagram profile link of the Dapp", - "moduleConfig": { - "text2vec-openai": { - "skip": True, - "vectorizePropertyName": False - } - } - }, - { - "name": "telegram", - "dataType": ["text"], - "description": "The Telegram channel link of the Dapp", - "moduleConfig": { - "text2vec-openai": { - "skip": True, - "vectorizePropertyName": False - } - } - } ] } @@ -128,13 +72,12 @@ def backfill(): documents = [d.pop("name") for d in dapp_list] # Use the remaining fields in each dapp to populate the 'metadatas' list - # is this the best 'metadatas' to use? metadatas = dapp_list create_schema(delete_first=True) client = get_client() - w = Weaviate(client, INDEX_NAME, DAPP_NAME) # is this a proper 3rd argument? + w = Weaviate(client, INDEX_NAME, DAPP_NAME) w.add_texts(documents, metadatas) except Exception as e: print(f"Error during backfill in dapps.py {str(e)}") From a054f4dde41a23ed8844b76a1b91a709328a78b4 Mon Sep 17 00:00:00 2001 From: Jacob Bryant Date: Fri, 22 Sep 2023 13:45:05 -0400 Subject: [PATCH 15/17] upgrading link suggestion prompt --- tools/index_link_suggestion.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/tools/index_link_suggestion.py b/tools/index_link_suggestion.py index 67c59d58..beeaf45f 100644 --- a/tools/index_link_suggestion.py +++ b/tools/index_link_suggestion.py @@ -8,6 +8,8 @@ import registry import streaming from .index_lookup import IndexLookupTool +from gpt_index.utils import ErrorToRetry, retry_on_exceptions_with_backoff +import utils.timing as timing TEMPLATE = '''You are a web3 assistant. You help users with answering web3-related questions. Your responses should sound natural, helpful, cheerful, and engaging, and you should use easy to understand language with explanations for jargon. @@ -51,11 +53,28 @@ def __init__( def _run(self, query: str) -> str: """Query index and answer question using document chunks.""" - task_info = super()._run(query) + + docs = retry_on_exceptions_with_backoff( + lambda: self._index.similarity_search(query, k=self._top_k), + [ErrorToRetry(TypeError)], + ) + timing.log('widget_index_lookup_done') + + task_info = "" + for i, doc in enumerate(docs): + dapp_info = f"""### DAPP {i+1}\nname: {doc.metadata['name']}\ndescription: {doc.page_content}\nurl: {doc.metadata['url']}\n\n""" + task_info += dapp_info + example = { "task_info": task_info, "question": query, "stop": "User", } + self._chain.verbose = True result = self._chain.run(example) + return result.strip() + + + + From fe0fb6a1e046f3bc354c190fe1e1a0f7d86e68e4 Mon Sep 17 00:00:00 2001 From: Jacob Bryant Date: Fri, 22 Sep 2023 13:50:12 -0400 Subject: [PATCH 16/17] removing comment --- index/dapps.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/index/dapps.py b/index/dapps.py index d9bbc308..588e2d7c 100644 --- a/index/dapps.py +++ b/index/dapps.py @@ -65,13 +65,11 @@ def backfill(): try: from langchain.vectorstores import Weaviate - with open('./knowledge_base/dapps_ranked.json') as f: + with open('./knowledge_base/dapps_ranked_unique.json') as f: dapp_list = json.load(f) - # Extract the 'name' field from each dapp and store it in the 'documents' list - documents = [d.pop("name") for d in dapp_list] + documents = [d.pop("description") for d in dapp_list] - # Use the remaining fields in each dapp to populate the 'metadatas' list metadatas = dapp_list create_schema(delete_first=True) From ffb6c33057e917d628135ba3efffbd07b05c1f32 Mon Sep 17 00:00:00 2001 From: Jacob Bryant Date: Fri, 22 Sep 2023 13:56:20 -0400 Subject: [PATCH 17/17] remove duplicated description and version bump --- knowledge_base/widgets.yaml | 1 - utils/constants.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/knowledge_base/widgets.yaml b/knowledge_base/widgets.yaml index 79708ea9..44b28416 100644 --- a/knowledge_base/widgets.yaml +++ b/knowledge_base/widgets.yaml @@ -469,7 +469,6 @@ parameters: properties: query: - description: a standalone question representing information to be retrieved description: a standalone question representing information to be retrieved from the index. type: string diff --git a/utils/constants.py b/utils/constants.py index cd74a884..3c9fa714 100644 --- a/utils/constants.py +++ b/utils/constants.py @@ -53,7 +53,7 @@ WIDGET_INFO_TOKEN_LIMIT = 4000 # Widget Index -WIDGET_INDEX_NAME = "WidgetV20" +WIDGET_INDEX_NAME = "WidgetV25" def get_widget_index_name(): if env.is_local():