banko-ai-assistant 1.0.14__py3-none-any.whl → 1.0.16__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- banko_ai/cli.py +2 -0
- banko_ai/vector_search/generator.py +36 -7
- banko_ai/vector_search/search.py +3 -3
- banko_ai/web/app.py +1 -1
- {banko_ai_assistant-1.0.14.dist-info → banko_ai_assistant-1.0.16.dist-info}/METADATA +1 -1
- {banko_ai_assistant-1.0.14.dist-info → banko_ai_assistant-1.0.16.dist-info}/RECORD +10 -10
- {banko_ai_assistant-1.0.14.dist-info → banko_ai_assistant-1.0.16.dist-info}/WHEEL +0 -0
- {banko_ai_assistant-1.0.14.dist-info → banko_ai_assistant-1.0.16.dist-info}/entry_points.txt +0 -0
- {banko_ai_assistant-1.0.14.dist-info → banko_ai_assistant-1.0.16.dist-info}/licenses/LICENSE +0 -0
- {banko_ai_assistant-1.0.14.dist-info → banko_ai_assistant-1.0.16.dist-info}/top_level.txt +0 -0
banko_ai/cli.py
CHANGED
@@ -60,6 +60,7 @@ def run(host, port, debug, generate_data, no_data, clear_data, background):
|
|
60
60
|
# Generate data if not explicitly disabled
|
61
61
|
if not no_data:
|
62
62
|
click.echo("🔍 Checking database setup...")
|
63
|
+
click.echo(f"Using database: {config.database_url}")
|
63
64
|
click.echo(f"Generating {generate_data} sample expense records...")
|
64
65
|
generator = EnhancedExpenseGenerator(config.database_url)
|
65
66
|
|
@@ -207,6 +208,7 @@ def start(host, port, generate_data, no_data, clear_data):
|
|
207
208
|
# Generate data if not explicitly disabled
|
208
209
|
if not no_data:
|
209
210
|
click.echo("🔍 Checking database setup...")
|
211
|
+
click.echo(f"Using database: {config.database_url}")
|
210
212
|
click.echo(f"Generating {generate_data} sample expense records...")
|
211
213
|
generator = EnhancedExpenseGenerator(config.database_url)
|
212
214
|
|
@@ -86,46 +86,56 @@ class EnhancedExpenseGenerator:
|
|
86
86
|
"Internet Provider", "Phone Company", "Water Company"
|
87
87
|
]
|
88
88
|
|
89
|
-
# Use the exact categories from the original CSV
|
89
|
+
# Use the exact categories from the original CSV with appropriate merchants
|
90
90
|
self._categories = {
|
91
91
|
"Groceries": {
|
92
92
|
"items": ["Fresh produce", "Dairy products", "Meat and poultry", "Pantry staples", "Organic foods", "Beverages", "Snacks"],
|
93
|
+
"merchants": ["Whole Foods", "Local Market", "Costco", "Walmart", "Target"],
|
93
94
|
"amount_range": (10, 150)
|
94
95
|
},
|
95
96
|
"Home Improvement": {
|
96
97
|
"items": ["Tools", "Hardware", "Paint", "Lumber", "Electrical supplies", "Plumbing supplies", "Garden supplies"],
|
98
|
+
"merchants": ["Home Depot", "Lowe's", "Ace Hardware", "IKEA"],
|
97
99
|
"amount_range": (20, 500)
|
98
100
|
},
|
99
101
|
"Electronics": {
|
100
102
|
"items": ["Smartphone", "Laptop", "Tablet", "Headphones", "Camera", "Gaming console", "Smart home device"],
|
103
|
+
"merchants": ["Apple Store", "Best Buy", "Amazon", "Target", "Walmart"],
|
101
104
|
"amount_range": (50, 1000)
|
102
105
|
},
|
103
106
|
"Subscription": {
|
104
107
|
"items": ["Streaming service", "Software subscription", "Gym membership", "News subscription", "Cloud storage", "Music service"],
|
108
|
+
"merchants": ["Netflix", "Spotify", "Planet Fitness", "Electric Company", "Internet Provider"],
|
105
109
|
"amount_range": (10, 50)
|
106
110
|
},
|
107
111
|
"Shopping": {
|
108
112
|
"items": ["Clothing", "Shoes", "Accessories", "Home decor", "Books", "Toys", "Beauty products"],
|
113
|
+
"merchants": ["Amazon", "Target", "Walmart", "IKEA", "Best Buy"],
|
109
114
|
"amount_range": (15, 200)
|
110
115
|
},
|
111
116
|
"Restaurant": {
|
112
117
|
"items": ["Dinner", "Lunch", "Breakfast", "Takeout", "Delivery", "Catering", "Fine dining"],
|
118
|
+
"merchants": ["McDonald's", "Italian Bistro", "Chipotle", "Subway", "Pizza Hut", "Domino's"],
|
113
119
|
"amount_range": (15, 100)
|
114
120
|
},
|
115
121
|
"Transport": {
|
116
122
|
"items": ["Uber ride", "Lyft ride", "Taxi", "Bus fare", "Train ticket", "Flight", "Car rental"],
|
123
|
+
"merchants": ["Uber", "Lyft", "Delta Airlines"],
|
117
124
|
"amount_range": (5, 500)
|
118
125
|
},
|
119
126
|
"Fuel": {
|
120
127
|
"items": ["Gas fill-up", "Electric charging", "Diesel fuel", "Premium gas", "Regular gas"],
|
128
|
+
"merchants": ["Shell Gas Station", "Tesla Supercharger", "Exxon", "Chevron", "BP"],
|
121
129
|
"amount_range": (20, 100)
|
122
130
|
},
|
123
131
|
"Travel": {
|
124
132
|
"items": ["Flight", "Hotel", "Car rental", "Travel insurance", "Airport parking", "Baggage fee"],
|
133
|
+
"merchants": ["Delta Airlines", "Hilton Hotels"],
|
125
134
|
"amount_range": (100, 2000)
|
126
135
|
},
|
127
136
|
"Coffee": {
|
128
137
|
"items": ["Coffee", "Espresso", "Latte", "Cappuccino", "Pastry", "Sandwich", "Breakfast"],
|
138
|
+
"merchants": ["Starbucks", "Local Market", "Whole Foods", "Costco"],
|
129
139
|
"amount_range": (3, 25)
|
130
140
|
}
|
131
141
|
}
|
@@ -142,8 +152,8 @@ class EnhancedExpenseGenerator:
|
|
142
152
|
category = random.choice(list(self.categories.keys()))
|
143
153
|
category_data = self.categories[category]
|
144
154
|
|
145
|
-
# Select merchant from
|
146
|
-
merchant = random.choice(
|
155
|
+
# Select merchant from category-specific merchants
|
156
|
+
merchant = random.choice(category_data["merchants"])
|
147
157
|
|
148
158
|
# Generate amount within category range
|
149
159
|
amount = round(random.uniform(*category_data["amount_range"]), 2)
|
@@ -242,10 +252,12 @@ class EnhancedExpenseGenerator:
|
|
242
252
|
df = pd.DataFrame(batch)
|
243
253
|
df.to_sql('expenses', conn, if_exists='append', index=False, method='multi')
|
244
254
|
# Transaction is automatically committed when exiting the context
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
255
|
+
|
256
|
+
# Only increment counter after successful transaction
|
257
|
+
total_inserted += len(batch)
|
258
|
+
batch_num = i//batch_size + 1
|
259
|
+
print(f"✅ Batch {batch_num}/{total_batches}: {len(batch)} records inserted (Total: {total_inserted})")
|
260
|
+
break # Success, exit retry loop
|
249
261
|
|
250
262
|
except OperationalError as e:
|
251
263
|
# Check if it's a CockroachDB serialization failure (SQL state 40001)
|
@@ -319,14 +331,31 @@ class EnhancedExpenseGenerator:
|
|
319
331
|
def get_expense_count(self) -> int:
|
320
332
|
"""Get the current number of expenses in the database."""
|
321
333
|
try:
|
334
|
+
# Ensure tables exist first
|
335
|
+
self._ensure_tables_exist()
|
336
|
+
|
322
337
|
from sqlalchemy import text
|
323
338
|
with self.engine.connect() as conn:
|
324
339
|
result = conn.execute(text("SELECT COUNT(*) FROM expenses"))
|
325
340
|
return result.scalar()
|
326
341
|
except Exception as e:
|
327
342
|
print(f"Error getting expense count: {e}")
|
343
|
+
if "connection" in str(e).lower() or "refused" in str(e).lower():
|
344
|
+
print("💡 Make sure CockroachDB is running:")
|
345
|
+
print(" cockroach start --insecure")
|
346
|
+
print(" Or set DATABASE_URL to your database connection string")
|
328
347
|
return 0
|
329
348
|
|
349
|
+
def _ensure_tables_exist(self):
|
350
|
+
"""Ensure database tables exist."""
|
351
|
+
try:
|
352
|
+
from ..utils.database import DatabaseManager
|
353
|
+
db_manager = DatabaseManager(self.database_url)
|
354
|
+
db_manager.create_tables()
|
355
|
+
except Exception as e:
|
356
|
+
print(f"Error creating tables: {e}")
|
357
|
+
# Continue anyway - tables might already exist
|
358
|
+
|
330
359
|
def generate_and_save(
|
331
360
|
self,
|
332
361
|
count: int,
|
banko_ai/vector_search/search.py
CHANGED
@@ -70,9 +70,9 @@ class VectorSearchEngine:
|
|
70
70
|
merchant,
|
71
71
|
shopping_type,
|
72
72
|
expense_amount,
|
73
|
-
embedding
|
73
|
+
embedding <-> :search_embedding as similarity_score
|
74
74
|
FROM expenses
|
75
|
-
ORDER BY embedding
|
75
|
+
ORDER BY embedding <-> :search_embedding
|
76
76
|
LIMIT :limit
|
77
77
|
""")
|
78
78
|
|
@@ -465,7 +465,7 @@ class VectorSearchEngine:
|
|
465
465
|
merchant,
|
466
466
|
expense_amount,
|
467
467
|
expense_date,
|
468
|
-
1 - (embedding
|
468
|
+
1 - (embedding <-> %s) as similarity_score,
|
469
469
|
shopping_type,
|
470
470
|
payment_method,
|
471
471
|
recurring,
|
banko_ai/web/app.py
CHANGED
@@ -620,7 +620,7 @@ def create_app() -> Flask:
|
|
620
620
|
def ai_status():
|
621
621
|
"""Endpoint to check the status of AI services and database."""
|
622
622
|
# Check database status
|
623
|
-
db_connected, db_message, table_exists, record_count =
|
623
|
+
db_connected, db_message, table_exists, record_count = check_database_connection(config.database_url)
|
624
624
|
|
625
625
|
status = {
|
626
626
|
'current_service': config.ai_service,
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: banko-ai-assistant
|
3
|
-
Version: 1.0.
|
3
|
+
Version: 1.0.16
|
4
4
|
Summary: AI-powered expense analysis and RAG system with CockroachDB vector search and multi-provider AI support
|
5
5
|
Author-email: Virag Tripathi <virag.tripathi@gmail.com>
|
6
6
|
License-Expression: MIT
|
@@ -1,6 +1,6 @@
|
|
1
1
|
banko_ai/__init__.py,sha256=G1InyKemqQxP9xx6yGZgolBmrmOLSpBXqGYY8LaFOeo,568
|
2
2
|
banko_ai/__main__.py,sha256=U-KkrXtL8JNIyV25PE5v_eYhlhjR7jd6kG-txfYfs0M,709
|
3
|
-
banko_ai/cli.py,sha256=
|
3
|
+
banko_ai/cli.py,sha256=7lMeDRIuJjeAkrVMzw2YmJp4t10KLGP7TRIywUSOkeU,13884
|
4
4
|
banko_ai/ai_providers/__init__.py,sha256=JdBgw5Mji2pe9nU-aiRYUmJuZk0q8KbcMtbpMJC5Dq8,483
|
5
5
|
banko_ai/ai_providers/aws_provider.py,sha256=-tR-8tlEeSL-Fspx05tTMFguvQylkW_pz0PI2XJEByM,13074
|
6
6
|
banko_ai/ai_providers/base.py,sha256=zbuAgkHIfJ0YkG83LXzieJuvXBcB2-nx7NhbL-I4Pf0,4725
|
@@ -151,14 +151,14 @@ banko_ai/utils/database.py,sha256=sJYAFTApkWReEJuMbbBDiz7XfgiiEd6lPSSyF6BQDpk,77
|
|
151
151
|
banko_ai/utils/migration.py,sha256=j1lYUVZyYMcMvxZUOFymoK19QTPqkDZFXD-iysVCnQo,4764
|
152
152
|
banko_ai/vector_search/__init__.py,sha256=vYksnkUU4FA8XBNzYZIH4FoGjXCx9oIbrDeapSzrNuE,621
|
153
153
|
banko_ai/vector_search/enrichment.py,sha256=tgAImLehkp2kL46vI5GEHsE8B5E4gT3PweXZLqqKei4,8097
|
154
|
-
banko_ai/vector_search/generator.py,sha256=
|
155
|
-
banko_ai/vector_search/search.py,sha256=
|
154
|
+
banko_ai/vector_search/generator.py,sha256=6SV6_RZ4M4-TfJvxlXHZY1p-zcLKpIJm0p871nmEjmI,17837
|
155
|
+
banko_ai/vector_search/search.py,sha256=RiDxqcRblAFSmxMvxy9nRRrw22OtVMHP5_rsvQsS_MU,18763
|
156
156
|
banko_ai/web/__init__.py,sha256=hjWVVxYpIZhOAN1qBf4xTd36a5AUHM03Q8BF8pykhJQ,363
|
157
|
-
banko_ai/web/app.py,sha256=
|
157
|
+
banko_ai/web/app.py,sha256=Temx39TX19idHrlrUwb_2QLr1GSZZVjqhyJC299NFMY,32145
|
158
158
|
banko_ai/web/auth.py,sha256=js6qIixSFHyLbETDm8GNLCPrDkCDcaQZPFOrqtZP1uw,2125
|
159
|
-
banko_ai_assistant-1.0.
|
160
|
-
banko_ai_assistant-1.0.
|
161
|
-
banko_ai_assistant-1.0.
|
162
|
-
banko_ai_assistant-1.0.
|
163
|
-
banko_ai_assistant-1.0.
|
164
|
-
banko_ai_assistant-1.0.
|
159
|
+
banko_ai_assistant-1.0.16.dist-info/licenses/LICENSE,sha256=skG0LkywIClj8fgSIXiG6o9vUDJ678BKBObIyJ19OMw,1075
|
160
|
+
banko_ai_assistant-1.0.16.dist-info/METADATA,sha256=BuVSoi6etHKRv2qq6rLW5FucRSzlUSuZip87XXi0y-g,13505
|
161
|
+
banko_ai_assistant-1.0.16.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
162
|
+
banko_ai_assistant-1.0.16.dist-info/entry_points.txt,sha256=IxPjBjMvbpCp-ikCA43bOSbYboTGPX4HYcZlvu2_vcA,47
|
163
|
+
banko_ai_assistant-1.0.16.dist-info/top_level.txt,sha256=xNMa9Z67UssefOQ2ubFObtqUYIfYmCIclfz0xdo5OPE,9
|
164
|
+
banko_ai_assistant-1.0.16.dist-info/RECORD,,
|
File without changes
|
{banko_ai_assistant-1.0.14.dist-info → banko_ai_assistant-1.0.16.dist-info}/entry_points.txt
RENAMED
File without changes
|
{banko_ai_assistant-1.0.14.dist-info → banko_ai_assistant-1.0.16.dist-info}/licenses/LICENSE
RENAMED
File without changes
|
File without changes
|