Sajil Awale commited on
Commit
1da2ffa
·
1 Parent(s): 10e22f9

add final code

Browse files
app.py ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import asyncio
3
+ import os
4
+ from money_rag import MoneyRAG
5
+
6
+ st.set_page_config(page_title="MoneyRAG", layout="wide")
7
+
8
+ # Sidebar for Authentication
9
+ with st.sidebar:
10
+ st.header("Authentication")
11
+ provider = st.selectbox("LLM Provider", ["Google", "OpenAI"])
12
+
13
+ if provider == "Google":
14
+ models = ["gemini-3-flash-preview", "gemini-3-pro-image-preview", "gemini-2.5-pro", "gemini-2.5-flash", "gemini-2.5-flash-lite"]
15
+ embeddings = ["text-embedding-004"]
16
+ else:
17
+ models = ["gpt-5-mini", "gpt-5-nano", "gpt-4o-mini", "gpt-4o"]
18
+ embeddings = ["text-embedding-3-small", "text-embedding-3-large", "text-embedding-ada-002"]
19
+
20
+ model_name = st.selectbox("Choose Decoder Model", models)
21
+ embed_name = st.selectbox("Choose Embedding Model", embeddings)
22
+ api_key = st.text_input("API Key", type="password")
23
+
24
+ auth_button = st.button("Authenticate")
25
+ if auth_button and api_key:
26
+ st.session_state.rag = MoneyRAG(provider, model_name, embed_name, api_key)
27
+ st.success("Authenticated!")
28
+
29
+ # Main Window
30
+ st.title("MoneyRAG 💰")
31
+ st.subheader("Where is my money?")
32
+ st.markdown("""
33
+ This app helps you analyze your personal finances using AI.
34
+ Upload your bank/credit card CSV statements to chat with your data semantically.
35
+ """)
36
+
37
+ if "rag" in st.session_state:
38
+ uploaded_files = st.file_uploader("Upload CSV transactions", accept_multiple_files=True, type=['csv'])
39
+
40
+ if uploaded_files:
41
+ if st.button("Ingest Data"):
42
+ temp_paths = []
43
+ for uploaded_file in uploaded_files:
44
+ path = os.path.join(st.session_state.rag.temp_dir, uploaded_file.name)
45
+ with open(path, "wb") as f:
46
+ f.write(uploaded_file.getbuffer())
47
+ temp_paths.append(path)
48
+
49
+ with st.spinner("Ingesting and vectorizing..."):
50
+ asyncio.run(st.session_state.rag.setup_session(temp_paths))
51
+ st.success("Data ready for chat!")
52
+
53
+ # Chat Interface
54
+ st.divider()
55
+ if "messages" not in st.session_state:
56
+ st.session_state.messages = []
57
+
58
+ for message in st.session_state.messages:
59
+ with st.chat_message(message["role"]):
60
+ st.markdown(message["content"])
61
+
62
+ if prompt := st.chat_input("Ask about your spending..."):
63
+ st.session_state.messages.append({"role": "user", "content": prompt})
64
+ with st.chat_message("user"):
65
+ st.markdown(prompt)
66
+
67
+ with st.chat_message("assistant"):
68
+ with st.spinner("Thinking..."):
69
+ response = asyncio.run(st.session_state.rag.chat(prompt))
70
+ st.markdown(response)
71
+ st.session_state.messages.append({"role": "assistant", "content": response})
72
+ else:
73
+ st.info("Please authenticate in the sidebar to start.")
mcp_server.py CHANGED
@@ -1,7 +1,7 @@
1
  from fastmcp import FastMCP
2
  from langchain_qdrant import QdrantVectorStore
3
  from qdrant_client import QdrantClient
4
- from langchain_google_vertexai import VertexAIEmbeddings
5
  from dotenv import load_dotenv
6
  import os
7
 
@@ -60,7 +60,6 @@ def get_database_schema() -> str:
60
  """Complete schema information for the money_rag database."""
61
  return get_schema_info()
62
 
63
-
64
  @mcp.tool()
65
  def query_database(query: str) -> str:
66
  """Execute a SELECT query on the money_rag SQLite database.
@@ -122,9 +121,8 @@ def query_database(query: str) -> str:
122
 
123
  def get_vector_store():
124
  """Initialize connection to the Qdrant vector store"""
125
- # Initialize Embedding Model
126
- # Uses environment variables/default gcloud auth
127
- embeddings = VertexAIEmbeddings(model_name="text-embedding-005")
128
 
129
  # Connect to Qdrant (Persistent Disk Mode at specific path)
130
  # We ensure the directory exists so Qdrant can write to it.
@@ -196,4 +194,4 @@ def clear_database() -> str:
196
 
197
  if __name__ == "__main__":
198
  # Runs the server over stdio
199
- mcp.run()
 
1
  from fastmcp import FastMCP
2
  from langchain_qdrant import QdrantVectorStore
3
  from qdrant_client import QdrantClient
4
+ from langchain_google_genai import GoogleGenerativeAIEmbeddings
5
  from dotenv import load_dotenv
6
  import os
7
 
 
60
  """Complete schema information for the money_rag database."""
61
  return get_schema_info()
62
 
 
63
  @mcp.tool()
64
  def query_database(query: str) -> str:
65
  """Execute a SELECT query on the money_rag SQLite database.
 
121
 
122
  def get_vector_store():
123
  """Initialize connection to the Qdrant vector store"""
124
+ # Initialize Embedding Model using Google AI Studio
125
+ embeddings = GoogleGenerativeAIEmbeddings(model="text-embedding-004")
 
126
 
127
  # Connect to Qdrant (Persistent Disk Mode at specific path)
128
  # We ensure the directory exists so Qdrant can write to it.
 
194
 
195
  if __name__ == "__main__":
196
  # Runs the server over stdio
197
+ mcp.run(transport="stdio")
money_rag.py ADDED
@@ -0,0 +1,255 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import uuid
3
+ import asyncio
4
+ import pandas as pd
5
+ import sqlite3
6
+ import shutil
7
+ import tempfile
8
+ from typing import List, Optional
9
+ from dataclasses import dataclass
10
+
11
+ from langchain.chat_models import init_chat_model
12
+ from langchain_core.prompts import ChatPromptTemplate
13
+ from langchain_core.output_parsers import JsonOutputParser
14
+ from langchain_core.tools import tool
15
+ from langchain_community.utilities import SQLDatabase
16
+ from langchain_qdrant import QdrantVectorStore
17
+ from qdrant_client import QdrantClient
18
+ from qdrant_client.http.models import Distance, VectorParams
19
+ from langgraph.runtime import get_runtime
20
+ from langgraph.checkpoint.memory import InMemorySaver
21
+ from langchain.agents import create_agent
22
+ from langchain_community.tools import DuckDuckGoSearchRun
23
+ from langchain_mcp_adapters.client import MultiServerMCPClient
24
+
25
+ # Import specific embeddings
26
+ from langchain_google_genai import GoogleGenerativeAIEmbeddings
27
+ from langchain_openai import OpenAIEmbeddings
28
+
29
+ class MoneyRAG:
30
+ def __init__(self, llm_provider: str, model_name: str, embedding_model_name: str, api_key: str):
31
+ self.llm_provider = llm_provider.lower()
32
+ self.model_name = model_name
33
+ self.embedding_model_name = embedding_model_name
34
+
35
+ # Set API Keys
36
+ if self.llm_provider == "google":
37
+ os.environ["GOOGLE_API_KEY"] = api_key
38
+ self.embeddings = GoogleGenerativeAIEmbeddings(model=embedding_model_name)
39
+ provider_name = "google_genai"
40
+ else:
41
+ os.environ["OPENAI_API_KEY"] = api_key
42
+ self.embeddings = OpenAIEmbeddings(model=embedding_model_name)
43
+ provider_name = "openai"
44
+
45
+ # Initialize LLM
46
+ self.llm = init_chat_model(
47
+ self.model_name,
48
+ model_provider=provider_name,
49
+ )
50
+
51
+ # Temporary paths for this session
52
+ self.temp_dir = tempfile.mkdtemp()
53
+ os.environ["DATA_DIR"] = self.temp_dir # Harmonize with mcp_server.py
54
+ self.db_path = os.path.join(self.temp_dir, "money_rag.db")
55
+ self.qdrant_path = os.path.join(self.temp_dir, "qdrant_db")
56
+
57
+ self.db: Optional[SQLDatabase] = None
58
+ self.vector_store: Optional[QdrantVectorStore] = None
59
+ self.agent = None
60
+ self.mcp_client: Optional[MultiServerMCPClient] = None
61
+ self.search_tool = DuckDuckGoSearchRun()
62
+ self.merchant_cache = {} # Session-based cache for merchant enrichment
63
+
64
+ async def setup_session(self, csv_paths: List[str]):
65
+ """Ingests CSVs and sets up DBs."""
66
+ for path in csv_paths:
67
+ await self._ingest_csv(path)
68
+
69
+ self.db = SQLDatabase.from_uri(f"sqlite:///{self.db_path}")
70
+ self.vector_store = self._sync_to_qdrant()
71
+ await self._init_agent()
72
+
73
+ async def _ingest_csv(self, file_path):
74
+ df = pd.read_csv(file_path)
75
+ headers = df.columns.tolist()
76
+ sample_data = df.head(10).to_json()
77
+
78
+ prompt = ChatPromptTemplate.from_template("""
79
+ Act as a financial data parser. Analyze this CSV data:
80
+ Filename: {filename}
81
+ Headers: {headers}
82
+ Sample Data: {sample}
83
+
84
+ TASK:
85
+ 1. Map the CSV columns to standard fields: date, description, amount, and category.
86
+ 2. Determine the 'sign_convention' for spending.
87
+
88
+ RULES:
89
+ - If the filename suggests 'Discover' credit card, spending are usually POSITIVE.
90
+ - If the filename suggests 'Chase' credit card, spending are usually NEGATIVE.
91
+
92
+ - Analyze the 'sign_convention' for spending (outflows):
93
+ - Look at the sample data for known merchants or spending patterns.
94
+ - If spending (like a restaurant or store) is NEGATIVE (e.g., -25.00), the convention is 'spending_is_negative'.
95
+ - If spending is POSITIVE (e.g., 25.00), the convention is 'spending_is_positive'.
96
+
97
+ OUTPUT FORMAT (JSON ONLY):
98
+ {{
99
+ "date_col": "column_name",
100
+ "desc_col": "column_name",
101
+ "amount_col": "column_name",
102
+ "category_col": "column_name or null",
103
+ "sign_convention": "spending_is_negative" | "spending_is_positive"
104
+ }}
105
+ """)
106
+
107
+ chain = prompt | self.llm | JsonOutputParser()
108
+ mapping = await chain.ainvoke({"headers": headers, "sample": sample_data, "filename": os.path.basename(file_path)})
109
+
110
+ standard_df = pd.DataFrame()
111
+ standard_df['id'] = [str(uuid.uuid4()) for _ in range(len(df))]
112
+ standard_df['transaction_date'] = pd.to_datetime(df[mapping['date_col']])
113
+ standard_df['description'] = df[mapping['desc_col']]
114
+
115
+ raw_amounts = pd.to_numeric(df[mapping['amount_col']])
116
+ standard_df['amount'] = raw_amounts * -1 if mapping['sign_convention'] == "spending_is_negative" else raw_amounts
117
+ standard_df['category'] = df[mapping.get('category_col')] if mapping.get('category_col') else 'Uncategorized'
118
+ standard_df['source_file'] = os.path.basename(file_path)
119
+
120
+ # --- Async Enrichment Step ---
121
+ print(f" ✨ Enriching descriptions for {os.path.basename(file_path)}...")
122
+ unique_descriptions = standard_df['description'].unique()
123
+ sem = asyncio.Semaphore(5)
124
+
125
+ async def get_merchant_info(description):
126
+ if description in self.merchant_cache:
127
+ return self.merchant_cache[description]
128
+
129
+ async with sem:
130
+ try:
131
+ await asyncio.sleep(0.05) # Jitter
132
+ print(f" 🔍 Web searching: {description}...")
133
+ result = await self.search_tool.ainvoke(f"What type of business / store is '{description}'?")
134
+ self.merchant_cache[description] = result
135
+ return result
136
+ except Exception as e:
137
+ print(f" ⚠️ Search failed for {description}: {e}")
138
+ return "Unknown"
139
+
140
+ tasks = [get_merchant_info(desc) for desc in unique_descriptions]
141
+ enrichment_results = await asyncio.gather(*tasks)
142
+
143
+ desc_map = dict(zip(unique_descriptions, enrichment_results))
144
+ standard_df['enriched_info'] = standard_df['description'].map(desc_map).fillna("")
145
+
146
+ conn = sqlite3.connect(self.db_path)
147
+ standard_df.to_sql("transactions", conn, if_exists="append", index=False)
148
+ conn.close()
149
+
150
+ def _sync_to_qdrant(self):
151
+ client = QdrantClient(path=self.qdrant_path)
152
+ collection = "transactions"
153
+
154
+ conn = sqlite3.connect(self.db_path)
155
+ df = pd.read_sql_query("SELECT * FROM transactions", conn)
156
+ conn.close()
157
+
158
+ # Check for empty dataframe
159
+ if df.empty:
160
+ raise ValueError("No transactions found in database. Please ingest CSV files first.")
161
+
162
+ # Dynamically detect embedding dimension
163
+ sample_embedding = self.embeddings.embed_query("test")
164
+ embedding_dim = len(sample_embedding)
165
+
166
+ client.recreate_collection(
167
+ collection_name=collection,
168
+ vectors_config=VectorParams(size=embedding_dim, distance=Distance.COSINE),
169
+ )
170
+
171
+ vs = QdrantVectorStore(client=client, collection_name=collection, embedding=self.embeddings)
172
+
173
+ # Use description + category + enrichment for vectorization
174
+ texts = []
175
+ for _, row in df.iterrows():
176
+ enriched = row.get('enriched_info', '')
177
+ base_text = f"{row['description']} ({row['category']})"
178
+ if enriched and enriched != "Unknown" and enriched != "":
179
+ texts.append(f"{base_text} - {enriched}")
180
+ else:
181
+ texts.append(base_text)
182
+
183
+ metadatas = df[['id', 'amount', 'category', 'transaction_date']].to_dict('records')
184
+ for m in metadatas: m['transaction_date'] = str(m['transaction_date'])
185
+
186
+ vs.add_texts(texts=texts, metadatas=metadatas)
187
+ return vs
188
+
189
+ async def _init_agent(self):
190
+ # 1. Initialize MCP client with absolute path to server
191
+ server_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "mcp_server.py")
192
+
193
+ self.mcp_client = MultiServerMCPClient(
194
+ {
195
+ "money_rag": {
196
+ "transport": "stdio",
197
+ "command": "python",
198
+ "args": [server_path],
199
+ "env": os.environ.copy(),
200
+ }
201
+ }
202
+ )
203
+
204
+ # 2. Get tools from MCP server
205
+ mcp_tools = await self.mcp_client.get_tools()
206
+
207
+ # 3. Define the Agent with MCP Tools
208
+ system_prompt = (
209
+ "You are a financial analyst. Use the provided tools to query the database "
210
+ "and perform semantic searches. Spending is POSITIVE (>0). "
211
+ "Always explain your findings clearly."
212
+ )
213
+
214
+ self.agent = create_agent(
215
+ model=self.llm,
216
+ tools=mcp_tools,
217
+ system_prompt=system_prompt,
218
+ checkpointer=InMemorySaver(),
219
+ )
220
+
221
+ async def chat(self, query: str):
222
+ config = {"configurable": {"thread_id": "session_1"}}
223
+
224
+ result = await self.agent.ainvoke(
225
+ {"messages": [{"role": "user", "content": query}]},
226
+ config,
227
+ )
228
+
229
+ # Extract content - handle both string and list formats
230
+ content = result["messages"][-1].content
231
+
232
+ # If content is a list (Gemini format), extract text from blocks
233
+ if isinstance(content, list):
234
+ text_parts = []
235
+ for block in content:
236
+ if isinstance(block, dict) and block.get("type") == "text":
237
+ text_parts.append(block.get("text", ""))
238
+ return "\n".join(text_parts)
239
+
240
+ # If content is already a string (OpenAI format), return as-is
241
+ return content
242
+
243
+ async def cleanup(self):
244
+ """Delete temporary session files and close MCP client."""
245
+ if self.mcp_client:
246
+ try:
247
+ await self.mcp_client.close()
248
+ except Exception as e:
249
+ print(f"Warning: Failed to close MCP client: {e}")
250
+
251
+ if os.path.exists(self.temp_dir):
252
+ try:
253
+ shutil.rmtree(self.temp_dir)
254
+ except Exception as e:
255
+ print(f"Warning: Failed to remove temp directory: {e}")
notebooks/1_test_pdf_reader.ipynb CHANGED
@@ -211,9 +211,150 @@
211
  "text": [
212
  "📂 Processing /Users/sawale/Documents/learning/money_rag/demo_data/Discover-AllAvailable-20260110.csv...\n",
213
  " ✨ Enriching descriptions (Async)...\n",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
214
  "✅ Ingested 124 rows from Discover-AllAvailable-20260110.csv. Logic: spending_is_positive\n",
215
  "📂 Processing /Users/sawale/Documents/learning/money_rag/demo_data/Chase5282_Activity20240110_20260110_20260111.CSV...\n",
216
  " ✨ Enriching descriptions (Async)...\n",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217
  "✅ Ingested 126 rows from Chase5282_Activity20240110_20260110_20260111.CSV. Logic: spending_is_negative\n"
218
  ]
