memra 0.2.13__py3-none-any.whl → 0.2.15__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.
- memra/cli.py +322 -51
- {memra-0.2.13.dist-info → memra-0.2.15.dist-info}/METADATA +1 -1
- {memra-0.2.13.dist-info → memra-0.2.15.dist-info}/RECORD +7 -61
- memra-0.2.15.dist-info/top_level.txt +1 -0
- memra-0.2.13.dist-info/top_level.txt +0 -4
- memra-ops/app.py +0 -808
- memra-ops/config/config.py +0 -25
- memra-ops/config.py +0 -34
- memra-ops/logic/__init__.py +0 -1
- memra-ops/logic/file_tools.py +0 -43
- memra-ops/logic/invoice_tools.py +0 -668
- memra-ops/logic/invoice_tools_fix.py +0 -66
- memra-ops/mcp_bridge_server.py +0 -1178
- memra-ops/scripts/check_database.py +0 -37
- memra-ops/scripts/clear_database.py +0 -48
- memra-ops/scripts/monitor_database.py +0 -67
- memra-ops/scripts/release.py +0 -133
- memra-ops/scripts/reset_database.py +0 -65
- memra-ops/scripts/start_memra.py +0 -334
- memra-ops/scripts/stop_memra.py +0 -132
- memra-ops/server_tool_registry.py +0 -190
- memra-ops/tests/test_llm_text_to_sql.py +0 -115
- memra-ops/tests/test_llm_vs_pattern.py +0 -130
- memra-ops/tests/test_mcp_schema_aware.py +0 -124
- memra-ops/tests/test_schema_aware_sql.py +0 -139
- memra-ops/tests/test_schema_aware_sql_simple.py +0 -66
- memra-ops/tests/test_text_to_sql_demo.py +0 -140
- memra-ops/tools/mcp_bridge_server.py +0 -851
- memra-sdk/examples/accounts_payable.py +0 -215
- memra-sdk/examples/accounts_payable_client.py +0 -217
- memra-sdk/examples/accounts_payable_mcp.py +0 -200
- memra-sdk/examples/ask_questions.py +0 -123
- memra-sdk/examples/invoice_processing.py +0 -116
- memra-sdk/examples/propane_delivery.py +0 -87
- memra-sdk/examples/simple_text_to_sql.py +0 -158
- memra-sdk/memra/__init__.py +0 -31
- memra-sdk/memra/discovery.py +0 -15
- memra-sdk/memra/discovery_client.py +0 -49
- memra-sdk/memra/execution.py +0 -481
- memra-sdk/memra/models.py +0 -99
- memra-sdk/memra/tool_registry.py +0 -343
- memra-sdk/memra/tool_registry_client.py +0 -106
- memra-sdk/scripts/release.py +0 -133
- memra-sdk/setup.py +0 -52
- memra-workflows/accounts_payable/accounts_payable.py +0 -215
- memra-workflows/accounts_payable/accounts_payable_client.py +0 -216
- memra-workflows/accounts_payable/accounts_payable_mcp.py +0 -200
- memra-workflows/accounts_payable/accounts_payable_smart.py +0 -221
- memra-workflows/invoice_processing/invoice_processing.py +0 -116
- memra-workflows/invoice_processing/smart_invoice_processor.py +0 -220
- memra-workflows/logic/__init__.py +0 -1
- memra-workflows/logic/file_tools.py +0 -50
- memra-workflows/logic/invoice_tools.py +0 -501
- memra-workflows/logic/propane_agents.py +0 -52
- memra-workflows/mcp_bridge_server.py +0 -230
- memra-workflows/propane_delivery/propane_delivery.py +0 -87
- memra-workflows/text_to_sql/complete_invoice_workflow_with_queries.py +0 -208
- memra-workflows/text_to_sql/complete_text_to_sql_system.py +0 -266
- memra-workflows/text_to_sql/file_discovery_demo.py +0 -156
- {memra-0.2.13.dist-info → memra-0.2.15.dist-info}/LICENSE +0 -0
- {memra-0.2.13.dist-info → memra-0.2.15.dist-info}/WHEEL +0 -0
- {memra-0.2.13.dist-info → memra-0.2.15.dist-info}/entry_points.txt +0 -0
memra/cli.py
CHANGED
@@ -37,11 +37,18 @@ def run_demo():
|
|
37
37
|
print("⏳ Waiting for services to be ready...")
|
38
38
|
wait_for_services()
|
39
39
|
|
40
|
-
# Step 5:
|
40
|
+
# Step 5: Start MCP bridge server
|
41
|
+
print("🔌 Starting MCP bridge server...")
|
42
|
+
if not start_mcp_bridge_server(demo_dir):
|
43
|
+
print("❌ Failed to start MCP bridge server.")
|
44
|
+
print(" You can start it manually: cd memra-ops && python mcp_bridge_server.py")
|
45
|
+
return False
|
46
|
+
|
47
|
+
# Step 6: Run the demo
|
41
48
|
print("🎯 Running ETL workflow...")
|
42
49
|
success = run_etl_workflow(demo_dir)
|
43
50
|
|
44
|
-
# Step
|
51
|
+
# Step 7: Show results
|
45
52
|
if success:
|
46
53
|
print("=" * 50)
|
47
54
|
print("🎉 Demo completed successfully!")
|
@@ -53,6 +60,7 @@ def run_demo():
|
|
53
60
|
print(" • Check database: docker exec -it memra_postgres psql -U postgres -d local_workflow")
|
54
61
|
print(" • View data: SELECT * FROM invoices ORDER BY created_at DESC;")
|
55
62
|
print(" • Stop services: cd memra-ops && docker compose down")
|
63
|
+
print(" • Stop MCP server: pkill -f mcp_bridge_server.py")
|
56
64
|
print(" • Explore code: Check the extracted files in the demo directory")
|
57
65
|
else:
|
58
66
|
print("❌ Demo failed. Check the logs above for details.")
|
@@ -158,36 +166,132 @@ import asyncio
|
|
158
166
|
import aiohttp
|
159
167
|
from aiohttp import web
|
160
168
|
import json
|
169
|
+
import psycopg2
|
170
|
+
import os
|
161
171
|
|
162
|
-
|
163
|
-
|
172
|
+
class MCPBridgeServer:
|
173
|
+
def __init__(self):
|
174
|
+
self.db_url = os.getenv('DATABASE_URL', 'postgresql://postgres:postgres@localhost:5432/local_workflow')
|
175
|
+
|
176
|
+
async def health_handler(self, request):
|
177
|
+
return web.json_response({"status": "healthy", "server": "MCP Bridge"})
|
178
|
+
|
179
|
+
async def execute_tool_handler(self, request):
|
180
|
+
try:
|
181
|
+
data = await request.json()
|
182
|
+
tool_name = data.get('tool_name', 'unknown')
|
183
|
+
tool_params = data.get('parameters', {})
|
184
|
+
|
185
|
+
if tool_name == 'SQLExecutor':
|
186
|
+
return await self.execute_sql(tool_params)
|
187
|
+
elif tool_name == 'PostgresInsert':
|
188
|
+
return await self.insert_data(tool_params)
|
189
|
+
elif tool_name == 'DataValidator':
|
190
|
+
return await self.validate_data(tool_params)
|
191
|
+
else:
|
192
|
+
return web.json_response({
|
193
|
+
"success": True,
|
194
|
+
"message": f"Demo {tool_name} executed",
|
195
|
+
"data": {"demo": True}
|
196
|
+
})
|
197
|
+
except Exception as e:
|
198
|
+
return web.json_response({
|
199
|
+
"success": False,
|
200
|
+
"error": str(e)
|
201
|
+
}, status=500)
|
202
|
+
|
203
|
+
async def execute_sql(self, params):
|
204
|
+
try:
|
205
|
+
query = params.get('query', 'SELECT 1')
|
206
|
+
conn = psycopg2.connect(self.db_url)
|
207
|
+
cursor = conn.cursor()
|
208
|
+
cursor.execute(query)
|
209
|
+
results = cursor.fetchall()
|
210
|
+
cursor.close()
|
211
|
+
conn.close()
|
212
|
+
|
213
|
+
return web.json_response({
|
214
|
+
"success": True,
|
215
|
+
"results": results,
|
216
|
+
"query": query
|
217
|
+
})
|
218
|
+
except Exception as e:
|
219
|
+
return web.json_response({
|
220
|
+
"success": False,
|
221
|
+
"error": f"SQL execution failed: {str(e)}"
|
222
|
+
}, status=500)
|
223
|
+
|
224
|
+
async def insert_data(self, params):
|
225
|
+
try:
|
226
|
+
table_name = params.get('table_name', 'invoices')
|
227
|
+
data = params.get('data', {})
|
228
|
+
|
229
|
+
conn = psycopg2.connect(self.db_url)
|
230
|
+
cursor = conn.cursor()
|
231
|
+
|
232
|
+
# Simple insert logic
|
233
|
+
columns = list(data.keys())
|
234
|
+
values = list(data.values())
|
235
|
+
placeholders = ', '.join(['%s'] * len(values))
|
236
|
+
column_list = ', '.join(columns)
|
237
|
+
|
238
|
+
query = f"INSERT INTO {table_name} ({column_list}) VALUES ({placeholders}) RETURNING id"
|
239
|
+
cursor.execute(query, values)
|
240
|
+
record_id = cursor.fetchone()[0]
|
241
|
+
|
242
|
+
conn.commit()
|
243
|
+
cursor.close()
|
244
|
+
conn.close()
|
245
|
+
|
246
|
+
return web.json_response({
|
247
|
+
"success": True,
|
248
|
+
"record_id": record_id,
|
249
|
+
"message": f"Inserted into {table_name}"
|
250
|
+
})
|
251
|
+
except Exception as e:
|
252
|
+
return web.json_response({
|
253
|
+
"success": False,
|
254
|
+
"error": f"Insert failed: {str(e)}"
|
255
|
+
}, status=500)
|
256
|
+
|
257
|
+
async def validate_data(self, params):
|
258
|
+
try:
|
259
|
+
data = params.get('data', {})
|
260
|
+
|
261
|
+
# Simple validation
|
262
|
+
is_valid = True
|
263
|
+
errors = []
|
264
|
+
|
265
|
+
if not data.get('vendor_name'):
|
266
|
+
is_valid = False
|
267
|
+
errors.append("Missing vendor name")
|
268
|
+
|
269
|
+
if not data.get('amount') or float(data.get('amount', 0)) <= 0:
|
270
|
+
is_valid = False
|
271
|
+
errors.append("Invalid amount")
|
272
|
+
|
273
|
+
return web.json_response({
|
274
|
+
"success": True,
|
275
|
+
"is_valid": is_valid,
|
276
|
+
"errors": errors,
|
277
|
+
"validated_data": data
|
278
|
+
})
|
279
|
+
except Exception as e:
|
280
|
+
return web.json_response({
|
281
|
+
"success": False,
|
282
|
+
"error": f"Validation failed: {str(e)}"
|
283
|
+
}, status=500)
|
164
284
|
|
165
|
-
|
166
|
-
|
167
|
-
tool_name = data.get('tool_name', 'unknown')
|
168
|
-
|
169
|
-
# Mock responses for demo
|
170
|
-
if tool_name == 'SQLExecutor':
|
171
|
-
return web.json_response({
|
172
|
-
"success": True,
|
173
|
-
"results": [{"message": "Demo SQL executed"}]
|
174
|
-
})
|
175
|
-
elif tool_name == 'PostgresInsert':
|
176
|
-
return web.json_response({
|
177
|
-
"success": True,
|
178
|
-
"id": 1
|
179
|
-
})
|
180
|
-
else:
|
181
|
-
return web.json_response({
|
182
|
-
"success": True,
|
183
|
-
"message": f"Demo {tool_name} executed"
|
184
|
-
})
|
285
|
+
# Create server instance
|
286
|
+
server = MCPBridgeServer()
|
185
287
|
|
288
|
+
# Create web application
|
186
289
|
app = web.Application()
|
187
|
-
app.router.add_get('/health', health_handler)
|
188
|
-
app.router.add_post('/execute_tool', execute_tool_handler)
|
290
|
+
app.router.add_get('/health', server.health_handler)
|
291
|
+
app.router.add_post('/execute_tool', server.execute_tool_handler)
|
189
292
|
|
190
293
|
if __name__ == '__main__':
|
294
|
+
print("🚀 Starting MCP Bridge Server on port 8081...")
|
191
295
|
web.run_app(app, host='0.0.0.0', port=8081)
|
192
296
|
"""
|
193
297
|
|
@@ -232,36 +336,132 @@ import asyncio
|
|
232
336
|
import aiohttp
|
233
337
|
from aiohttp import web
|
234
338
|
import json
|
339
|
+
import psycopg2
|
340
|
+
import os
|
235
341
|
|
236
|
-
|
237
|
-
|
342
|
+
class MCPBridgeServer:
|
343
|
+
def __init__(self):
|
344
|
+
self.db_url = os.getenv('DATABASE_URL', 'postgresql://postgres:postgres@localhost:5432/local_workflow')
|
345
|
+
|
346
|
+
async def health_handler(self, request):
|
347
|
+
return web.json_response({"status": "healthy", "server": "MCP Bridge"})
|
348
|
+
|
349
|
+
async def execute_tool_handler(self, request):
|
350
|
+
try:
|
351
|
+
data = await request.json()
|
352
|
+
tool_name = data.get('tool_name', 'unknown')
|
353
|
+
tool_params = data.get('parameters', {})
|
354
|
+
|
355
|
+
if tool_name == 'SQLExecutor':
|
356
|
+
return await self.execute_sql(tool_params)
|
357
|
+
elif tool_name == 'PostgresInsert':
|
358
|
+
return await self.insert_data(tool_params)
|
359
|
+
elif tool_name == 'DataValidator':
|
360
|
+
return await self.validate_data(tool_params)
|
361
|
+
else:
|
362
|
+
return web.json_response({
|
363
|
+
"success": True,
|
364
|
+
"message": f"Demo {tool_name} executed",
|
365
|
+
"data": {"demo": True}
|
366
|
+
})
|
367
|
+
except Exception as e:
|
368
|
+
return web.json_response({
|
369
|
+
"success": False,
|
370
|
+
"error": str(e)
|
371
|
+
}, status=500)
|
372
|
+
|
373
|
+
async def execute_sql(self, params):
|
374
|
+
try:
|
375
|
+
query = params.get('query', 'SELECT 1')
|
376
|
+
conn = psycopg2.connect(self.db_url)
|
377
|
+
cursor = conn.cursor()
|
378
|
+
cursor.execute(query)
|
379
|
+
results = cursor.fetchall()
|
380
|
+
cursor.close()
|
381
|
+
conn.close()
|
382
|
+
|
383
|
+
return web.json_response({
|
384
|
+
"success": True,
|
385
|
+
"results": results,
|
386
|
+
"query": query
|
387
|
+
})
|
388
|
+
except Exception as e:
|
389
|
+
return web.json_response({
|
390
|
+
"success": False,
|
391
|
+
"error": f"SQL execution failed: {str(e)}"
|
392
|
+
}, status=500)
|
393
|
+
|
394
|
+
async def insert_data(self, params):
|
395
|
+
try:
|
396
|
+
table_name = params.get('table_name', 'invoices')
|
397
|
+
data = params.get('data', {})
|
398
|
+
|
399
|
+
conn = psycopg2.connect(self.db_url)
|
400
|
+
cursor = conn.cursor()
|
401
|
+
|
402
|
+
# Simple insert logic
|
403
|
+
columns = list(data.keys())
|
404
|
+
values = list(data.values())
|
405
|
+
placeholders = ', '.join(['%s'] * len(values))
|
406
|
+
column_list = ', '.join(columns)
|
407
|
+
|
408
|
+
query = f"INSERT INTO {table_name} ({column_list}) VALUES ({placeholders}) RETURNING id"
|
409
|
+
cursor.execute(query, values)
|
410
|
+
record_id = cursor.fetchone()[0]
|
411
|
+
|
412
|
+
conn.commit()
|
413
|
+
cursor.close()
|
414
|
+
conn.close()
|
415
|
+
|
416
|
+
return web.json_response({
|
417
|
+
"success": True,
|
418
|
+
"record_id": record_id,
|
419
|
+
"message": f"Inserted into {table_name}"
|
420
|
+
})
|
421
|
+
except Exception as e:
|
422
|
+
return web.json_response({
|
423
|
+
"success": False,
|
424
|
+
"error": f"Insert failed: {str(e)}"
|
425
|
+
}, status=500)
|
426
|
+
|
427
|
+
async def validate_data(self, params):
|
428
|
+
try:
|
429
|
+
data = params.get('data', {})
|
430
|
+
|
431
|
+
# Simple validation
|
432
|
+
is_valid = True
|
433
|
+
errors = []
|
434
|
+
|
435
|
+
if not data.get('vendor_name'):
|
436
|
+
is_valid = False
|
437
|
+
errors.append("Missing vendor name")
|
438
|
+
|
439
|
+
if not data.get('amount') or float(data.get('amount', 0)) <= 0:
|
440
|
+
is_valid = False
|
441
|
+
errors.append("Invalid amount")
|
442
|
+
|
443
|
+
return web.json_response({
|
444
|
+
"success": True,
|
445
|
+
"is_valid": is_valid,
|
446
|
+
"errors": errors,
|
447
|
+
"validated_data": data
|
448
|
+
})
|
449
|
+
except Exception as e:
|
450
|
+
return web.json_response({
|
451
|
+
"success": False,
|
452
|
+
"error": f"Validation failed: {str(e)}"
|
453
|
+
}, status=500)
|
238
454
|
|
239
|
-
|
240
|
-
|
241
|
-
tool_name = data.get('tool_name', 'unknown')
|
242
|
-
|
243
|
-
# Mock responses for demo
|
244
|
-
if tool_name == 'SQLExecutor':
|
245
|
-
return web.json_response({
|
246
|
-
"success": True,
|
247
|
-
"results": [{"message": "Demo SQL executed"}]
|
248
|
-
})
|
249
|
-
elif tool_name == 'PostgresInsert':
|
250
|
-
return web.json_response({
|
251
|
-
"success": True,
|
252
|
-
"id": 1
|
253
|
-
})
|
254
|
-
else:
|
255
|
-
return web.json_response({
|
256
|
-
"success": True,
|
257
|
-
"message": f"Demo {tool_name} executed"
|
258
|
-
})
|
455
|
+
# Create server instance
|
456
|
+
server = MCPBridgeServer()
|
259
457
|
|
458
|
+
# Create web application
|
260
459
|
app = web.Application()
|
261
|
-
app.router.add_get('/health', health_handler)
|
262
|
-
app.router.add_post('/execute_tool', execute_tool_handler)
|
460
|
+
app.router.add_get('/health', server.health_handler)
|
461
|
+
app.router.add_post('/execute_tool', server.execute_tool_handler)
|
263
462
|
|
264
463
|
if __name__ == '__main__':
|
464
|
+
print("🚀 Starting MCP Bridge Server on port 8081...")
|
265
465
|
web.run_app(app, host='0.0.0.0', port=8081)
|
266
466
|
"""
|
267
467
|
|
@@ -498,8 +698,32 @@ def run_etl_workflow(demo_dir):
|
|
498
698
|
real_demo_script = demo_dir / "etl_invoice_demo.py"
|
499
699
|
if real_demo_script.exists():
|
500
700
|
print("🎯 Running real ETL workflow...")
|
701
|
+
print(f"📁 Working directory: {demo_dir}")
|
702
|
+
print(f"📄 Demo script: {real_demo_script}")
|
703
|
+
|
704
|
+
# Check if data directory exists
|
705
|
+
data_dir = demo_dir / "data"
|
706
|
+
invoices_dir = data_dir / "invoices"
|
707
|
+
if invoices_dir.exists():
|
708
|
+
pdf_files = list(invoices_dir.glob("*.PDF"))
|
709
|
+
print(f"📊 Found {len(pdf_files)} PDF files in {invoices_dir}")
|
710
|
+
if pdf_files:
|
711
|
+
print(f" First few files: {[f.name for f in pdf_files[:3]]}")
|
712
|
+
else:
|
713
|
+
print(f"⚠️ Warning: {invoices_dir} does not exist")
|
714
|
+
print(f" Available directories in {demo_dir}:")
|
715
|
+
for item in demo_dir.iterdir():
|
716
|
+
if item.is_dir():
|
717
|
+
print(f" - {item.name}/")
|
718
|
+
|
501
719
|
print("⏱️ Processing 15 files with delays - this may take 10-15 minutes")
|
502
|
-
|
720
|
+
|
721
|
+
# Set the working directory to the demo directory so the script can find data/invoices/
|
722
|
+
result = subprocess.run(
|
723
|
+
[sys.executable, str(real_demo_script)],
|
724
|
+
cwd=demo_dir, # This is crucial - sets working directory
|
725
|
+
timeout=1800 # 30 minute timeout
|
726
|
+
)
|
503
727
|
return result.returncode == 0
|
504
728
|
else:
|
505
729
|
# Fallback to simplified demo
|
@@ -510,6 +734,10 @@ def run_etl_workflow(demo_dir):
|
|
510
734
|
return result.returncode == 0
|
511
735
|
else:
|
512
736
|
print("❌ No demo script found")
|
737
|
+
print(f" Looking for: {real_demo_script}")
|
738
|
+
print(f" Available files in {demo_dir}:")
|
739
|
+
for item in demo_dir.iterdir():
|
740
|
+
print(f" - {item.name}")
|
513
741
|
return False
|
514
742
|
|
515
743
|
except subprocess.TimeoutExpired:
|
@@ -520,6 +748,49 @@ def run_etl_workflow(demo_dir):
|
|
520
748
|
print(f"❌ Error running ETL workflow: {e}")
|
521
749
|
return False
|
522
750
|
|
751
|
+
def start_mcp_bridge_server(demo_dir):
|
752
|
+
"""Start the MCP bridge server"""
|
753
|
+
try:
|
754
|
+
ops_dir = demo_dir / "memra-ops"
|
755
|
+
bridge_script = ops_dir / "mcp_bridge_server.py"
|
756
|
+
|
757
|
+
if not bridge_script.exists():
|
758
|
+
print("❌ MCP bridge server script not found")
|
759
|
+
return False
|
760
|
+
|
761
|
+
# Start the bridge server in the background
|
762
|
+
if os.name == 'nt': # Windows
|
763
|
+
# Use start command to run in background
|
764
|
+
result = subprocess.run([
|
765
|
+
'start', '/B', 'python', str(bridge_script)
|
766
|
+
], cwd=ops_dir, shell=True, capture_output=True, text=True)
|
767
|
+
else: # Unix/Linux/Mac
|
768
|
+
result = subprocess.run([
|
769
|
+
'python', str(bridge_script)
|
770
|
+
], cwd=ops_dir, start_new_session=True, capture_output=True, text=True)
|
771
|
+
|
772
|
+
# Wait a moment for the server to start
|
773
|
+
time.sleep(3)
|
774
|
+
|
775
|
+
# Check if the server is responding
|
776
|
+
try:
|
777
|
+
import requests
|
778
|
+
response = requests.get('http://localhost:8081/health', timeout=5)
|
779
|
+
if response.status_code == 200:
|
780
|
+
print("✅ MCP bridge server started successfully")
|
781
|
+
return True
|
782
|
+
else:
|
783
|
+
print(f"⚠️ MCP bridge server responded with status {response.status_code}")
|
784
|
+
return False
|
785
|
+
except Exception as e:
|
786
|
+
print(f"⚠️ Could not verify MCP bridge server: {e}")
|
787
|
+
print(" Server may still be starting up...")
|
788
|
+
return True # Assume it's working
|
789
|
+
|
790
|
+
except Exception as e:
|
791
|
+
print(f"❌ Error starting MCP bridge server: {e}")
|
792
|
+
return False
|
793
|
+
|
523
794
|
def main():
|
524
795
|
"""Main CLI entry point"""
|
525
796
|
if len(sys.argv) < 2:
|
@@ -1,5 +1,5 @@
|
|
1
1
|
memra/__init__.py,sha256=6i82jodsWZPgtRhUaDF3wuQuRDSaboIpew8D3zDN__s,1109
|
2
|
-
memra/cli.py,sha256=
|
2
|
+
memra/cli.py,sha256=_IlOrTBlv_zBElxxQs13JYsdAuOn9wO1UiogmnwO1Qg,29430
|
3
3
|
memra/discovery.py,sha256=yJIQnrDQu1nyzKykCIuzG_5SW5dIXHCEBLLKRWacIoY,480
|
4
4
|
memra/discovery_client.py,sha256=AbnKn6qhyrf7vmOvknEeDzH4tiGHsqPHtDaein_qaW0,1271
|
5
5
|
memra/execution.py,sha256=OXpBKxwBIjhACWL_qh8KHNndO8HUgB6gBF81AiQBBm0,34751
|
@@ -58,63 +58,9 @@ memra/demos/etl_invoice_processing/data/invoices/10352262702.PDF,sha256=aNWnxbYq
|
|
58
58
|
memra/demos/etl_invoice_processing/data/invoices/10352262884.PDF,sha256=G0eszEhpTOS15hIlMyPMM6iyVw6UZPKycXvS3P42xRc,1010830
|
59
59
|
memra/demos/etl_invoice_processing/data/invoices/10352263346.PDF,sha256=NMfsgrmaNtvNu6xk2aLtubI05I9cuVIbwJMxv_pYPhQ,1089624
|
60
60
|
memra/demos/etl_invoice_processing/data/invoices/10352263429.PDF,sha256=1IzJbmnsKDE1cV6CtyNMENn0Rmpq2tA_BDnZYTYhNhQ,1082893
|
61
|
-
memra-
|
62
|
-
memra-
|
63
|
-
memra-
|
64
|
-
memra-
|
65
|
-
memra-
|
66
|
-
memra-
|
67
|
-
memra-ops/logic/file_tools.py,sha256=iVe4xE7lNBhhoiL0Hi2zx4oF7koDeVvsOh1uMbn6HEo,1126
|
68
|
-
memra-ops/logic/invoice_tools.py,sha256=Jp3PEFfUXRTAAP1ZM4Juei_zzPKy8EFi8H2uP6T9c2A,27787
|
69
|
-
memra-ops/logic/invoice_tools_fix.py,sha256=sF4qADqbfWEgOyavslrNlCDEyIkaZo35TtnyHd7PClY,3020
|
70
|
-
memra-ops/scripts/check_database.py,sha256=sBPmIJ10WW3jHQfOjeDRJnQahRBwVAi60-98r4HG9rw,987
|
71
|
-
memra-ops/scripts/clear_database.py,sha256=yO4JUbMOcSQ1-S57n1oua-SheM360yg-oNiPyj8LW5o,1441
|
72
|
-
memra-ops/scripts/monitor_database.py,sha256=OmIgUmtVjtUfSziSEiTy5CheueMMZ5R5HciPpMishE0,2287
|
73
|
-
memra-ops/scripts/release.py,sha256=riQ-jz7-vnd1cSfQdU1eUZmVDyuWym1nmZW65lGetiI,4218
|
74
|
-
memra-ops/scripts/reset_database.py,sha256=QJagPQIkMOr3s-o-g_Urz0CvSYNm0D2xbwo3JSrKIWY,2255
|
75
|
-
memra-ops/scripts/start_memra.py,sha256=VR7WESQXgvPuzZEFMhtmABSR7IzYixsnpgtoPcECLK0,11987
|
76
|
-
memra-ops/scripts/stop_memra.py,sha256=yyTu4jxjUbxTrvobQ-UhpNk-eWB8bCFjcBPGW1scIJg,4591
|
77
|
-
memra-ops/tests/test_llm_text_to_sql.py,sha256=IDL7FEzlm2Dr9pRCcJQ6SGddF9VBDfHonwztrDpxBGU,4099
|
78
|
-
memra-ops/tests/test_llm_vs_pattern.py,sha256=ZATV1fS7C6Jn-N4-UB5LzuRjbiO1ctZq3gNoIud2RWc,4880
|
79
|
-
memra-ops/tests/test_mcp_schema_aware.py,sha256=H5NmGxS3LWo9xoodqVeliJyHco7ZjGOtHg80ep1SHzw,4537
|
80
|
-
memra-ops/tests/test_schema_aware_sql.py,sha256=b_XPtv7eldR2ARBVlriTHMA1nwqYUcMgthL8mHpewuM,4645
|
81
|
-
memra-ops/tests/test_schema_aware_sql_simple.py,sha256=8f8zijkTwvIqVHM3B5oVviRfFS-U6bfC43fk9hcWsoE,2309
|
82
|
-
memra-ops/tests/test_text_to_sql_demo.py,sha256=5mmpSwXZ8r8sj3J9iCYkFx0SgwyXPe-7Prie1hL6cis,5092
|
83
|
-
memra-ops/tools/mcp_bridge_server.py,sha256=IKUNusZovPdR0_6Bv_XejmAk27lnHrM1uOE8xPVnM8s,35051
|
84
|
-
memra-sdk/setup.py,sha256=j95Pq2ha28B3owPv0J1isq5pgUwa9p02nbBXqxa4Lwo,1513
|
85
|
-
memra-sdk/examples/accounts_payable.py,sha256=PfpXKrGOUu6NpkNcHy6cN6TtsXfnsJZhUv-KGlOvDqY,7990
|
86
|
-
memra-sdk/examples/accounts_payable_client.py,sha256=tLHHCydEpasLHTHd4YULhSxFy6zs81X5PZHav0dlQ2I,7816
|
87
|
-
memra-sdk/examples/accounts_payable_mcp.py,sha256=lOgwDfMVKxifQi70GmeXQnpZiIFrZnNj5_JSZ9qsdBw,7344
|
88
|
-
memra-sdk/examples/ask_questions.py,sha256=jek7EVXXZ_vODlMy_hQGQCkN9vYBfaW7SOWsIQRV2GY,3830
|
89
|
-
memra-sdk/examples/invoice_processing.py,sha256=STe3ri65WH_Ss84qiRWuGZTpDZke5GoJf8LEqOAc5ys,3980
|
90
|
-
memra-sdk/examples/propane_delivery.py,sha256=ryvIxDjM9GJY9T6fFIqJgHOcX2PEMkfF_t_3E5CyZW4,2539
|
91
|
-
memra-sdk/examples/simple_text_to_sql.py,sha256=NnpKo9nFpmPQ089zcSx4wwG6_tSHTmGJSS7LPs55NA0,5314
|
92
|
-
memra-sdk/memra/__init__.py,sha256=CTiSeBBZ40-pNd2-wBIdZduqNLrA5OnWmmwk1y1f894,787
|
93
|
-
memra-sdk/memra/discovery.py,sha256=yJIQnrDQu1nyzKykCIuzG_5SW5dIXHCEBLLKRWacIoY,480
|
94
|
-
memra-sdk/memra/discovery_client.py,sha256=AbnKn6qhyrf7vmOvknEeDzH4tiGHsqPHtDaein_qaW0,1271
|
95
|
-
memra-sdk/memra/execution.py,sha256=P7tAur0SEMtX6uLlfxTfCZBgMLIRj6Wl3dsv2EA9fHc,23443
|
96
|
-
memra-sdk/memra/models.py,sha256=sXMPRnMB_mUVtJdBFyd0ElCf_uh1yqx7iLssIYNm0vI,3333
|
97
|
-
memra-sdk/memra/tool_registry.py,sha256=P2TafpiqV19yzi0jVrQQrXFGBpQkbmePbRfEW_ai24M,14700
|
98
|
-
memra-sdk/memra/tool_registry_client.py,sha256=uzMQ4COvRams9vuPLcqcdljUpDlAYU_tyFxrRhrA0Lc,4009
|
99
|
-
memra-sdk/scripts/release.py,sha256=riQ-jz7-vnd1cSfQdU1eUZmVDyuWym1nmZW65lGetiI,4218
|
100
|
-
memra-workflows/mcp_bridge_server.py,sha256=6K9fedZiwNpkT7wGAS6IW-HgMYBUC94zu8ppUgftqDg,8528
|
101
|
-
memra-workflows/accounts_payable/accounts_payable.py,sha256=rRpviqKZ-g0KPEnI98GbXy-KnyTrN1dLkj0HP9PKlYs,8012
|
102
|
-
memra-workflows/accounts_payable/accounts_payable_client.py,sha256=kNu2EQ8d6T6qcKn68FznnMGBeoqtXFbN4PHDVDImapk,7813
|
103
|
-
memra-workflows/accounts_payable/accounts_payable_mcp.py,sha256=kySt7PKyIgLbG1Q3jPY1kFPQK8o_3aAmL9vJG2Qcnxc,7366
|
104
|
-
memra-workflows/accounts_payable/accounts_payable_smart.py,sha256=g_V6-1qPsLiIOFw-eLT4w-RoljjErF65SuKRzkEeSck,8004
|
105
|
-
memra-workflows/invoice_processing/invoice_processing.py,sha256=STe3ri65WH_Ss84qiRWuGZTpDZke5GoJf8LEqOAc5ys,3980
|
106
|
-
memra-workflows/invoice_processing/smart_invoice_processor.py,sha256=Ct3ZjNujK4VTlCDgwMWXn6Y7b1dg0a_eIbRP-xm-p3g,7203
|
107
|
-
memra-workflows/logic/__init__.py,sha256=kLTdniFpBqOusmRng8W2LSIAmgj-jfM3Agjl_vXYTl8,76
|
108
|
-
memra-workflows/logic/file_tools.py,sha256=n6uDwInPZcr74zAJJbA9iZajWgRcKoHYtEKX_lbzsik,1586
|
109
|
-
memra-workflows/logic/invoice_tools.py,sha256=wLTI0JqkMYMlFv1z_DPwliIvKbpFBcYh5SnEnhU13Co,20366
|
110
|
-
memra-workflows/logic/propane_agents.py,sha256=ZF1RSccn73a5XZVa-1nxgjvubcYzf62g9lr9PoTbGl4,1804
|
111
|
-
memra-workflows/propane_delivery/propane_delivery.py,sha256=ryvIxDjM9GJY9T6fFIqJgHOcX2PEMkfF_t_3E5CyZW4,2539
|
112
|
-
memra-workflows/text_to_sql/complete_invoice_workflow_with_queries.py,sha256=x4wq3o_ogFnnrI6MQwEhqIiNH-NNwS5SXQUoKd_br7U,7428
|
113
|
-
memra-workflows/text_to_sql/complete_text_to_sql_system.py,sha256=Izj4ucXDXTWFY29SWr2YrEf3ZyXH4QCDEljNk4jlpI0,8991
|
114
|
-
memra-workflows/text_to_sql/file_discovery_demo.py,sha256=4R_QN0Y6OtHmnX6CvtwDXen122XCDrk-MRBOzxb_x_k,5306
|
115
|
-
memra-0.2.13.dist-info/LICENSE,sha256=8OrnTd8DWwLWmUEj5srSLvT4PREfW1Qo1T5gEUIHPws,1062
|
116
|
-
memra-0.2.13.dist-info/METADATA,sha256=KwY4StFLr17bUJ6eZ3eazCqwBZlVX7jBMzX_bB9iKxY,9427
|
117
|
-
memra-0.2.13.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
118
|
-
memra-0.2.13.dist-info/entry_points.txt,sha256=LBVjwWoxWJRzNLgeByPn6xUvWFIRnqnemvAZgIoSt08,41
|
119
|
-
memra-0.2.13.dist-info/top_level.txt,sha256=IviXF9qSQY_BidRYund9zFaV-q1VMl6CuizwTAggQks,42
|
120
|
-
memra-0.2.13.dist-info/RECORD,,
|
61
|
+
memra-0.2.15.dist-info/LICENSE,sha256=8OrnTd8DWwLWmUEj5srSLvT4PREfW1Qo1T5gEUIHPws,1062
|
62
|
+
memra-0.2.15.dist-info/METADATA,sha256=-a6F6PGuriDeFNJjtGn30f0XFdt64O1pmkZjKwvzCB8,9427
|
63
|
+
memra-0.2.15.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
64
|
+
memra-0.2.15.dist-info/entry_points.txt,sha256=LBVjwWoxWJRzNLgeByPn6xUvWFIRnqnemvAZgIoSt08,41
|
65
|
+
memra-0.2.15.dist-info/top_level.txt,sha256=pXWcTRS1zctdiSUivW4iyKpJ4tcfIu-1BW_fpbal3OY,6
|
66
|
+
memra-0.2.15.dist-info/RECORD,,
|
@@ -0,0 +1 @@
|
|
1
|
+
memra
|