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.
Files changed (62) hide show
  1. memra/cli.py +322 -51
  2. {memra-0.2.13.dist-info → memra-0.2.15.dist-info}/METADATA +1 -1
  3. {memra-0.2.13.dist-info → memra-0.2.15.dist-info}/RECORD +7 -61
  4. memra-0.2.15.dist-info/top_level.txt +1 -0
  5. memra-0.2.13.dist-info/top_level.txt +0 -4
  6. memra-ops/app.py +0 -808
  7. memra-ops/config/config.py +0 -25
  8. memra-ops/config.py +0 -34
  9. memra-ops/logic/__init__.py +0 -1
  10. memra-ops/logic/file_tools.py +0 -43
  11. memra-ops/logic/invoice_tools.py +0 -668
  12. memra-ops/logic/invoice_tools_fix.py +0 -66
  13. memra-ops/mcp_bridge_server.py +0 -1178
  14. memra-ops/scripts/check_database.py +0 -37
  15. memra-ops/scripts/clear_database.py +0 -48
  16. memra-ops/scripts/monitor_database.py +0 -67
  17. memra-ops/scripts/release.py +0 -133
  18. memra-ops/scripts/reset_database.py +0 -65
  19. memra-ops/scripts/start_memra.py +0 -334
  20. memra-ops/scripts/stop_memra.py +0 -132
  21. memra-ops/server_tool_registry.py +0 -190
  22. memra-ops/tests/test_llm_text_to_sql.py +0 -115
  23. memra-ops/tests/test_llm_vs_pattern.py +0 -130
  24. memra-ops/tests/test_mcp_schema_aware.py +0 -124
  25. memra-ops/tests/test_schema_aware_sql.py +0 -139
  26. memra-ops/tests/test_schema_aware_sql_simple.py +0 -66
  27. memra-ops/tests/test_text_to_sql_demo.py +0 -140
  28. memra-ops/tools/mcp_bridge_server.py +0 -851
  29. memra-sdk/examples/accounts_payable.py +0 -215
  30. memra-sdk/examples/accounts_payable_client.py +0 -217
  31. memra-sdk/examples/accounts_payable_mcp.py +0 -200
  32. memra-sdk/examples/ask_questions.py +0 -123
  33. memra-sdk/examples/invoice_processing.py +0 -116
  34. memra-sdk/examples/propane_delivery.py +0 -87
  35. memra-sdk/examples/simple_text_to_sql.py +0 -158
  36. memra-sdk/memra/__init__.py +0 -31
  37. memra-sdk/memra/discovery.py +0 -15
  38. memra-sdk/memra/discovery_client.py +0 -49
  39. memra-sdk/memra/execution.py +0 -481
  40. memra-sdk/memra/models.py +0 -99
  41. memra-sdk/memra/tool_registry.py +0 -343
  42. memra-sdk/memra/tool_registry_client.py +0 -106
  43. memra-sdk/scripts/release.py +0 -133
  44. memra-sdk/setup.py +0 -52
  45. memra-workflows/accounts_payable/accounts_payable.py +0 -215
  46. memra-workflows/accounts_payable/accounts_payable_client.py +0 -216
  47. memra-workflows/accounts_payable/accounts_payable_mcp.py +0 -200
  48. memra-workflows/accounts_payable/accounts_payable_smart.py +0 -221
  49. memra-workflows/invoice_processing/invoice_processing.py +0 -116
  50. memra-workflows/invoice_processing/smart_invoice_processor.py +0 -220
  51. memra-workflows/logic/__init__.py +0 -1
  52. memra-workflows/logic/file_tools.py +0 -50
  53. memra-workflows/logic/invoice_tools.py +0 -501
  54. memra-workflows/logic/propane_agents.py +0 -52
  55. memra-workflows/mcp_bridge_server.py +0 -230
  56. memra-workflows/propane_delivery/propane_delivery.py +0 -87
  57. memra-workflows/text_to_sql/complete_invoice_workflow_with_queries.py +0 -208
  58. memra-workflows/text_to_sql/complete_text_to_sql_system.py +0 -266
  59. memra-workflows/text_to_sql/file_discovery_demo.py +0 -156
  60. {memra-0.2.13.dist-info → memra-0.2.15.dist-info}/LICENSE +0 -0
  61. {memra-0.2.13.dist-info → memra-0.2.15.dist-info}/WHEEL +0 -0
  62. {memra-0.2.13.dist-info → memra-0.2.15.dist-info}/entry_points.txt +0 -0