219
  }
@@ -275,7 +416,7 @@
275
  " <tbody>\n",
276
  " <tr>\n",
277
  " <th>0</th>\n",
278
- " <td>5712be16-98a8-41d7-94de-15ecff7793da</td>\n",
279
  " <td>2024-10-17 00:00:00</td>\n",
280
  " <td>BACK MARKET BROOKLYN NY</td>\n",
281
  " <td>231.19</td>\n",
@@ -285,7 +426,7 @@
285
  " </tr>\n",
286
  " <tr>\n",
287
  " <th>1</th>\n",
288
- " <td>cea08bf8-440c-4d05-b06c-5c0d2e3b2997</td>\n",
289
  " <td>2024-10-18 00:00:00</td>\n",
290
  " <td>TEMU.COM 8884958368 DE</td>\n",
291
  " <td>16.51</td>\n",
@@ -295,27 +436,27 @@
295
  " </tr>\n",
296
  " <tr>\n",
297
  " <th>2</th>\n",
298
- " <td>b021b290-36fc-4667-993c-6f620da3a54a</td>\n",
299
  " <td>2024-10-18 00:00:00</td>\n",
300
  " <td>WALMART STORE 00332 HUNTSVILLE AL</td>\n",
301
  " <td>146.73</td>\n",
302
  " <td>Merchandise</td>\n",
303
  " <td>Discover-AllAvailable-20260110.csv</td>\n",
304
- " <td>Walmart Inc. is an American multinational reta...</td>\n",
305
  " </tr>\n",
306
  " <tr>\n",
307
  " <th>3</th>\n",
308
- " <td>d260bc87-ca63-4238-ad9e-3482273c49fb</td>\n",
309
  " <td>2024-10-18 00:00:00</td>\n",
310
  " <td>$100 STATEMENT CREDIT W 1ST PU</td>\n",
311
  " <td>-100.00</td>\n",
312
  " <td>Awards and Rebate Credits</td>\n",
313
  " <td>Discover-AllAvailable-20260110.csv</td>\n",
314
- " <td>All U.S. Bank credit cards offer contactless c...</td>\n",
315
  " </tr>\n",
316
  " <tr>\n",
317
  " <th>4</th>\n",
318
- " <td>2c06fe8e-8ef2-49f1-bed6-dd282effec85</td>\n",
319
  " <td>2024-11-02 00:00:00</td>\n",
320
  " <td>PY *KUNG-FU TEA AL HUNTSVILLE AL</td>\n",
321
  " <td>8.09</td>\n",
@@ -335,27 +476,27 @@
335
  " </tr>\n",
336
  " <tr>\n",
337
  " <th>245</th>\n",
338
- " <td>6a6167f7-dc54-480f-8a15-0561c7b877da</td>\n",
339
  " <td>2025-06-18 00:00:00</td>\n",
340
  " <td>PANDA EXPRESS #2005</td>\n",
341
  " <td>52.87</td>\n",
342
  " <td>Food &amp; Drink</td>\n",
343
  " <td>Chase5282_Activity20240110_20260110_20260111.CSV</td>\n",
344
- " <td>This is a list of notable current and former f...</td>\n",
345
  " </tr>\n",
346
  " <tr>\n",
347
  " <th>246</th>\n",
348
- " <td>2a01f41e-8f1e-4a10-9e7f-3ac29795607b</td>\n",
349
  " <td>2025-06-14 00:00:00</td>\n",
350
  " <td>Payment Thank You-Mobile</td>\n",
351
  " <td>-62.07</td>\n",
352
  " <td>None</td>\n",
353
  " <td>Chase5282_Activity20240110_20260110_20260111.CSV</td>\n",
354
- " <td>Locate a mobile phone | GSM locator of mobile ...</td>\n",
355
  " </tr>\n",
356
  " <tr>\n",
357
  " <th>247</th>\n",
358
- " <td>f7648015-85a6-4412-87d5-1499ac29fce6</td>\n",
359
  " <td>2025-06-12 00:00:00</td>\n",
360
  " <td>STARS AND STRIKES - HUNTS</td>\n",
361
  " <td>21.80</td>\n",
@@ -365,23 +506,23 @@
365
  " </tr>\n",
366
  " <tr>\n",
367
  " <th>248</th>\n",
368
- " <td>2edd49e5-9f4f-46d4-b94f-f9d7661bcdab</td>\n",
369
  " <td>2025-06-11 00:00:00</td>\n",
370
  " <td>WAL-MART #332</td>\n",
371
  " <td>4.47</td>\n",
372
  " <td>Groceries</td>\n",
373
  " <td>Chase5282_Activity20240110_20260110_20260111.CSV</td>\n",
374
- " <td>From toys and video games to fashionable cloth...</td>\n",
375
  " </tr>\n",
376
  " <tr>\n",
377
  " <th>249</th>\n",
378
- " <td>1d2ecebf-4994-4cdd-8d09-b6751655cd3f</td>\n",
379
  " <td>2025-06-11 00:00:00</td>\n",
380
  " <td>WAL-MART #332</td>\n",
381
  " <td>57.60</td>\n",
382
  " <td>Groceries</td>\n",
383
  " <td>Chase5282_Activity20240110_20260110_20260111.CSV</td>\n",
384
- " <td>From toys and video games to fashionable cloth...</td>\n",
385
  " </tr>\n",
386
  " </tbody>\n",
387
  "</table>\n",
@@ -390,17 +531,17 @@
390
  ],
