1+ import json
12from pathlib import Path
23from typing import Optional , Type
34
@@ -28,23 +29,33 @@ class RulesRetriever(BaseTool):
2829 rules_path : Path
2930 embeddings : OllamaEmbeddings
3031 vector_store : None | InMemoryVectorStore = None
32+ recreate_storage : bool = False
3133
3234 name : str = "RulesRetriever"
3335 description : str = "Provides relevant information for the latest Magic: The Gathering rules, as of November 2024."
3436 args_schema : Type [BaseModel ] = StrQuery
3537
36- def __init__ (self , rules_path : Path , embeddings : OllamaEmbeddings ):
37- super ().__init__ (rules_path = rules_path , embeddings = embeddings )
38+ def __init__ (self , rules_path : Path , embeddings : OllamaEmbeddings , recreate_storage : bool = False ):
39+ super ().__init__ (rules_path = rules_path , embeddings = embeddings , recreate_storage = recreate_storage )
3840 self .create_storage ()
3941
4042 def create_storage (self ) -> None :
41- self .vector_store = InMemoryVectorStore (self .embeddings )
42- loader = PyPDFLoader (str (self .rules_path ))
43- docs = loader .load ()
44- text_splitter = RecursiveCharacterTextSplitter (chunk_size = 1000 , chunk_overlap = 200 , add_start_index = True )
45- all_splits = text_splitter .split_documents (docs )
46- print (f"Loaded { len (all_splits )} document splits." )
47- self .vector_store .add_documents (documents = all_splits )
43+ if self .recreate_storage or not (self .rules_path .parent / "rules.vec" ).exists ():
44+ self .vector_store = InMemoryVectorStore (self .embeddings )
45+ loader = PyPDFLoader (str (self .rules_path ))
46+ docs = loader .load ()
47+ text_splitter = RecursiveCharacterTextSplitter (chunk_size = 1000 , chunk_overlap = 200 , add_start_index = True )
48+ all_splits = text_splitter .split_documents (docs )
49+ print (f"Loaded { len (all_splits )} document splits." )
50+ self .vector_store .add_documents (documents = all_splits )
51+ print (f"Dumping vectors to disk { self .rules_path .parent / 'rules.vec' } ..." )
52+ self .vector_store .dump (str (self .rules_path .parent / "rules.vec" ))
53+
54+ else :
55+ print (f"Loading vectors from disk { self .rules_path .parent / 'rules.vec' } ..." )
56+ self .vector_store = InMemoryVectorStore (self .embeddings ).load (
57+ str (self .rules_path .parent / "rules.vec" ), self .embeddings
58+ )
4859
4960 def _run (self , query : str , run_manager : Optional [CallbackManagerForToolRun ] = None ) -> tuple [str , list ]:
5061 """Retrieve information related to a query."""
@@ -77,7 +88,7 @@ class CardsRetriever(BaseTool):
7788 """
7889 recreate_storage : bool = False
7990
80- name : str = "CardsRetriever "
91+ name : str = "SetsRetriever "
8192 description : str = "Provides relevant information for cards in Magic."
8293 args_schema : Type [BaseModel ] = ScalableQuery
8394
@@ -97,7 +108,8 @@ def __init__(self, sets_path: Path, llm: ChatOllama, embeddings: OllamaEmbedding
97108 "Include the name of the card in the summary."
98109 "Include details of the card's role in that, strengths, and weaknesses."
99110 "Include the mana colors of the card, along with the a qualitative description of the mana cost."
100- "Do not return anything other than the summary of the card." ,
111+ "Do not return anything other than the summary of the card."
112+ "Make sure to check that your summary accurately reflects the card." ,
101113 ),
102114 ("user" , "{card}" ),
103115 ]
@@ -134,22 +146,26 @@ def create_storage(self) -> None:
134146 # Create card summaries
135147 print (f"Creating summaries for { len (filtered_cards )} cards..." )
136148 for card in tqdm (filtered_cards ):
137- summary = self .llm .invoke (self .summary_prompt .invoke ({"card" : card .page_content })).content
149+ card_dict = json .loads (card .page_content )
150+ if "land" in card_dict ["types" ]:
151+ summary = card_dict ["text" ]
152+ else :
153+ summary = self .llm .invoke (self .summary_prompt .invoke ({"card" : card .page_content })).content
138154 # clean up the summary
139155 summary = summary .replace ("\n " , " " )
140156 summary = summary .replace ('"' , "" )
141- card .page_content = '{"summary": "' + summary + '", ' + card .page_content [1 :] # type: ignore [operator]
157+ card .page_content = '{"summary": "' + summary + '", ' + card .page_content [1 :]
142158
143159 self .card_vector_store .add_documents (documents = filtered_cards )
144160 print (f"Loaded { len (filtered_cards )} cards from set { s } ." )
145161
146- print (f"Dumping vectors to disk { self .sets_path / 'cards.vec' } " )
162+ print (f"Dumping vectors to disk { self .sets_path / 'cards.vec' } ... " )
147163 self .card_vector_store .dump (str (self .sets_path / "cards.vec" ))
148164
149165 else :
150166 print (f"Loading vectors from disk { self .sets_path / 'cards.vec' } ..." )
151167 self .card_vector_store = InMemoryVectorStore (self .embeddings ).load (
152- path = str (self .sets_path / "cards.vec" ), embedding = self .embeddings
168+ str (self .sets_path / "cards.vec" ), self .embeddings
153169 )
154170
155171 def _run (
0 commit comments