@@ -1,266 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Complete Text-to-SQL System
4
- Demonstrates the full pipeline: English Question → Schema → SQL Generation → Execution → Real Results
5
- """
6
-
7
- import os
8
- import sys
9
- import json
10
- from pathlib import Path
11
-
12
- # Add the parent directory to the path so we can import memra
13
- sys.path.insert(0, str(Path(__file__).parent.parent))
14
-
15
- from memra import ExecutionEngine, Agent, Tool
16
-
17
- def create_text_to_sql_system():
18
- """Create a complete text-to-SQL system with real database integration"""
19
-
20
- # Initialize execution engine
21
- engine = ExecutionEngine()
22
-
23
- # Schema Extraction Agent
24
- schema_agent = Agent(
25
- role="Database Schema Analyst",
26
- job="Extract and analyze database schemas",
27
- output_key="schema_data",
28
- tools=[
29
- Tool(
30
- name="DatabaseQueryTool",
31
- hosted_by="memra",
32
- description="Query database schemas and structure"
33
- )
34
- ]
35
- )
36
-
37
- # SQL Generation Agent
38
- sql_generator_agent = Agent(
39
- role="SQL Generator",
40
- job="Convert natural language to SQL queries",
41
- output_key="generated_sql",
42
- tools=[
43
- Tool(
44
- name="TextToSQLGenerator",
45
- hosted_by="mcp",
46
- description="Generate SQL from natural language questions",
47
- config={
48
- "bridge_url": "http://localhost:8081",
49
- "bridge_secret": "test-secret-for-development"
50
- }
51
- )
52
- ]
53
- )
54
-
55
- # SQL Execution Agent
56
- sql_executor_agent = Agent(
57
- role="SQL Executor",
58
- job="Execute SQL queries and return results",
59
- output_key="query_results",
60
- tools=[
61
- Tool(
62
- name="SQLExecutor",
63
- hosted_by="mcp",
64
- description="Execute SQL queries against PostgreSQL database",
65
- config={
66
- "bridge_url": "http://localhost:8081",
67
- "bridge_secret": "test-secret-for-development"
68
- }
69
- )
70
- ]
71
- )
72
-
73
- return engine, schema_agent, sql_generator_agent, sql_executor_agent
74
-
75
- def extract_database_schema(engine, schema_agent):
76
- """Extract the database schema for context"""
77
- print("🔍 Extracting database schema...")
78
-
79
- schema_task = {
80
- "task": "Extract the complete schema for the invoices table including column names, types, and sample data",
81
- "table_name": "invoices",
82
- "include_sample_data": True
83
- }
84
-
85
- result = engine.execute_task(schema_agent, schema_task)
86
-
87
- if result.get("success"):
88
- print(f"✅ Schema extracted successfully ({result.get('execution_time', 0):.1f}s)")
89
- schema_data = result.get("result", {})
90
-
91
- # Display schema info
92
- if "schema" in schema_data:
93
- print("\n📊 Database Schema:")
94
- schema = schema_data["schema"]
95
- for table_name, table_info in schema.items():
96
- print(f" Table: {table_name}")
97
- if "columns" in table_info:
98
- for col in table_info["columns"]:
99
- print(f" - {col['name']} ({col['type']})")
100
-
101
- return schema_data
102
- else:
103
- print(f"❌ Schema extraction failed: {result.get('error', 'Unknown error')}")
104
- return {}
105
-
106
- def generate_sql_from_question(engine, sql_generator_agent, question, schema_info):
107
- """Generate SQL from natural language question"""
108
- print(f"\n🤖 Generating SQL for: '{question}'")
109
-
110
- sql_generation_task = {
111
- "question": question,
112
- "schema_info": schema_info,
113
- "context": "Generate SQL query for invoice database analysis"
114
- }
115
-
116
- result = engine.execute_task(sql_generator_agent, sql_generation_task)
117
-
118
- if result.get("success"):
119
- print(f"✅ SQL generated successfully ({result.get('execution_time', 0):.1f}s)")
120
- sql_data = result.get("result", {})
121
-
122
- generated_sql = sql_data.get("generated_sql", "")
123
- print(f"\n📝 Generated SQL:")
124
- print(f" {generated_sql}")
125
-
126
- return generated_sql
127
- else:
128
- print(f"❌ SQL generation failed: {result.get('error', 'Unknown error')}")
129
- return None
130
-
131
- def execute_sql_query(engine, sql_executor_agent, sql_query):
132
- """Execute the generated SQL query"""
133
- print(f"\n⚡ Executing SQL query...")
134
-
135
- execution_task = {
136
- "sql_query": sql_query,
137
- "timeout": 30
138
- }
139
-
140
- result = engine.execute_task(sql_executor_agent, execution_task)
141
-
142
- if result.get("success"):
143
- print(f"✅ SQL executed successfully ({result.get('execution_time', 0):.1f}s)")
144
- query_results = result.get("result", {})
145
-
146
- # Display results
147
- results = query_results.get("results", [])
148
- row_count = query_results.get("row_count", 0)
149
-
150
- print(f"\n📋 Query Results ({row_count} rows):")
151
- if results:
152
- # Display first few results
153
- for i, row in enumerate(results[:5]):
154
- print(f" Row {i+1}: {row}")
155
-
156
- if len(results) > 5:
157
- print(f" ... and {len(results) - 5} more rows")
158
- else:
159
- print(" No results found")
160
-
161
- return query_results
162
- else:
163
- print(f"❌ SQL execution failed: {result.get('error', 'Unknown error')}")
164
- return {}
165
-
166
- def run_text_to_sql_query(engine, schema_agent, sql_generator_agent, sql_executor_agent, question):
167
- """Run the complete text-to-SQL pipeline"""
168
- print(f"\n{'='*60}")
169
- print(f"🎯 Processing Question: {question}")
170
- print(f"{'='*60}")
171
-
172
- # Step 1: Extract schema (cached after first run)
173
- if not hasattr(run_text_to_sql_query, 'cached_schema'):
174
- run_text_to_sql_query.cached_schema = extract_database_schema(engine, schema_agent)
175
-
176
- schema_info = run_text_to_sql_query.cached_schema
177
-
178
- # Step 2: Generate SQL
179
- sql_query = generate_sql_from_question(engine, sql_generator_agent, question, schema_info)
180
-
181
- if not sql_query:
182
- return None
183
-
184
- # Step 3: Execute SQL
185
- results = execute_sql_query(engine, sql_executor_agent, sql_query)
186
-
187
- return {
188
- "question": question,
189
- "sql_query": sql_query,
190
- "results": results
191
- }
192
-
193
- def main():
194
- """Main function to demonstrate the complete text-to-SQL system"""
195
- print("🚀 Starting Complete Text-to-SQL System")
196
- print("=" * 60)
197
-
198
- # Create the system
199
- engine, schema_agent, sql_generator_agent, sql_executor_agent = create_text_to_sql_system()
200
-
201
- # Example questions to test
202
- test_questions = [
203
- "Show me all invoices from Air Liquide",
204
- "What is the total amount of all invoices?",
205
- "How many invoices do we have in the database?",
206
- "Show me the most recent 5 invoices",
207
- "What is the average invoice amount?",
208
- ]
209
-
210
- print("📝 Available test questions:")
211
- for i, question in enumerate(test_questions, 1):
212
- print(f" {i}. {question}")
213
-
214
- print("\n" + "="*60)
215
-
216
- # Interactive mode
217
- while True:
218
- print("\n🤔 What would you like to know about the invoices?")
219
- print(" (Enter a question, number 1-5 for examples, or 'quit' to exit)")
220
-
221
- user_input = input("\n❓ Your question: ").strip()
222
-
223
- if user_input.lower() in ['quit', 'exit', 'q']:
224
- print("\n👋 Goodbye!")
225
- break
226
-
227
- # Check if it's a number for example questions
228
- if user_input.isdigit():
229
- question_num = int(user_input)
230
- if 1 <= question_num <= len(test_questions):
231
- question = test_questions[question_num - 1]
232
- else:
233
- print(f"❌ Please enter a number between 1 and {len(test_questions)}")
234
- continue
235
- else:
236
- question = user_input
237
-
238
- if not question:
239
- print("❌ Please enter a question")
240
- continue
241
-
242
- # Run the complete pipeline
243
- try:
244
- result = run_text_to_sql_query(
245
- engine, schema_agent, sql_generator_agent, sql_executor_agent, question
246
- )
247
-
248
- if result:
249
- print(f"\n✨ Query completed successfully!")
250
-
251
- # Check if results are real or mock
252
- results_data = result.get("results", {})
253
- if results_data.get("_mock"):
254
- print("ℹ️ Note: Results are mocked (MCP bridge not fully connected)")
255
- else:
256
- print("🎉 Real database results!")
257
- else:
258
- print("❌ Query failed")
259
-
260
- except KeyboardInterrupt:
261
- print("\n\n⏹️ Query interrupted by user")
262
- except Exception as e:
263
- print(f"\n❌ Error: {str(e)}")
264
-
265
- if __name__ == "__main__":
266
- main()
@@ -1,156 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- File Discovery and Management Demo
4
- Simple demonstration of intelligent file discovery tools
5
- """
6
-
7
- import os
8
- import sys
9
- sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
10
-
11
- from memra import Agent, Department
12
- from memra.execution import ExecutionEngine
13
-
14
- # Set up environment
15
- os.environ['MEMRA_API_KEY'] = 'memra-prod-2024-001'
16
-
17
- def create_file_discovery_department():
18
- """Create a simple department for file discovery"""
19
- file_manager_agent = Agent(
20
- role="File Manager",
21
- job="Discover and manage files in directories",
22
- sops=[
23
- "Scan specified directory for files matching pattern",
24
- "List all discovered files with metadata",
25
- "Copy files from external locations to standard directories",
26
- "Provide file selection interface for multiple files"
27
- ],
28
- systems=["FileSystem"],
29
- tools=[
30
- {"name": "FileDiscovery", "hosted_by": "mcp"}
31
- ],
32
- input_keys=["directory", "pattern"],
33
- output_key="file_operations"
34
- )
35
-
36
- return Department(
37
- name="File Discovery",
38
- mission="Discover files in directories",
39
- agents=[file_manager_agent],
40
- workflow_order=["File Manager"],
41
- context={
42
- "mcp_bridge_url": "http://localhost:8081",
43
- "mcp_bridge_secret": "test-secret-for-development"
44
- }
45
- )
46
-
47
- def create_file_copy_department():
48
- """Create a simple department for file copying"""
49
- file_copy_agent = Agent(
50
- role="File Copier",
51
- job="Copy files from external locations to standard directories",
52
- sops=[
53
- "Accept source file path and destination directory",
54
- "Copy file to destination with proper naming",
55
- "Verify copy operation success",
56
- "Return copy confirmation with metadata"
57
- ],
58
- systems=["FileSystem"],
59
- tools=[
60
- {"name": "FileCopy", "hosted_by": "mcp"}
61
- ],
62
- input_keys=["source_path", "destination_dir"],
63
- output_key="file_operations"
64
- )
65
-
66
- return Department(
67
- name="File Copy",
68
- mission="Copy files to standard directories",
69
- agents=[file_copy_agent],
70
- workflow_order=["File Copier"],
71
- context={
72
- "mcp_bridge_url": "http://localhost:8081",
73
- "mcp_bridge_secret": "test-secret-for-development"
74
- }
75
- )
76
-
77
- def main():
78
- print("📁 File Discovery and Management Demo")
79
- print("=" * 50)
80
-
81
- engine = ExecutionEngine()
82
-
83
- # Demo 1: Discover files in invoices directory
84
- print("\n🔍 Demo 1: Discover files in invoices/ directory")
85
-
86
- discovery_dept = create_file_discovery_department()
87
- discovery_input = {
88
- "directory": "invoices",
89
- "pattern": "*.pdf"
90
- }
91
-
92
- result = engine.execute_department(discovery_dept, discovery_input)
93
-
94
- if result.success:
95
- print("✅ File discovery completed!")
96
- file_data = result.data.get('file_operations', {})
97
-
98
- if 'files' in file_data:
99
- print(f"\n📄 Found {file_data['files_found']} files:")
100
- for file_info in file_data['files']:
101
- print(f" • {file_info['filename']} ({file_info['size']}) - {file_info['modified']}")
102
- else:
103
- print(f"📊 Scanned: {file_data.get('directory', 'unknown')} directory")
104
- print(f"🔍 Pattern: {file_data.get('pattern', 'unknown')}")
105
- print(f"📁 Files found: {file_data.get('files_found', 0)}")
106
- else:
107
- print(f"❌ Discovery failed: {result.error}")
108
-
109
- print("\n" + "="*50)
110
-
111
- # Demo 2: Copy external file
112
- print("\n📋 Demo 2: Copy external file to invoices/ directory")
113
-
114
- copy_dept = create_file_copy_department()
115
- copy_input = {
116
- "source_path": "/Users/tarpus/Downloads/new_invoice.pdf",
117
- "destination_dir": "invoices"
118
- }
119
-
120
- result = engine.execute_department(copy_dept, copy_input)
121
-
122
- if result.success:
123
- print("✅ File copy completed!")
124
- copy_data = result.data.get('file_operations', {})
125
-
126
- print(f"\n📁 Copy Details:")
127
- print(f" Source: {copy_data.get('source_path', 'unknown')}")
128
- print(f" Destination: {copy_data.get('destination_path', 'unknown')}")
129
- print(f" Size: {copy_data.get('file_size', 'unknown')}")
130
- print(f" Status: {copy_data.get('message', 'unknown')}")
131
- else:
132
- print(f"❌ Copy failed: {result.error}")
133
-
134
- print("\n" + "="*50)
135
-
136
- # Demo 3: Discover files in different directory
137
- print("\n🗂 Demo 3: Discover files in documents/ directory")
138
-
139
- docs_input = {
140
- "directory": "documents",
141
- "pattern": "*.*"
142
- }
143
-
144
- result = engine.execute_department(discovery_dept, docs_input)
145
-
146
- if result.success:
147
- print("✅ Document discovery completed!")
148
- doc_data = result.data.get('file_operations', {})
149
- print(f"📊 Scanned: {doc_data.get('directory', 'unknown')} directory")
150
- print(f"🔍 Pattern: {doc_data.get('pattern', 'unknown')}")
151
- print(f"📁 Files found: {doc_data.get('files_found', 0)}")
152
- else:
153
- print(f"❌ Document discovery failed: {result.error}")
154
-
155
- if __name__ == "__main__":
156
- main()
File without changes