391
  "text/plain": [
392
  " id transaction_date \\\n",
393
- "0 5712be16-98a8-41d7-94de-15ecff7793da 2024-10-17 00:00:00 \n",
394
- "1 cea08bf8-440c-4d05-b06c-5c0d2e3b2997 2024-10-18 00:00:00 \n",
395
- "2 b021b290-36fc-4667-993c-6f620da3a54a 2024-10-18 00:00:00 \n",
396
- "3 d260bc87-ca63-4238-ad9e-3482273c49fb 2024-10-18 00:00:00 \n",
397
- "4 2c06fe8e-8ef2-49f1-bed6-dd282effec85 2024-11-02 00:00:00 \n",
398
  ".. ... ... \n",
399
- "245 6a6167f7-dc54-480f-8a15-0561c7b877da 2025-06-18 00:00:00 \n",
400
- "246 2a01f41e-8f1e-4a10-9e7f-3ac29795607b 2025-06-14 00:00:00 \n",
401
- "247 f7648015-85a6-4412-87d5-1499ac29fce6 2025-06-12 00:00:00 \n",
402
- "248 2edd49e5-9f4f-46d4-b94f-f9d7661bcdab 2025-06-11 00:00:00 \n",
403
- "249 1d2ecebf-4994-4cdd-8d09-b6751655cd3f 2025-06-11 00:00:00 \n",
404
  "\n",
405
  " description amount category \\\n",
406
  "0 BACK MARKET BROOKLYN NY 231.19 Merchandise \n",
@@ -431,15 +572,15 @@
431
  " enriched_info \n",
432
  "0 Online Retailer in New York, NY . See BBB rati... \n",
433
  "1 Temu ' s business model has allowed it to beco... \n",
434
- "2 Walmart Inc. is an American multinational reta... \n",
435
- "3 All U.S. Bank credit cards offer contactless c... \n",
436
  "4 Jan 22, 2021 · Best part to me--besides the ro... \n",
437
  ".. ... \n",
438
- "245 This is a list of notable current and former f... \n",
439
- "246 Locate a mobile phone | GSM locator of mobile ... \n",
440
  "247 At our Huntsville , AL location , we pride our... \n",
441
- "248 From toys and video games to fashionable cloth... \n",
442
- "249 From toys and video games to fashionable cloth... \n",
443
  "\n",
444
  "[250 rows x 7 columns]"
445
  ]
@@ -646,9 +787,9 @@
646
  "name": "stdout",
647
  "output_type": "stream",
648
  "text": [
649
- "Match: CASHBACK BONUS REDEMPTION PYMT/STMT CRDT - What is this charge? Cashback bonus redemption pymt / stmt crdt . Cash - back from mogl 858-36958. His IP address, location , Internet provider, what browser he uses and operating system? You can find out all this using \"2IP spy\".It serves two main functions. It provides the network location of the host and identifies the host or network interface. What is the purpose of an IP address? Cashback bonus redemption pymt / stmt crdt .March is the month in which I had most number of transcations. I think this is because I visited the store next to me very frequently for small purchases. Cashback bonus redemption pymt / stmt crdt . Redemption Activity This Period is the total amount of Rewards you redeemed during the statement period and includes Miles partners, gift cards, account credits, electronic deposits and charitable donations. Cashback bonus redemption pymt / stmt crdt .Question2 : What was the frequency(number of occurences) of each category in terms of expenses made over the entire time period?. | Metadata: {'id': '96dca195-03e6-4a7f-8836-fc71659a5379', 'amount': -11.32, 'category': 'Awards and Rebate Credits', 'transaction_date': '2025-03-18 00:00:00', '_id': 'ed7d701418bc4c96b42143671dc16464', '_collection_name': 'transactions'}\n",
650
- "Match: CASHBACK BONUS REDEMPTION PYMT/STMT CRDT - What is this charge? Cashback bonus redemption pymt / stmt crdt . Cash - back from mogl 858-36958. His IP address, location , Internet provider, what browser he uses and operating system? You can find out all this using \"2IP spy\".It serves two main functions. It provides the network location of the host and identifies the host or network interface. What is the purpose of an IP address? Cashback bonus redemption pymt / stmt crdt .March is the month in which I had most number of transcations. I think this is because I visited the store next to me very frequently for small purchases. Cashback bonus redemption pymt / stmt crdt . Redemption Activity This Period is the total amount of Rewards you redeemed during the statement period and includes Miles partners, gift cards, account credits, electronic deposits and charitable donations. Cashback bonus redemption pymt / stmt crdt .Question2 : What was the frequency(number of occurences) of each category in terms of expenses made over the entire time period?. | Metadata: {'id': '70d72fc3-f61f-4a26-982f-0a71a1c48e30', 'amount': -9.0, 'category': 'Awards and Rebate Credits', 'transaction_date': '2025-05-15 00:00:00', '_id': 'e90a36aa56ed4b50a496a0b1d468d4e6', '_collection_name': 'transactions'}\n",
651
- "Match: CASHBACK BONUS REDEMPTION PYMT/STMT CRDT - What is this charge? Cashback bonus redemption pymt / stmt crdt . Cash - back from mogl 858-36958. His IP address, location , Internet provider, what browser he uses and operating system? You can find out all this using \"2IP spy\".It serves two main functions. It provides the network location of the host and identifies the host or network interface. What is the purpose of an IP address? Cashback bonus redemption pymt / stmt crdt .March is the month in which I had most number of transcations. I think this is because I visited the store next to me very frequently for small purchases. Cashback bonus redemption pymt / stmt crdt . Redemption Activity This Period is the total amount of Rewards you redeemed during the statement period and includes Miles partners, gift cards, account credits, electronic deposits and charitable donations. Cashback bonus redemption pymt / stmt crdt .Question2 : What was the frequency(number of occurences) of each category in terms of expenses made over the entire time period?. | Metadata: {'id': 'a4803064-dde5-48a5-be3b-34b17cbb0fbc', 'amount': -2.55, 'category': 'Awards and Rebate Credits', 'transaction_date': '2025-11-06 00:00:00', '_id': 'a10a1f901da54e0599b3578e66ff3fcb', '_collection_name': 'transactions'}\n"
652
  ]
653
  }
654
  ],
@@ -675,22 +816,35 @@
675
  "text": [
676
  "================================\u001b[1m Human Message \u001b[0m=================================\n",
677
  "\n",
678
- "is there anything i need to be worried about in my spending over the last 2 months?\n",
679
  "==================================\u001b[1m Ai Message \u001b[0m==================================\n",
 
 
 
 
 
 
 
 
680
  "\n",
681
- "I can't tell you if there's anything to \"worry about\" as that's a subjective judgment. However, I can help you analyze your spending in various ways. For example, I can:\n",
682
- "\n",
683
- "* Show you your total spending over the last two months.\n",
684
- "* Break down your spending by category or merchant.\n",
685
- "* Identify your largest transactions.\n",
686
- "* Find transactions related to specific keywords (e.g., \"fast food,\" \"online shopping\").\n",
 
 
 
 
 
687
  "\n",
688
- "What kind of spending insights would be most helpful for you?\n"
689
  ]
690
  }
691
  ],
692
  "source": [
693
- "question = \"is there anything i need to be worried about in my spending over the last 2 months?\"\n",
694
  "steps = []\n",
695
  "\n",
696
  "for step in agent.stream(\n",
 
211
  "text": [
212
  "📂 Processing /Users/sawale/Documents/learning/money_rag/demo_data/Discover-AllAvailable-20260110.csv...\n",
213
  " ✨ Enriching descriptions (Async)...\n",
214
+ " 🔍 Web searching for: BACK MARKET BROOKLYN NY...\n",
215
+ " 🔍 Web searching for: TEMU.COM 8884958368 DE...\n",
216
+ " 🔍 Web searching for: WALMART STORE 00332 HUNTSVILLE AL...\n",
217
+ " 🔍 Web searching for: $100 STATEMENT CREDIT W 1ST PU...\n",
218
+ " 🔍 Web searching for: PY *KUNG-FU TEA AL HUNTSVILLE AL...\n",
219
+ " 🔍 Web searching for: MADISON MONTGOMERY AL...\n",
220
+ " 🔍 Web searching for: INTERNET PAYMENT - THANK YOU...\n",
221
+ " 🔍 Web searching for: GRUBHUB - UNIVERSITY OF HUNTSVILLE AL...\n",
222
+ " 🔍 Web searching for: MINT MOBILE 800-683-7392 CA...\n",
223
+ " 🔍 Web searching for: POPEYES 2577 HUNTSVILLE AL...\n",
224
+ " 🔍 Web searching for: 88 BUFFET HUNTSVILLE AL...\n",
225
+ " 🔍 Web searching for: VIET HUONG VIETNAMESE RE HUNTSVILLE AL...\n",
226
+ " 🔍 Web searching for: CASHBACK BONUS REDEMPTION PYMT/STMT CRDT...\n",
227
+ " 🔍 Web searching for: SPO*THECURRYMODERNINDIAN HUNTSVILLE AL...\n",
228
+ " 🔍 Web searching for: H&M 0273HUNTSVILLE HUNTSVILLE ALUS0273001241222182740...\n",
229
+ " 🔍 Web searching for: INDIAN BAZAAR HUNTSVILLE AL...\n",
230
+ " 🔍 Web searching for: HANDELS HOMEMADE HUNTSVI HUNTSVILLE AL...\n",
231
+ " 🔍 Web searching for: UAH COLLEGE 256-824-6170 AL...\n",
232
+ " 🔍 Web searching for: UAH COLLEGE FSF 800-346-9252 MA...\n",
233
+ " 🔍 Web searching for: CHIPOTLE 1687 NASHVILLE TN...\n",
234
+ " 🔍 Web searching for: TST*PIE TOWN TACOS - F NASHVILLE TN00153526022200965677AA...\n",
235
+ " 🔍 Web searching for: INDIAN BAZAAR HUNTSVILLE ALGOOGLE PAY ENDING IN 8984...\n",
236
+ " 🔍 Web searching for: INDIA MART HUNTSVILLE ALGOOGLE PAY ENDING IN 8984...\n",
237
+ " 🔍 Web searching for: PAYPAL *KEVDUDE1186 KEV 888-221-1161 CA...\n",
238
+ " 🔍 Web searching for: LYFT *RIDE WED 10AM 8552800278 CA...\n",
239
+ " 🔍 Web searching for: SKECHERS USA INC 1069 HUNTSVILLE AL...\n",
240
+ " 🔍 Web searching for: STORE HUNTSVILLE AL...\n",
241
+ " 🔍 Web searching for: LYFT *RIDE WED 3PM 8552800278 CA...\n",
242
+ " 🔍 Web searching for: SQ *TAQUERIA LAS ADELI HUNTSVILLE AL0002305843021411201895...\n",
243
+ " 🔍 Web searching for: UAH HUNTSVILLE DUNKIN HUNTSVILLE AL...\n",
244
+ " 🔍 Web searching for: WALMART.COM 800-925-6278 AR...\n",
245
+ " 🔍 Web searching for: WALMART.COM 8009256278 BENTONVILLE AR...\n",
246
+ " 🔍 Web searching for: TOUS LES JOURS - HUNTSVI HUNTSVILLE AL...\n",
247
+ " 🔍 Web searching for: MARSHALLS #422 HUNTSVILLE AL...\n",
248
+ " 🔍 Web searching for: ROSS STORE #2436 HUNTSVILLE AL...\n",
249
+ " 🔍 Web searching for: SPRINTAX NR TAX 8882038900 NY...\n",
250
+ " 🔍 Web searching for: USPS PO 0142460804 HUNTSVILLE AL...\n",
251
+ " 🔍 Web searching for: CHIPOTLE 1796 HUNTSVILLE ALGOOGLE PAY ENDING IN 8984...\n",
252
+ " 🔍 Web searching for: TST*POURHOUSE HUNTSVILLE AL00031984024314246667AA...\n",
253
+ " 🔍 Web searching for: TST*WOKS UP HUNTSVILLE AL00075396024313993332AA...\n",
254
+ " 🔍 Web searching for: SPIRIT AIRLINES 8014012222 FL...\n",
255
+ " 🔍 Web searching for: CHIPOTLE 1796 HUNTSVILLE AL...\n",
256
+ " 🔍 Web searching for: UAH BURSARS OFFICE HUNTSVILLE AL...\n",
257
+ " 🔍 Web searching for: STARS AND STRIKES - HUNT HUNTSVILLE AL...\n",
258
+ " 🔍 Web searching for: ROSS STORES #620 HUNTSVILLE AL...\n",
259
+ " 🔍 Web searching for: TST*KAMADO RAMEN - MID HUNTSVILLE AL00006963025030352515AA...\n",
260
+ " 🔍 Web searching for: SQ *MOM'SCLAYCO HARVEST AL0002305843022068424398...\n",
261
+ " 🔍 Web searching for: DOLLARTREE HUNTSVILLE AL...\n",
262
+ " 🔍 Web searching for: SLIM & HUSKIES NASHVILLE TN...\n",
263
+ " 🔍 Web searching for: CHIPOTLE 1392 SANTA MONICA CA...\n",
264
+ " 🔍 Web searching for: DOLLAR TREE LAS VEGAS NV...\n",
265
+ " 🔍 Web searching for: LYFT *RIDE TUE 12AM 8552800278 CA...\n",
266
+ " 🔍 Web searching for: SQ *SHIKU GCM LOS ANGELES CA0001152921515467218869...\n",
267
+ " 🔍 Web searching for: SQ *SHIKU GCM LOS ANGELES CA0001152921515467211997...\n",
268
+ " 🔍 Web searching for: WALMART STORE 05686 BURBANK CA...\n",
269
+ " 🔍 Web searching for: CAFE BELLA NEWPORT SAN DIEGO CAGOOGLE PAY ENDING IN 8984...\n",
270
+ " 🔍 Web searching for: CHIPOTLE 2883 NORTH LAS VEGNVGOOGLE PAY ENDING IN 8984...\n",
271
+ " 🔍 Web searching for: SHELL10006319007 HESPERIA CAGOOGLE PAY ENDING IN 8984...\n",
272
+ " 🔍 Web searching for: PANDA EXPRESS #1964 LAS VEGAS NV...\n",
273
+ " 🔍 Web searching for: DENNY'S #0141 QR LAS VEGAS NVGOOGLE PAY ENDING IN 8984...\n",
274
+ " 🔍 Web searching for: LAS VEGAS SOUVENIRS AND LAS VEGAS NV...\n",
275
+ " 🔍 Web searching for: CTLP*FIRST CLASS VENDI BELLGARDENS CA...\n",
276
+ " 🔍 Web searching for: SHELL12874333011 FRANKLIN TN...\n",
277
+ " 🔍 Web searching for: AMARAVATI INDIAN CUISINE BRENTWOOD TNGOOGLE PAY ENDING IN 8984...\n",
278
+ " 🔍 Web searching for: CENTRAL MARKET NASHVILLE TN...\n",
279
+ " 🔍 Web searching for: TST*PRINCES HOT CHICKE NASHVILLE TN00104605025320544723AA...\n",
280
+ " 🔍 Web searching for: TST*PRINCES HOT CHICKE NASHVILLE TN00104605025321087148AA...\n",
281
+ " 🔍 Web searching for: WALMART STORE 05616 NASHVILLE TN...\n",
282
+ " 🔍 Web searching for: PY *KUNG-FU TEA AL HUNTSVILLE ALGOOGLE PAY ENDING IN 8984...\n",
283
+ " 🔍 Web searching for: 2LEVY R&C CHATTANOOGA TNGOOGLE PAY ENDING IN 8984...\n",
284
  "✅ Ingested 124 rows from Discover-AllAvailable-20260110.csv. Logic: spending_is_positive\n",
285
  "📂 Processing /Users/sawale/Documents/learning/money_rag/demo_data/Chase5282_Activity20240110_20260110_20260111.CSV...\n",
286
  " ✨ Enriching descriptions (Async)...\n",
287
+ " 🔍 Web searching for: TOUS LES JOURS - HUNTSVIL...\n",
288
+ " 🔍 Web searching for: Payment Thank You-Mobile...\n",
289
+ " 🔍 Web searching for: INDIAN BAZAAR...\n",
290
+ " 🔍 Web searching for: TST*BLUE OAK BBQ-HUNTSVI...\n",
291
+ " 🔍 Web searching for: AMC 4112 VAL BEND 18...\n",
292
+ " 🔍 Web searching for: HANDELS HOMEMADE JONES V...\n",
293
+ " 🔍 Web searching for: PAYYOURSELFBACK CREDIT...\n",
294
+ " 🔍 Web searching for: TST* HYDERABAD HOUSE...\n",
295
+ " 🔍 Web searching for: PATEL BROTHERS NASHVILLE...\n",
296
+ " 🔍 Web searching for: CITY OF HUNTSVILLE...\n",
297
+ " 🔍 Web searching for: WM SUPERCENTER #332...\n",
298
+ " 🔍 Web searching for: WAL-MART #0332...\n",
299
+ " 🔍 Web searching for: AMAZON MKTPL*OS1RI3LN3...\n",
300
+ " 🔍 Web searching for: TST* HATTIE B'S HUNTSVILL...\n",
301
+ " 🔍 Web searching for: AMAZON MKTPL*BI23Z6JR0...\n",
302
+ " 🔍 Web searching for: AMAZON MKTPL*BI9IW9OS2...\n",
303
+ " 🔍 Web searching for: AMAZON MKTPL*BI0296OJ2...\n",
304
+ " 🔍 Web searching for: AMAZON MKTPL*BB71A2881...\n",
305
+ " 🔍 Web searching for: AMAZON MKTPL*BB3FU2UQ2...\n",
306
+ " 🔍 Web searching for: AMAZON MKTPL*BI03P1OX2...\n",
307
+ " 🔍 Web searching for: AMAZON MKTPL*BB92U9QK2...\n",
308
+ " 🔍 Web searching for: AMAZON MKTPL*BB9TA14Q0...\n",
309
+ " 🔍 Web searching for: 88 BUFFET...\n",
310
+ " 🔍 Web searching for: AMAZON MKTPL*BB0DC71B1...\n",
311
+ " 🔍 Web searching for: AMAZON MKTPL*B20NN4ID0...\n",
312
+ " 🔍 Web searching for: AMAZON MKTPL*B273C1WY2...\n",
313
+ " 🔍 Web searching for: AMAZON MKTPL*B27IN41E1...\n",
314
+ " 🔍 Web searching for: AMAZON MKTPL*B250Z60P1...\n",
315
+ " 🔍 Web searching for: BEST BUY 00005140...\n",
316
+ " 🔍 Web searching for: DAVES HOT CHICKEN 1282...\n",
317
+ " 🔍 Web searching for: SQ *VIETCUISINE LLC...\n",
318
+ " 🔍 Web searching for: CHICK-FIL-A #00579...\n",
319
+ " 🔍 Web searching for: COSTCO WHSE #0356...\n",
320
+ " 🔍 Web searching for: AMAZON MKTPL*NK4AM43Q2...\n",
321
+ " 🔍 Web searching for: HUNTSVILLE FLV...\n",
322
+ " 🔍 Web searching for: AMAZON MKTPL*NM1H055K0...\n",
323
+ " 🔍 Web searching for: MAPCO EXPRESS #3403...\n",
324
+ " 🔍 Web searching for: DUNKIN #346212 Q35...\n",
325
+ " 🔍 Web searching for: CENTRAL MARKET...\n",
326
+ " 🔍 Web searching for: TARA INTERNATIONAL MARKET...\n",
327
+ " 🔍 Web searching for: BOTAN MARKET INC...\n",
328
+ " 🔍 Web searching for: AMARAVATI INDIAN CUISINE...\n",
329
+ " 🔍 Web searching for: GRUBHUB - UNIVERSITY OF A...\n",
330
+ " 🔍 Web searching for: BURGER KING #4959...\n",
331
+ " 🔍 Web searching for: PANDA EXPRESS #3013...\n",
332
+ " 🔍 Web searching for: MCDONALD'S F2431...\n",
333
+ " 🔍 Web searching for: ENDZONE COLLECTIBLES...\n",
334
+ " 🔍 Web searching for: ZIMMAD EVE* ZIMMAD JOI...\n",
335
+ " 🔍 Web searching for: SQ *SPILL COFFEE AND CREA...\n",
336
+ " 🔍 Web searching for: 10267 CAVA WHITESBURG...\n",
337
+ " 🔍 Web searching for: SPO*DRAGONSFORGECAFE...\n",
338
+ " 🔍 Web searching for: UAH BURSARS OFFICE...\n",
339
+ " 🔍 Web searching for: MARATHON PETRO42804...\n",
340
+ " 🔍 Web searching for: TST*NOTHING BUT NOODLES...\n",
341
+ " 🔍 Web searching for: VEDA INDIAN CUISINE...\n",
342
+ " 🔍 Web searching for: DOLLARTREE...\n",
343
+ " 🔍 Web searching for: TARGET 00013466...\n",
344
+ " 🔍 Web searching for: POPEYES 2577...\n",
345
+ " 🔍 Web searching for: DEORALI GROCERY...\n",
346
+ " 🔍 Web searching for: HELLO ATLANTA #33...\n",
347
+ " 🔍 Web searching for: SKY VIEW ATLANTA...\n",
348
+ " 🔍 Web searching for: STARBUCKS 25111...\n",
349
+ " 🔍 Web searching for: BP#8998205AM/PM WADE GRE...\n",
350
+ " 🔍 Web searching for: Waffle House 0857...\n",
351
+ " 🔍 Web searching for: CINEMARK 1131 BOXCON...\n",
352
+ " 🔍 Web searching for: CINEMARK 1131 RSTBAR...\n",
353
+ " 🔍 Web searching for: HOMEGOODS # 0568...\n",
354
+ " 🔍 Web searching for: ASIAN MARKET...\n",
355
+ " 🔍 Web searching for: PANDA EXPRESS #2005...\n",
356
+ " 🔍 Web searching for: STARS AND STRIKES - HUNTS...\n",
357
+ " 🔍 Web searching for: WAL-MART #332...\n",
358
  "✅ Ingested 126 rows from Chase5282_Activity20240110_20260110_20260111.CSV. Logic: spending_is_negative\n"
359
  ]
360
  }
 
416
  " <tbody>\n",
417
  " <tr>\n",
418
  " <th>0</th>\n",
419
+ " <td>cf2f48c5-34ab-4544-b1f4-542681fd5017</td>\n",
420
  " <td>2024-10-17 00:00:00</td>\n",
421
  " <td>BACK MARKET BROOKLYN NY</td>\n",
422
  " <td>231.19</td>\n",
 
426
  " </tr>\n",
427
  " <tr>\n",
428
  " <th>1</th>\n",
429
+ " <td>16913dce-52bf-43f4-853d-7bb55e09aac5</td>\n",
430
  " <td>2024-10-18 00:00:00</td>\n",
431
  " <td>TEMU.COM 8884958368 DE</td>\n",
432
  " <td>16.51</td>\n",
 
436
  " </tr>\n",
437
  " <tr>\n",
438
  " <th>2</th>\n",
439
+ " <td>5917cb10-f0e6-49fa-9987-776cee28688c</td>\n",
440
  " <td>2024-10-18 00:00:00</td>\n",
441
  " <td>WALMART STORE 00332 HUNTSVILLE AL</td>\n",
442
  " <td>146.73</td>\n",
443
  " <td>Merchandise</td>\n",
444
  " <td>Discover-AllAvailable-20260110.csv</td>\n",
445
+ " <td>Posts Walmart Huntsville - University Drive De...</td>\n",
446
  " </tr>\n",
447
  " <tr>\n",
448
  " <th>3</th>\n",
449
+ " <td>bd66a49e-5064-43ca-bdb2-94947297b6d5</td>\n",
450
  " <td>2024-10-18 00:00:00</td>\n",
451
  " <td>$100 STATEMENT CREDIT W 1ST PU</td>\n",
452
  " <td>-100.00</td>\n",
453
  " <td>Awards and Rebate Credits</td>\n",
454
  " <td>Discover-AllAvailable-20260110.csv</td>\n",
455
+ " <td>That said, I woke up yesterday and saw a $ 100...</td>\n",
456
  " </tr>\n",
457
  " <tr>\n",
458
  " <th>4</th>\n",
459
+ " <td>8b9b16d4-dd81-4ebe-820f-62fdc827a0bb</td>\n",
460
  " <td>2024-11-02 00:00:00</td>\n",
461
  " <td>PY *KUNG-FU TEA AL HUNTSVILLE AL</td>\n",
462
  " <td>8.09</td>\n",
 
476
  " </tr>\n",
477
  " <tr>\n",
478
  " <th>245</th>\n",
479
+ " <td>239f983e-2ed8-4454-90ad-0e8477bf7893</td>\n",
480
  " <td>2025-06-18 00:00:00</td>\n",
481
  " <td>PANDA EXPRESS #2005</td>\n",
482
  " <td>52.87</td>\n",
483
  " <td>Food &amp; Drink</td>\n",
484
  " <td>Chase5282_Activity20240110_20260110_20260111.CSV</td>\n",
485
+ " <td>Aug 29, 2025 · The group's headquarters is loc...</td>\n",
486
  " </tr>\n",
487
  " <tr>\n",
488
  " <th>246</th>\n",
489
+ " <td>0ecba974-5491-4ef2-ba52-bf3c37d6e854</td>\n",
490
  " <td>2025-06-14 00:00:00</td>\n",
491
  " <td>Payment Thank You-Mobile</td>\n",
492
  " <td>-62.07</td>\n",
493
  " <td>None</td>\n",
494
  " <td>Chase5282_Activity20240110_20260110_20260111.CSV</td>\n",
495
+ " <td>Sep 25, 2025 · Thank You Mobile is not a compa...</td>\n",
496
  " </tr>\n",
497
  " <tr>\n",
498
  " <th>247</th>\n",
499
+ " <td>fb966472-d77a-4723-a9e6-15e63bda4cd2</td>\n",
500
  " <td>2025-06-12 00:00:00</td>\n",
501
  " <td>STARS AND STRIKES - HUNTS</td>\n",
502
  " <td>21.80</td>\n",
 
506
  " </tr>\n",
507
  " <tr>\n",
508
  " <th>248</th>\n",
509
+ " <td>b6bc2e1d-d68b-4acd-a201-46d8cf5175e5</td>\n",
510
  " <td>2025-06-11 00:00:00</td>\n",
511
  " <td>WAL-MART #332</td>\n",
512
  " <td>4.47</td>\n",
513
  " <td>Groceries</td>\n",
514
  " <td>Chase5282_Activity20240110_20260110_20260111.CSV</td>\n",
515
+ " <td>3 days ago · Walmart Inc. is an American multi...</td>\n",
516
  " </tr>\n",
517
  " <tr>\n",
518
  " <th>249</th>\n",
519
+ " <td>e896adcc-5445-4626-b14c-09ebd5c9f658</td>\n",
520
  " <td>2025-06-11 00:00:00</td>\n",
521
  " <td>WAL-MART #332</td>\n",
522
  " <td>57.60</td>\n",
523
  " <td>Groceries</td>\n",
524
  " <td>Chase5282_Activity20240110_20260110_20260111.CSV</td>\n",
525
+ " <td>3 days ago · Walmart Inc. is an American multi...</td>\n",
526
  " </tr>\n",
527
  " </tbody>\n",
528
  "</table>\n",
 
531
  ],
532
  "text/plain": [
533
  " id transaction_date \\\n",
534
+ "0 cf2f48c5-34ab-4544-b1f4-542681fd5017 2024-10-17 00:00:00 \n",
535
+ "1 16913dce-52bf-43f4-853d-7bb55e09aac5 2024-10-18 00:00:00 \n",
536
+ "2 5917cb10-f0e6-49fa-9987-776cee28688c 2024-10-18 00:00:00 \n",
537
+ "3 bd66a49e-5064-43ca-bdb2-94947297b6d5 2024-10-18 00:00:00 \n",
538
+ "4 8b9b16d4-dd81-4ebe-820f-62fdc827a0bb 2024-11-02 00:00:00 \n",
539
  ".. ... ... \n",
540
+ "245 239f983e-2ed8-4454-90ad-0e8477bf7893 2025-06-18 00:00:00 \n",
541
+ "246 0ecba974-5491-4ef2-ba52-bf3c37d6e854 2025-06-14 00:00:00 \n",
542
+ "247 fb966472-d77a-4723-a9e6-15e63bda4cd2 2025-06-12 00:00:00 \n",
543
+ "248 b6bc2e1d-d68b-4acd-a201-46d8cf5175e5 2025-06-11 00:00:00 \n",
544
+ "249 e896adcc-5445-4626-b14c-09ebd5c9f658 2025-06-11 00:00:00 \n",
545
  "\n",
546
  " description amount category \\\n",
547
  "0 BACK MARKET BROOKLYN NY 231.19 Merchandise \n",
 
572
  " enriched_info \n",
573
  "0 Online Retailer in New York, NY . See BBB rati... \n",
574
  "1 Temu ' s business model has allowed it to beco... \n",
575
+ "2 Posts Walmart Huntsville - University Drive De... \n",
576
+ "3 That said, I woke up yesterday and saw a $ 100... \n",
577
  "4 Jan 22, 2021 · Best part to me--besides the ro... \n",
578
  ".. ... \n",
579
+ "245 Aug 29, 2025 · The group's headquarters is loc... \n",
580
+ "246 Sep 25, 2025 · Thank You Mobile is not a compa... \n",
581
  "247 At our Huntsville , AL location , we pride our... \n",
582
+ "248 3 days ago · Walmart Inc. is an American multi... \n",
583
+ "249 3 days ago · Walmart Inc. is an American multi... \n",
584
  "\n",
585
  "[250 rows x 7 columns]"
586
  ]
 
787
  "name": "stdout",
788
  "output_type": "stream",
789
  "text": [
790
+ "Match: TST*WOKS UP HUNTSVILLE AL00075396024313993332AA - Take a look at these nine new businesses that have just opened or announced an opening here in the Rocket City. Check Dress Up - Huntsville in Huntsville , AL, 920 Bob Wallace Ave SW #317 on Cylex and find ☎ (256) 585-2..., contact info, opening hours. We're posted at the WeUp location for just a couple more hours —so if you're hungry, now's the time to pull up ! We've had some amazing folks swing through today, including the owner of Ms. Juju's Kitchen and one of your favorite local barbers Mike —and YES, they're repeat customers because the food speaks for itself! Detailed info and reviews on 27 top companies and startups in Huntsville in 2026. Get the latest updates on their products, jobs, funding, investors, founders and more. Check Your Statement: Look for entries starting with \"TST\" on your debit card statement. Note the date, amount, and any additional details like a business name or code. Match with Receipts: Compare the charge to recent purchases, especially at restaurants, cafes, or bars. The amount should match your receipt or include a tip. | Metadata: {'id': '737481c4-fc9c-48a5-8cd9-9f2a02844c12', 'amount': 15.21, 'category': 'Restaurants', 'transaction_date': '2025-04-14 00:00:00', '_id': 'd461cada0bc542e6803cd9d14460ad05', '_collection_name': 'transactions'}\n",
791
+ "Match: TST*KAMADO RAMEN - MID HUNTSVILLE AL00006963025030352515AA - Kamado Ramen in Huntsville rated 4.7 out of 5 on Restaurant Guru: 896 reviews by visitors, 205 photos & 5 videos. Explore menu, check opening hours and order delivery Kamado Ramen : Spicy Miso Ramen 1022 Mid City Drive Huntsville , AL & 3414 Governors Dr. Huntsville , AL ( Mid City location and Stovehouse Food Garden Location ) Ramen is a hearty soup with quick-cooking noodles, often loaded with vegetables, meat, and egg. These two locations vary but carry similar items. Get address, phone number, hours, reviews, photos and more for Kamado Ramen Midcity | 1022 MidCity Drive, Huntsville , AL 35806, USA on usarestaurants.info Check Your Statement: Look for entries starting with \"TST\" on your debit card statement. Note the date, amount, and any additional details like a business name or code. Match with Receipts: Compare the charge to recent purchases, especially at restaurants, cafes, or bars. The amount should match your receipt or include a tip. Kamado Ramen at MidCity 1022 Mid City Drive, Huntsville , AL 35806 About Discussion 4 went 35 interested 3 shares | Metadata: {'id': 'cb6d01a0-0bab-4617-aba9-7e587b3ea32d', 'amount': 16.29, 'category': 'Restaurants', 'transaction_date': '2025-05-16 00:00:00', '_id': '9dc318e6b9e04a2f91e1a85ffbb375b8', '_collection_name': 'transactions'}\n",
792
+ "Match: AMAZON MKTPL*B27IN41E1 - In these cases, Amazon charges your payment method when each part of the order is shipped. This is why you have separate charges on your statement. Access Your Transactions to match the charge amounts and dates on your statement with the associated order number. Amazon is one of the world's most valuable brands and is one of the big five American information technology companies, along with Alphabet, Apple, Meta, and Microsoft. Some items Amazon sells include Show some love to small businesses . Donate to Kiva.org today to provide loans to local entrepreneurs and the Tripadvisor Foundation will match it, up to $150,000 USD collectively. Terms apply. Amazon mktpl ZG27L7451. General operating fund. Buildings and grounds.The UPS store 5242. General operating fund. Police department. Политика обработки персональных данных Согласие на обработку персональных данных Агентский Договор Все бренды. Мобильное приложение. Скачать в App Store Скачать в Google Play. | Metadata: {'id': 'ea13dad8-5978-442b-b4e4-7b22c226d72f', 'amount': 86.38, 'category': 'Shopping', 'transaction_date': '2025-11-24 00:00:00', '_id': '88754c75d8154f9e9912cf46cc51ade3', '_collection_name': 'transactions'}\n"
793
  ]
794
  }
795
  ],
 
816
  "text": [
817
  "================================\u001b[1m Human Message \u001b[0m=================================\n",
818
  "\n",
819
+ "ow much did i spend in haircuts\n",
820
  "==================================\u001b[1m Ai Message \u001b[0m==================================\n",
821
+ "Tool Calls:\n",
822
+ " semantic_search (f8fc4ebf-658f-4c58-a163-6bc4308ae46a)\n",
823
+ " Call ID: f8fc4ebf-658f-4c58-a163-6bc4308ae46a\n",
824
+ " Args:\n",
825
+ " topk: 10.0\n",
826
+ " query: haircuts\n",
827
+ "=================================\u001b[1m Tool Message \u001b[0m=================================\n",
828
+ "Name: semantic_search\n",
829
  "\n",
830
+ "Result: TST*WOKS UP HUNTSVILLE AL00075396024313993332AA - Take a look at these nine new businesses that have just opened or announced an opening here in the Rocket City. Check Dress Up - Huntsville in Huntsville , AL, 920 Bob Wallace Ave SW #317 on Cylex and find ☎ (256) 585-2..., contact info, ⌚ opening hours. We're posted at the WeUp location for just a couple more hours —so if you're hungry, now's the time to pull up ! We've had some amazing folks swing through today, including the owner of Ms. Juju's Kitchen and one of your favorite local barbers Mike —and YES, they're repeat customers because the food speaks for itself! Detailed info and reviews on 27 top companies and startups in Huntsville in 2026. Get the latest updates on their products, jobs, funding, investors, founders and more. Check Your Statement: Look for entries starting with \"TST\" on your debit card statement. Note the date, amount, and any additional details like a business name or code. Match with Receipts: Compare the charge to recent purchases, especially at restaurants, cafes, or bars. The amount should match your receipt or include a tip. | Metadata: {'id': '737481c4-fc9c-48a5-8cd9-9f2a02844c12', 'amount': 15.21, 'category': 'Restaurants', 'transaction_date': '2025-04-14 00:00:00', '_id': 'd461cada0bc542e6803cd9d14460ad05', '_collection_name': 'transactions'}\n",
831
+ "Result: BEST BUY 00005140 - Visit your local Best Buy at 20290 Katy Fwy in Katy, TX for electronics, computers, appliances, cell phones, video games & more new tech. In- store pickup & free shipping. Learn about the \" Best Buy 00005140 Huntsville Al\" charge and why it appears on your credit card statement. First seen on March 20, 2023, Last updated on March 20, 2023. What is it?Also Appears on Statements As. Chkcardbest buy 00005140 huntsville al. Is it time you ditched store - bought bread and started making your own, being in total control of the ingredients and your health? You might just do that when you learn about the differences between homemade bread vs. store - bought bread. Best Buy Goes Out Of Business ?? Why Best Buy Is Tanking Hard - YouTube. Best Buy has closed 18 stores , but physical locations still key to strategy. Typically during the weekdays, AT&T store hours are from 9 AM to 9 PM on Monday through Friday. The weekend begins in a similar fashion, and the AT&T store will open at 9 AM and close at 9 PM as well for most locations . | Metadata: {'id': '112c618f-6a83-4bfd-bb37-1193a2632a80', 'amount': 816.42, 'category': 'Shopping', 'transaction_date': '2025-11-22 00:00:00', '_id': '2e1ced908f6e44e3936e32cb8352e625', '_collection_name': 'transactions'}\n",
832
+ "Result: SLIM & HUSKIES NASHVILLE TN - Slim & Husky ’s has quickly become one of Nashville ’s fastest-growing businesses , and their mission to support the Nashville community is very ... While this isn ’ t their only location around the city, Emmy Squared: The Gulch is located in the heart of Nashville . ... of experience in WordPress development , we deliver powerful, scalable WordPress development in Nashville , TN —delivering custom development and ... Whether your business is based in Nashville , or you want to give a national feel, our comfortable and spacious meeting room will provide a creative ... ... Reviews: Reviews ordered by recency and descriptiveness of user-identified themes such as wait time, length of visit, general tips, and location ... | Metadata: {'id': '536147de-9359-4206-84b5-08e316fbd784', 'amount': 16.9, 'category': 'Restaurants', 'transaction_date': '2025-05-19 00:00:00', '_id': '6f3179b1f3364948a07bd5188e95b836', '_collection_name': 'transactions'}\n",
833
+ "Result: HUNTSVILLE FLV - Huntsville FLV is a local establishment in Huntsville, AL that offers a variety of services to its customers. Specializing in providing solutions for everyday needs, Huntsville FLV aims to cater to the diverse needs of the community. Now that we've got the long-awaited Trader Joe's, Dave & Busters, Top Golf, and Cheesecake Factory in town, what is the next business you'd like to see come to Hsv? Dec 16, 2024 · Take a look at these three new businesses that have opened or are about to open here in the Huntsville area. With four unique services— Huntsville International Airport, Rail and Air Cargo, Space Port, and Jetplex Industrial Park—we deliver opportunities for businesses and travelers. Whether by land, air, or space, we link people to places and products to markets. Jan 3, 2024 · Find the best Retail Stores in Huntsville , AL. Search Huntsville , AL Retail Stores to find the top rated Retail Stores . | Metadata: {'id': 'f6171537-bbe6-4c47-9b75-81b443e2d3ad', 'amount': 3.25, 'category': 'Food & Drink', 'transaction_date': '2025-10-25 00:00:00', '_id': 'f65cd50fdc7d4d7f8d5ad2ff4e307a78', '_collection_name': 'transactions'}\n",
834
+ "Result: HUNTSVILLE FLV - Huntsville FLV is a local establishment in Huntsville, AL that offers a variety of services to its customers. Specializing in providing solutions for everyday needs, Huntsville FLV aims to cater to the diverse needs of the community. Now that we've got the long-awaited Trader Joe's, Dave & Busters, Top Golf, and Cheesecake Factory in town, what is the next business you'd like to see come to Hsv? Dec 16, 2024 · Take a look at these three new businesses that have opened or are about to open here in the Huntsville area. With four unique services— Huntsville International Airport, Rail and Air Cargo, Space Port, and Jetplex Industrial Park—we deliver opportunities for businesses and travelers. Whether by land, air, or space, we link people to places and products to markets. Jan 3, 2024 · Find the best Retail Stores in Huntsville , AL. Search Huntsville , AL Retail Stores to find the top rated Retail Stores . | Metadata: {'id': '5aad4b5a-848f-4539-9d3a-54dfce7f3ed9', 'amount': 3.25, 'category': 'Food & Drink', 'transaction_date': '2025-10-30 00:00:00', '_id': 'ed5ee1ae725b452983b42bda99cd129b', '_collection_name': 'transactions'}\n",
835
+ "Result: HUNTSVILLE FLV - Huntsville FLV is a local establishment in Huntsville, AL that offers a variety of services to its customers. Specializing in providing solutions for everyday needs, Huntsville FLV aims to cater to the diverse needs of the community. Now that we've got the long-awaited Trader Joe's, Dave & Busters, Top Golf, and Cheesecake Factory in town, what is the next business you'd like to see come to Hsv? Dec 16, 2024 · Take a look at these three new businesses that have opened or are about to open here in the Huntsville area. With four unique services— Huntsville International Airport, Rail and Air Cargo, Space Port, and Jetplex Industrial Park—we deliver opportunities for businesses and travelers. Whether by land, air, or space, we link people to places and products to markets. Jan 3, 2024 · Find the best Retail Stores in Huntsville , AL. Search Huntsville , AL Retail Stores to find the top rated Retail Stores . | Metadata: {'id': 'ea82ce94-0253-4e76-bdfa-2ca89be58129', 'amount': 3.25, 'category': 'Food & Drink', 'transaction_date': '2025-10-26 00:00:00', '_id': '6f27f08b44aa462282a2267ff5b2c339', '_collection_name': 'transactions'}\n",
836
+ "Result: LAS VEGAS SOUVENIRS AND LAS VEGAS NV - Earn $$ as a professional gift shop owner. Take your first steps and register today. Become a professional gift shop owner from the comfort of your home. Register today. amazon.com has been visited by 1M+ users in the past month Read Customer Reviews & Find Best Sellers. Free, Easy Returns On Millions Of Items. Shop Chairs, Tables, Place Mats, Chandeliers, Pendant Light Fixtures and More. faire.com has been visited by 100K+ users in the past month Empowering Independent Entrepreneurs To Chase Their Dreams, Shop From Over 100,000 Brands. Buy Wholesale Products Easily & Risk Free on Faire With Free Returns On Your First Order. Organic · Eco-Friendly · Free & Easy Returns · Small Batch Bonanza Gift Shop - The World's Largest Gift Shop located in Las Vegas , Nevada . 40,000 square feet of Vegas souvenirs, apparel, collectibles, Native American art and more since 1980. Open daily 9AM-midnight. This is a review for souvenir shops in Las Vegas , NV : \"Morris & Co is a high-end souvenir shop of luxury items like jewelry, clothing, gifts, accessories, snacks, and many other cool items like LIV nightclub accessories. M&M’s World Las Vegasis located inside a showcase mall on Las Vegas Blvd. The impressive four-level store was the first ever M&M store ! This isn’t a traditional gift shop, but that doesn’t mean you won’t find plenty of fun gifts and Las Vegas souvenirs . Guests can create their M&M design or choose from several premade, Vegas -themed designs. This is ... See full list on vegasfoodandfun.com Coca-Cola has been a staple in American homes for decades. If you’re one of the many Coca-Cola lovers, this gift shop is for you! The store features a variety of Coca-Cola and Las Vegas -themed merchandise. Many of the products sold in the Coca-Cola storeare vintage or limited edition items that can’t be purchased anywhere else. If the gifts aren’t ... See full list on vegasfoodandfun.com Welcome to Las Vegas has multiple gift shops around Sin City, but the store on Las Vegas Blvd inside The Venetian at Grand Canal Shoppesis the most impressive. The whole store is dedicated to celebrating fabulous Las Vegas ! You’ll find t-shirts, shot glasses, snow globes, onesies, and anything else you can imagine in Las Vegas memorabilia form. Thi... See full list on vegasfoodandfun.com Downtown Container Parkis a hub for shopping, dining, and entertainment in Downtown Las Vegas . The park is made of repurposed shipping containers, hence the unique name. The best part about visiting the Downtown Container Park is wandering from one store to another with amazing food in between. The park focuses on local retailers, so you’ll find a ... See full list on vegasfoodandfun.com Tokyo Discount is a store on Maryland Pkwy, Las Vegas , NV , that brings Japanese culture to Sin City. The discount shop has all things Tokyo including Hello Kitty, Japanese snacks, Pokemon, and Japanese decor. The downtown location makes it easy to explore Tokyo Discount during your Las Vegas trip! Whether you buy something Vegas -themed or something... See full list on vegasfoodandfun.com Local Oasis is a shop in the art district of Las Vegas that a local artist opened in 2020. The small shop sells art, gifts, and items from local brand owners. What better souvenir for your Vegas trip than a one- of -a-kind art piece? It’s important to remember this shop doesn’t have a huge selection of cheesy Las Vegas souvenirs , but that’s why many ... See full list on vegasfoodandfun.com Karma Connection is a shop that specializes in all things psychic, crystals, and natural healing. If you’re interested in those things, you’ll find this store is overflowing with possibilities! You can buy a new crystal to keep as your Las Vegas souvenir or get a personalized psychic reading. This gift shop is usually filled with like-minded people... See full list on vegasfoodandfun.com The Gamblers General Store has been appealing to casino lovers since 1984. The store is located on S Main Street, and it’s one of the only souvenir shops in Las Vegas that caters to people who love gambling. You’ll find an inventory that includes playing cards, customized chips, and casino memorabilia. There’s even a book section with books that te... See full list on vegasfoodandfun.com Hudson News is the best place to get a gift when entering Las Vegas via Harry Reid Airport, formerly known as McCarran International Airport. They have a lot of the same stuff you’d find in gift shops outside the airport, but it’s way more convenient! Grab a t-shirt, mugs, key chains, and several other airport-friendly last-minute gifts. You can al... See full list on vegasfoodandfun.com Bonanza Gift Shop is much more than just another souvenir shop on the Strip. It’s the world’s largest gift shop! The inventory at Bonanza doesn’t just compete with other souvenir shops. It blows those shops out of the water! Bonanza has reasonable prices and a prime location , making it a fan favorite over the years. The world’s largest gift shop ca... See full list on vegasfoodandfun.com Jan 24, 2024 · The store was established in 1984 and has since been a staple of Las Vegas as the one and only Gamblers general store. You won’t miss any gamblers’ favorite items; ranging from hand to find items to popular selections. This guide will give you all the best places to get souvenirs, the different types of gifts to expect in the shops, and even tips on how to get them back home. Get your shopping lists ready because you’ll check off everyone—and find a few fun items for your own keepsake. Just a short walk away, M&M’s Las Vegas at Showcase Mall is a four-story candy wonderland, where you can create personalized M&M’s in minutes. Whether you're a chocolate fanatic or just looking for a fun stop, these iconic stores are the sweetest attractions on the Strip! Because we are here \"in the heart of it\" we are able to offer you ALL the popular Las Vegas Souvenirs and Las Vegas Gift Items you will see around Vegas in the various giftshops. We continually strive to bring you what you see and want from Las Vegas in the form of Quality Products. Earn $$ as a professional gift shop owner. Take your first steps and register today. Become a professional gift shop owner from the comfort of your home. Register today. amazon.com has been visited by 1M+ users in the past month Read Customer Reviews & Find Best Sellers. Free, Easy Returns On Millions Of Items. Shop Chairs, Tables, Place Mats, Chandeliers, Pendant Light Fixtures and More. faire.com has been visited by 100K+ users in the past month Empowering Independent Entrepreneurs To Chase Their Dreams, Shop From Over 100,000 Brands. Buy Wholesale Products Easily & Risk Free on Faire With Free Returns On Your First Order. Organic · Eco-Friendly · Free & Easy Returns · Small Batch | Metadata: {'id': 'bac13cd8-cfcc-48f3-8dfa-18c3a3b2cc59', 'amount': 15.14, 'category': 'Merchandise', 'transaction_date': '2025-05-24 00:00:00', '_id': '415f62d03ac949f2b5ab56ef8cc8d105', '_collection_name': 'transactions'}\n",
837
+ "Result: UAH BURSARS OFFICE - The Bursar 's Office oversees the billing and collection of fees, adding funds to student accounts, and student refunds.Student Services Building, Room 123 301 Sparkman Drive Huntsville, AL 35899. 256.824.6226 bursar @ uah .edu. UAH Bursar Welcome to the Office of the Bursar The Bursar ’s Office manages student accounts, including the billing and collection of fees, and student refunds. Located in the Student Services… cs_ office . Dismiss.Your personal data will be processed and information from your device (cookies, unique identifiers, and other device data) may be stored by, accessed by and shared with 156 TCF vendor(s) and 81 ad partner(s), or used specifically by this site. UAH 1 199,50Цена предложения: UAH 1 199,50.Политика отмены PS Store . Меры предосторожности. О рейтингах. Searching for an Advance Auto Parts close to you? Advance has locations across North America which provide quality auto parts, advice and accessories for your car. | Metadata: {'id': 'eea3224b-1289-40bd-bf02-a54a6a7a7ce7', 'amount': 50.0, 'category': 'Education', 'transaction_date': '2025-08-21 00:00:00', '_id': '775b6f5066bd4435837a5f3c1b613aea', '_collection_name': 'transactions'}\n",
838
+ "Result: HANDELS HOMEMADE JONES V - Jan 2, 2026 · Monty Python's Life of Brian is a 1979 British surreal biblical black comedy film starring and written by the comedy group Monty Python It was directed by ... Nov 24, 2025 · In 1861, Welsh entrepreneur Pryce Pryce-Jones formed the first mail order business, an idea which would change the nature of retail. Selling Welsh flannel ... Dec 10, 2025 · Christmas music comprises a variety of genres of music regularly performed or heard around the Christmas season. Enter your address to see if Handel ' s Homemade Ice Cream - Jones Valley delivery is available to your location in Huntsville.What are some other stores nearby Handel ' s Homemade Ice Cream - Jones Valley? store locator pin Store Finder. All Our Fun-Filled Flavors. We have a collection of over 100 flavors. Below is a full list of our flavors. Be sure to check your local store to discover the flavors they are currently serving. | Metadata: {'id': '1c5b9d0f-8ecf-4d06-baa5-e6f036102eb0', 'amount': 8.18, 'category': 'Food & Drink', 'transaction_date': '2025-12-30 00:00:00', '_id': '8e207351ec57437aae0343b6c81ea434', '_collection_name': 'transactions'}\n",
839
+ "Result: SQ *SPILL COFFEE AND CREA - **Free refills of hot and iced brewed coffee and tea during same store visit. Excludes Cold Brew, Nitro Cold Brew, Iced Tea Lemonade, flavored Iced Tea and Starbucks Refreshers® base. At participating stores . Find out my IP address, public IPv4 and IPv6, IP location , ISP with additional information like the country, city, user agent, your browser and OS. osu! farm pp maps and beatmap recommendations... Square register is the POS software that’s simple, powerful, and free. Grand Tour Around Island 16 Locations plus Snorkeling. 4.9. (7,365).Donate to Kiva.org today to provide loans to local entrepreneurs and the Tripadvisor Foundation will match it, up to $150,000 USD collectively. Terms apply. | Metadata: {'id': 'b7708547-c125-427e-9e9e-f330ea66af71', 'amount': 4.39, 'category': 'Food & Drink', 'transaction_date': '2025-08-30 00:00:00', '_id': '5b48543fabe44e468e8db6844d868baf', '_collection_name': 'transactions'}\n",
840
+ "==================================\u001b[1m Ai Message \u001b[0m==================================\n",
841
  "\n",
842
+ "I couldn't find any transactions related to haircuts.\n"
843
  ]
844
  }
845
  ],
846
  "source": [
847
+ "question = \"ow much did i spend in haircuts\"\n",
848
  "steps = []\n",
849
  "\n",
850
  "for step in agent.stream(\n",
notebooks/2_test_vectordb.ipynb CHANGED
@@ -1,76 +1,118 @@
1
  {
2
  "cells": [
 
 
 
 
 
 
 
 
 
 
3
  {
4
  "cell_type": "code",
5
- "execution_count": 3,
6
  "metadata": {},
7
  "outputs": [],
8
  "source": [
9
- "%reload_ext autoreload\n",
10
- "%autoreload 2"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  ]
12
  },
13
  {
14
  "cell_type": "code",
15
- "execution_count": 4,
16
  "metadata": {},
17
- "outputs": [
18
- {
19
- "data": {
20
- "text/plain": [
21
- "True"
22
- ]
23
- },
24
- "execution_count": 4,
25
- "metadata": {},
26
- "output_type": "execute_result"
27
- }
28
- ],
29
  "source": [
30
- "import pandas as pd\n",
31
- "import sqlite3\n",
32
- "from langchain.chat_models import init_chat_model\n",
33
- "from langchain_core.prompts import ChatPromptTemplate\n",
34
- "from langchain_core.output_parsers import JsonOutputParser\n",
35
  "\n",
36
- "from dotenv import load_dotenv\n",
37
- "load_dotenv()"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  ]
39
  },
40
  {
41
  "cell_type": "code",
42
  "execution_count": null,
43
  "metadata": {},
44
- "outputs": [
45
- {
46
- "name": "stderr",
47
- "output_type": "stream",
48
- "text": [
49
- "/Users/sawale/Documents/learning/money_rag/.venv/lib/python3.12/site-packages/google/cloud/aiplatform/models.py:52: FutureWarning: Support for google-cloud-storage < 3.0.0 will be removed in a future version of google-cloud-aiplatform. Please upgrade to google-cloud-storage >= 3.0.0.\n",
50
- " from google.cloud.aiplatform.utils import gcs_utils\n"
51
- ]
52
- },
53
- {
54
- "data": {
55
- "text/plain": [
56
- "langchain_google_vertexai.chat_models.ChatVertexAI"
57
- ]
58
- },
59
- "execution_count": 5,
60
- "metadata": {},
61
- "output_type": "execute_result"
62
- }
63
- ],
64
  "source": [
65
- "# Initialize the Gemini model via Vertex AI\n",
66
- "vertex_llm = init_chat_model(\n",
67
- " \"gemini-2.5-flash\", \n",
68
- " model_provider=\"google_vertexai\",\n",
69
- " project='gen-lang-client-0311515393',\n",
70
- " location='us-central1',\n",
71
- ")\n",
72
  "\n",
73
- "type(vertex_llm)"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  ]
75
  },
76
  {
 
1
  {
2
  "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "metadata": {},
6
+ "source": [
7
+ "# Test MCP Server (Local Mode)\n",
8
+ "\n",
9
+ "This notebook demonstrates how to use the `mcp_server.py` tools directly within a LangChain workflow. \n",
10
+ "This simulates how an Agent would interact with your Local or Cloud MCP Server."
11
+ ]
12
+ },
13
  {
14
  "cell_type": "code",
15
+ "execution_count": null,
16
  "metadata": {},
17
  "outputs": [],
18
  "source": [
19
+ "import sys\n",
20
+ "import os\n",
21
+ "import pandas as pd\n",
22
+ "from dotenv import load_dotenv\n",
23
+ "from langchain_core.tools import StructuredTool\n",
24
+ "from langchain_google_vertexai import ChatVertexAI\n",
25
+ "from langgraph.prebuilt import create_react_agent\n",
26
+ "\n",
27
+ "# 1. Setup Path to import mcp_server from parent directory\n",
28
+ "sys.path.append(\"..\")\n",
29
+ "\n",
30
+ "# 2. Setup Environment\n",
31
+ "load_dotenv()\n",
32
+ "\n",
33
+ "# POINT DATABASE TO A LOCAL FOLDER FOR THIS NOTEBOOK\n",
34
+ "# This ensures we don't mess with deployment default paths, or we explicitly stick to 'temp_data'\n",
35
+ "# mcp_server defaults to using 'DATA_DIR' env var if set\n",
36
+ "os.environ[\"DATA_DIR\"] = os.path.abspath(\"../temp_data_notebook_test\")\n",
37
+ "print(f\"Using Data Dir: {os.environ['DATA_DIR']}\")\n",
38
+ "\n",
39
+ "# 3. Import Tools directly from Server Code\n",
40
+ "# (In a real remote scenario, you would use MCPClient instead)\n",
41
+ "from mcp_server import ingest_transactions, get_database_schema, query_database, semantic_search, clear_database\n",
42
+ "\n",
43
+ "# 4. Wrap as LangChain Tools\n",
44
+ "tools = [\n",
45
+ " StructuredTool.from_function(ingest_transactions),\n",
46
+ " StructuredTool.from_function(clear_database),\n",
47
+ " StructuredTool.from_function(get_database_schema),\n",
48
+ " StructuredTool.from_function(query_database),\n",
49
+ " StructuredTool.from_function(semantic_search),\n",
50
+ "]\n",
51
+ "\n",
52
+ "# 5. Initialize Agent\n",
53
+ "llm = ChatVertexAI(model=\"gemini-1.5-flash-001\", temperature=0)\n",
54
+ "agent_executor = create_react_agent(llm, tools)\n",
55
+ "\n",
56
+ "print(\"Agent and Tools loaded successfully!\")"
57
  ]
58
  },
59
  {
60
  "cell_type": "code",
61
+ "execution_count": null,
62
  "metadata": {},
63
+ "outputs": [],
 
 
 
 
 
 
 
 
 
 
 
64
  "source": [
65
+ "# --- STEP 1: LOAD & INGEST DATA ---\n",
66
+ "# We will read one of the CSVs from demo_data and send it to the 'ingest_transactions' tool.\n",
 
 
 
67
  "\n",
68
+ "# Read Local File\n",
69
+ "csv_path = \"../demo_data/Chase5282_Activity20240110_20260110_20260111.CSV\"\n",
70
+ "\n",
71
+ "if os.path.exists(csv_path):\n",
72
+ " with open(csv_path, 'r') as f:\n",
73
+ " csv_content = f.read()\n",
74
+ "\n",
75
+ " print(f\"Read {len(csv_content)} bytes from CSV.\")\n",
76
+ " \n",
77
+ " # Run the Agent to Ingest\n",
78
+ " print(\"\\n--- Ingesting Data via Agent ---\")\n",
79
+ " response = agent_executor.invoke(\n",
80
+ " {\"messages\": [(\"user\", f\"Please clear the database first, then ingest this transaction data:\\n\\n{csv_content}\")]}\n",
81
+ " )\n",
82
+ " print(response[\"messages\"][-1].content)\n",
83
+ "else:\n",
84
+ " print(f\"File not found: {csv_path}\")"
85
  ]
86
  },
87
  {
88
  "cell_type": "code",
89
  "execution_count": null,
90
  "metadata": {},
91
+ "outputs": [],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  "source": [
93
+ "# --- STEP 2: TEST RETRIEVAL (RAG) ---\n",
 
 
 
 
 
 
94
  "\n",
95
+ "queries = [\n",
96
+ " \"What is the database schema?\",\n",
97
+ " \"How much did I spend at McDonalds?\",\n",
98
+ " \"Show me the top 3 most expensive transactions.\",\n",
99
+ " \"What is my total spending on Food & Drink?\" \n",
100
+ "]\n",
101
+ "\n",
102
+ "for q in queries:\n",
103
+ " print(f\"\\nUser: {q}\")\n",
104
+ " result = agent_executor.invoke({\"messages\": [(\"user\", q)]})\n",
105
+ " print(f\"AI: {result['messages'][-1].content}\")"
106
+ ]
107
+ },
108
+ {
109
+ "cell_type": "code",
110
+ "execution_count": 3,
111
+ "metadata": {},
112
+ "outputs": [],
113
+ "source": [
114
+ "%reload_ext autoreload\n",
115
+ "%autoreload 2"
116
  ]
117
  },
118
  {
requirements.txt CHANGED
@@ -1,156 +1,42 @@
1
- ddgs>=9.10.0
2
- duckduckgo-search>=8.1.1
3
- fastmcp>=2.14.3
4
- google-api-core>=2.29.0
5
- google-auth>=2.47.0
6
- google-cloud-aiplatform>=1.133.0
7
- google-cloud-bigquery>=3.40.0
8
- google-cloud-core>=2.5.0
9
- google-cloud-resource-manager>=1.15.0
10
- google-cloud-storage>=2.19.0
11
- google-crc32c>=1.8.0
12
- google-genai>=1.57.0
13
- google-resumable-media>=2.8.0
14
- googleapis-common-protos>=1.72.0
15
- grpc-google-iam-v1>=0.14.3
16
- grpcio>=1.76.0
17
- grpcio-status>=1.76.0
18
- h11>=0.16.0
19
- h2>=4.3.0
20
- hpack>=4.1.0
21
- httpcore>=1.0.9
22
- httpx>=0.28.1
23
- httpx-sse>=0.4.3
24
- hyperframe>=6.1.0
25
- idna>=3.11
26
- importlib-metadata>=8.7.1
27
- ipykernel>=7.1.0
28
- ipython>=9.9.0
29
- ipython-pygments-lexers>=1.1.1
30
- jaraco-classes>=3.4.0
31
- jaraco-context>=6.1.0
32
- jaraco-functools>=4.4.0
33
- jedi>=0.19.2
34
- jiter>=0.12.0
35
- jsonpatch>=1.33
36
- jsonpointer>=3.0.0
37
- jsonschema>=4.26.0
38
- jsonschema-path>=0.3.4
39
- jsonschema-specifications>=2025.9.1
40
- jupyter-client>=8.8.0
41
- jupyter-core>=5.9.1
42
- keyring>=25.7.0
43
  langchain>=1.2.3
44
- langchain-classic>=1.0.1
45
- langchain-community>=0.3.31
46
  langchain-core>=1.2.7
 
 
 
 
 
47
  langchain-google-vertexai>=2.1.2
48
- langchain-mcp>=0.2.1
49
- langchain-openai>=0.3.35
50
- langchain-qdrant>=1.1.0
51
- langchain-text-splitters>=0.3.11
52
- langgraph>=1.0.5
53
- langgraph-checkpoint>=3.0.1
54
- langgraph-prebuilt>=1.0.5
55
- langgraph-sdk>=0.3.2
56
- langsmith>=0.6.2
57
- lupa>=2.6
58
- lxml>=6.0.2
59
- markdown-it-py>=4.0.0
60
- marshmallow>=3.26.2
61
- matplotlib-inline>=0.2.1
62
- mcp>=1.25.0
63
- mdurl>=0.1.2
64
- more-itertools>=10.8.0
65
- multidict>=6.7.0
66
- mypy-extensions>=1.1.0
67
- nest-asyncio>=1.6.0
68
- numexpr>=2.14.1
69
- numpy>=2.4.1
70
  openai>=2.15.0
71
- openapi-pydantic>=0.5.1
72
- opentelemetry-api>=1.39.1
73
- opentelemetry-exporter-prometheus>=0.60b1
74
- opentelemetry-instrumentation>=0.60b1
75
- opentelemetry-sdk>=1.39.1
76
- opentelemetry-semantic-conventions>=0.60b1
77
- orjson>=3.11.5
78
- ormsgpack>=1.12.1
79
- packaging>=25.0
80
- pandas>=2.3.3
81
- parso>=0.8.5
82
- pathable>=0.4.4
83
- pathvalidate>=3.3.1
84
- pexpect>=4.9.0
85
- platformdirs>=4.5.1
86
- portalocker>=3.2.0
87
- primp>=0.15.0
88
- prometheus-client>=0.24.1
89
- prompt-toolkit>=3.0.52
90
- propcache>=0.4.1
91
- proto-plus>=1.27.0
92
- protobuf>=6.33.3
93
- psutil>=7.2.1
94
- ptyprocess>=0.7.0
95
- pure-eval>=0.2.3
96
- py-key-value-aio>=0.3.0
97
- py-key-value-shared>=0.3.0
98
- pyarrow>=21.0.0
99
- pyasn1>=0.6.1
100
- pyasn1-modules>=0.4.2
101
- pycparser>=2.23
102
- pydantic>=2.12.5
103
- pydantic-core>=2.41.5
104
- pydantic-settings>=2.12.0
105
- pydocket>=0.16.6
106
- pygments>=2.19.2
107
- pyjwt>=2.10.1
108
- pyperclip>=1.11.0
109
- python-dateutil>=2.9.0.post0
110
- python-dotenv>=1.2.1
111
- python-json-logger>=4.0.0
112
- python-multipart>=0.0.21
113
- pytz>=2025.2
114
- pyyaml>=6.0.3
115
- pyzmq>=27.1.0
116
  qdrant-client>=1.16.2
117
- redis>=7.1.0
118
- referencing>=0.36.2
119
- regex>=2025.11.3
120
- requests>=2.32.5
121
- requests-toolbelt>=1.0.0
122
- rich>=14.2.0
123
- rich-rst>=1.3.2
124
- rpds-py>=0.30.0
125
- rsa>=4.9.1
126
- shellingham>=1.5.4
127
- six>=1.17.0
128
- sniffio>=1.3.1
129
- socksio>=1.0.0
130
- sortedcontainers>=2.4.0
131
  sqlalchemy>=2.0.45
132
- sse-starlette>=3.1.2
133
- stack-data>=0.6.3
 
 
 
134
  starlette>=0.51.0
135
- tabulate>=0.9.0
 
 
136
  tenacity>=9.1.2
137
- tiktoken>=0.12.0
138
- tornado>=6.5.4
139
- tqdm>=4.67.1
140
- traitlets>=5.14.3
141
- typer>=0.21.1
142
- typing-extensions>=4.15.0
143
- typing-inspect>=0.9.0
144
- typing-inspection>=0.4.2
145
- tzdata>=2025.3
146
- urllib3>=2.6.3
147
- uuid-utils>=0.13.0
148
- uvicorn>=0.40.0
149
- validators>=0.35.0
150
- wcwidth>=0.2.14
151
- websockets>=15.0.1
152
- wrapt>=1.17.3
153
- xxhash>=3.6.0
154
- yarl>=1.22.0
155
- zipp>=3.23.0
156
- zstandard>=0.25.0
 
1
+ # --- Core AI Orchestration ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  langchain>=1.2.3
3
+ langchain-community>=0.4.1
 
4
  langchain-core>=1.2.7
5
+ langgraph>=1.0.6
6
+ pydantic>=2.12.5
7
+
8
+ # --- Model Providers ---
9
+ # Google / Vertex AI
10
  langchain-google-vertexai>=2.1.2
11
+ langchain-google-genai>=2.0.0
12
+ google-cloud-aiplatform>=1.133.0
13
+ google-genai>=1.57.0
14
+
15
+ # OpenAI
16
+ langchain-openai>=1.1.7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  openai>=2.15.0
18
+
19
+ # --- MCP & Tooling ---
20
+ fastmcp>=2.14.3
21
+ mcp>=1.25.0
22
+ # langchain-mcp>=0.2.1
23
+ langchain-mcp-adapters>=0.2.1
24
+ duckduckgo-search>=8.1.1
25
+
26
+ # --- Vector DB & Data ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  qdrant-client>=1.16.2
28
+ langchain-qdrant>=1.1.0
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  sqlalchemy>=2.0.45
30
+ pandas>=2.3.3
31
+ redis>=7.1.0
32
+
33
+ # --- Infrastructure & API ---
34
+ uvicorn>=0.40.0
35
  starlette>=0.51.0
36
+ python-dotenv>=1.2.1
37
+ httpx>=0.28.1
38
+ requests>=2.32.5
39
  tenacity>=9.1.2
40
+
41
+
42
+ streamlit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
utils/data_ingestion.py DELETED
@@ -1,84 +0,0 @@
1
- import pandas as pd
2
- import sqlite3
3
- from langchain.chat_models import init_chat_model
4
- from langchain_core.prompts import ChatPromptTemplate
5
- from langchain_core.output_parsers import JsonOutputParser
6
-
7
- def ingest_csv(file_path, llm, db_path="money_rag.db"):
8
- df = pd.read_csv(file_path)
9
- headers = df.columns.tolist()
10
- sample_data = df.head(5).to_json() # Increased sample to 5 for better context
11
-
12
- prompt = ChatPromptTemplate.from_template("""
13
- I have a CSV with these headers: {headers}
14
- Sample data: {sample}
15
-
16
- Tasks:
17
- 1. Map headers to my standard schema: date_col, desc_col, amount_col, category_col, type
18
- 2. Identify type:
19
- - type = payment type, use sign from amount to extract the type
20
- - If it is a credit, return "credit"
21
- - If it is a debit, return "debit"
22
- - Sign conventions are of two types:
23
- - Positive : Positive means credit
24
- - Negative: Negative means debit
25
- - {filename} : from the filename find the source
26
- - Positive convention : if the source is Discover
27
- - Negative convention : if the source is Chase
28
-
29
-
30
- 3. Remove the sign from amount to map to amount_col
31
-
32
- 2. Identify 'sign_convention':
33
- - Look at the 'amount_col' column.
34
- - If a 'Payment' or 'Credit' is a NEGATIVE number, return "payment_is_negative".
35
- - If a 'Payment' or 'Credit' is a POSITIVE number, return "payment_is_positive".
36
-
37
- Return ONLY JSON with keys: date_col, desc_col, amount_col, category_col, sign_convention.
38
-
39
- Understand that the conventions work like this:
40
- 1. Credit convention:
41
- """)
42
-
43
- chain = prompt | llm | JsonOutputParser()
44
- mapping = chain.invoke({"headers": headers, "sample": sample_data, "filename": file_path})
45
-
46
- standard_df = pd.DataFrame()
47
- standard_df['transaction_date'] = pd.to_datetime(df[mapping['date_col']])
48
- standard_df['description'] = df[mapping['desc_col']]
49
-
50
- # --- Normalization Logic ---
51
- raw_amounts = pd.to_numeric(df[mapping['amount_col']])
52
-
53
- # We want a standard: Spending is POSITIVE, Payments/Refunds are NEGATIVE
54
- if mapping.get('sign_convention') == "payment_is_positive":
55
- # Flip the signs so payments become negative
56
- standard_df['amount'] = raw_amounts * -1
57
- else:
58
- # Already consistent (spending +, payments -)
59
- standard_df['amount'] = raw_amounts
60
-
61
- standard_df['category'] = df[mapping['category_col']] if mapping.get('category_col') else 'Uncategorized'
62
- standard_df['source_file'] = file_path
63
-
64
- conn = sqlite3.connect(db_path)
65
- standard_df.to_sql("transactions", conn, if_exists="append", index=False)
66
- conn.close()
67
-
68
- print(f"✅ Ingested {len(standard_df)} rows. Convention: {mapping.get('sign_convention')}")
69
-
70
- # --- Example Usage with Different Providers ---
71
-
72
- # To use Gemini, you'd install: pip install -U langchain-google-genai
73
- # To use Vertex AI, you'd install: pip install -qU langchain-google-vertexai
74
-
75
- # Option A: OpenAI
76
- # llm = init_chat_model("gpt-4o", model_provider="openai", temperature=0)
77
-
78
- # Option B: Google Gemini (Developer API)
79
- # llm_gemini = init_chat_model("gemini-2.5-flash", model_provider="google_genai", temperature=0)
80
-
81
- # Option C: Google Vertex AI (GCP Enterprise)
82
- # llm_vertex = init_chat_model("gemini-1.5-pro", model_provider="google_vertexai", temperature=0)
83
-
84
- # ingest_csv("discover_june.csv", llm_gemini)