memra 0.2.4__py3-none-any.whl → 0.2.5__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.
@@ -0,0 +1,37 @@
1
+ import psycopg2
2
+ from prettytable import PrettyTable
3
+ import time
4
+
5
+ def check_database():
6
+ # Connect to the Postgres database
7
+ conn = psycopg2.connect(
8
+ dbname="memra_invoice_db",
9
+ user="memra", # From docker-compose.yml
10
+ password="memra123", # From docker-compose.yml
11
+ host="localhost",
12
+ port=5432
13
+ )
14
+
15
+ # Create a cursor and run the query
16
+ cur = conn.cursor()
17
+ cur.execute("SELECT * FROM invoices ORDER BY created_at DESC LIMIT 10;")
18
+ rows = cur.fetchall()
19
+ columns = [desc[0] for desc in cur.description]
20
+
21
+ # Create and populate the pretty table
22
+ table = PrettyTable()
23
+ table.field_names = columns
24
+ for row in rows:
25
+ table.add_row(row)
26
+
27
+ # Print the table
28
+ print(f"\n📊 Current invoices in database (as of {time.strftime('%H:%M:%S')}):")
29
+ print(table)
30
+ print(f"Total rows: {len(rows)}")
31
+
32
+ # Clean up
33
+ cur.close()
34
+ conn.close()
35
+
36
+ if __name__ == "__main__":
37
+ check_database()
@@ -0,0 +1,48 @@
1
+ import psycopg2
2
+
3
+ def clear_database():
4
+ """Clear all data from the invoices table"""
5
+
6
+ # Connect to the Postgres database
7
+ conn = psycopg2.connect(
8
+ dbname="memra_invoice_db",
9
+ user="memra", # From docker-compose.yml
10
+ password="memra123", # From docker-compose.yml
11
+ host="localhost",
12
+ port=5432
13
+ )
14
+
15
+ try:
16
+ # Create a cursor and run the query
17
+ cur = conn.cursor()
18
+
19
+ # First, let's see how many rows we have
20
+ cur.execute("SELECT COUNT(*) FROM invoices;")
21
+ count_before = cur.fetchone()[0]
22
+ print(f"📊 Current invoice count: {count_before}")
23
+
24
+ if count_before > 0:
25
+ # Clear all data from the invoices table
26
+ cur.execute("DELETE FROM invoices;")
27
+ conn.commit()
28
+
29
+ # Verify the deletion
30
+ cur.execute("SELECT COUNT(*) FROM invoices;")
31
+ count_after = cur.fetchone()[0]
32
+
33
+ print(f"🗑️ Deleted {count_before} invoice records")
34
+ print(f"📊 New invoice count: {count_after}")
35
+ print("✅ Database cleared successfully!")
36
+ else:
37
+ print("📊 Database is already empty")
38
+
39
+ cur.close()
40
+
41
+ except Exception as e:
42
+ print(f"❌ Error: {e}")
43
+ conn.rollback()
44
+ finally:
45
+ conn.close()
46
+
47
+ if __name__ == "__main__":
48
+ clear_database()
@@ -0,0 +1,67 @@
1
+ import psycopg2
2
+ from prettytable import PrettyTable
3
+ import time
4
+ import os
5
+
6
+ def monitor_database():
7
+ """Continuously monitor the database for new invoice rows"""
8
+
9
+ # Connect to the Postgres database
10
+ conn = psycopg2.connect(
11
+ dbname="memra_invoice_db",
12
+ user="memra", # From docker-compose.yml
13
+ password="memra123", # From docker-compose.yml
14
+ host="localhost",
15
+ port=5432
16
+ )
17
+
18
+ print("🔍 Monitoring database for new invoice rows...")
19
+ print("Press Ctrl+C to stop monitoring\n")
20
+
21
+ last_count = 0
22
+
23
+ try:
24
+ while True:
25
+ # Create a cursor and run the query
26
+ cur = conn.cursor()
27
+ cur.execute("SELECT COUNT(*) FROM invoices;")
28
+ current_count = cur.fetchone()[0]
29
+
30
+ # Get the latest invoices
31
+ cur.execute("SELECT id, invoice_number, vendor_name, total_amount, created_at FROM invoices ORDER BY created_at DESC LIMIT 5;")
32
+ rows = cur.fetchall()
33
+
34
+ # Clear screen (works on Unix-like systems)
35
+ os.system('clear' if os.name == 'posix' else 'cls')
36
+
37
+ print(f"📊 Database Monitor - {time.strftime('%Y-%m-%d %H:%M:%S')}")
38
+ print(f"Total invoices: {current_count}")
39
+
40
+ if current_count > last_count:
41
+ print(f"🆕 New invoices detected! (+{current_count - last_count})")
42
+ last_count = current_count
43
+
44
+ if rows:
45
+ # Create and populate the pretty table
46
+ table = PrettyTable()
47
+ table.field_names = ["ID", "Invoice #", "Vendor", "Amount", "Created"]
48
+ for row in rows:
49
+ table.add_row(row)
50
+ print("\nLatest invoices:")
51
+ print(table)
52
+ else:
53
+ print("\nNo invoices found in database.")
54
+
55
+ print(f"\nMonitoring... (refresh every 2 seconds)")
56
+ cur.close()
57
+ time.sleep(2)
58
+
59
+ except KeyboardInterrupt:
60
+ print("\n\n🛑 Monitoring stopped by user.")
61
+ except Exception as e:
62
+ print(f"\n❌ Error: {e}")
63
+ finally:
64
+ conn.close()
65
+
66
+ if __name__ == "__main__":
67
+ monitor_database()
@@ -0,0 +1,65 @@
1
+ import psycopg2
2
+
3
+ def reset_database():
4
+ """Clear all data from the invoices table and reset the sequence"""
5
+
6
+ # Connect to the Postgres database
7
+ conn = psycopg2.connect(
8
+ dbname="memra_invoice_db",
9
+ user="memra", # From docker-compose.yml
10
+ password="memra123", # From docker-compose.yml
11
+ host="localhost",
12
+ port=5432
13
+ )
14
+
15
+ try:
16
+ # Create a cursor and run the query
17
+ cur = conn.cursor()
18
+
19
+ # First, let's see how many rows we have and current sequence value
20
+ cur.execute("SELECT COUNT(*) FROM invoices;")
21
+ count_before = cur.fetchone()[0]
22
+
23
+ cur.execute("SELECT last_value FROM invoices_id_seq;")
24
+ sequence_before = cur.fetchone()[0]
25
+
26
+ print(f"📊 Current invoice count: {count_before}")
27
+ print(f"🔢 Current sequence value: {sequence_before}")
28
+
29
+ if count_before > 0:
30
+ # Clear all data from the invoices table
31
+ cur.execute("DELETE FROM invoices;")
32
+
33
+ # Reset the sequence to start from 1
34
+ cur.execute("ALTER SEQUENCE invoices_id_seq RESTART WITH 1;")
35
+
36
+ conn.commit()
37
+
38
+ # Verify the deletion and sequence reset
39
+ cur.execute("SELECT COUNT(*) FROM invoices;")
40
+ count_after = cur.fetchone()[0]
41
+
42
+ cur.execute("SELECT last_value FROM invoices_id_seq;")
43
+ sequence_after = cur.fetchone()[0]
44
+
45
+ print(f"🗑️ Deleted {count_before} invoice records")
46
+ print(f"🔄 Reset sequence from {sequence_before} to {sequence_after}")
47
+ print(f"📊 New invoice count: {count_after}")
48
+ print("✅ Database reset successfully!")
49
+ else:
50
+ print("📊 Database is already empty")
51
+ # Still reset the sequence
52
+ cur.execute("ALTER SEQUENCE invoices_id_seq RESTART WITH 1;")
53
+ conn.commit()
54
+ print("🔄 Reset sequence to start from 1")
55
+
56
+ cur.close()
57
+
58
+ except Exception as e:
59
+ print(f"❌ Error: {e}")
60
+ conn.rollback()
61
+ finally:
62
+ conn.close()
63
+
64
+ if __name__ == "__main__":
65
+ reset_database()
@@ -137,7 +137,9 @@ class ServerToolRegistry:
137
137
 
138
138
  elif tool_name == "PDFProcessor":
139
139
  file_path = input_data.get("file", "")
140
- return tool_instance.process_pdf(file_path)
140
+ # Handle both "schema" and "invoice_schema" keys
141
+ schema = input_data.get("schema") or input_data.get("invoice_schema", {})
142
+ return tool_instance.process_pdf(file_path, schema)
141
143
 
142
144
  elif tool_name == "OCRTool":
143
145
  # Assume PDF processor output is passed as input
@@ -6,7 +6,7 @@ Think of it as "Kubernetes for business logic" where agents are the pods and
6
6
  departments are the deployments.
7
7
  """
8
8
 
9
- __version__ = "0.2.3"
9
+ __version__ = "0.2.4"
10
10
 
11
11
  # Core imports
12
12
  from .models import Agent, Department, Tool, LLM
memra-sdk/setup.py CHANGED
@@ -5,7 +5,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
5
5
 
6
6
  setup(
7
7
  name="memra",
8
- version="0.2.3",
8
+ version="0.2.4",
9
9
  author="Memra",
10
10
  author_email="support@memra.com",
11
11
  description="Declarative framework for enterprise workflows with MCP integration - Client SDK",
@@ -1,145 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: memra
3
- Version: 0.2.4
4
- Summary: Declarative framework for enterprise workflows with MCP integration - Client SDK
5
- Home-page: https://github.com/memra/memra-sdk
6
- Author: Memra
7
- Author-email: Memra <support@memra.com>
8
- License: MIT
9
- Project-URL: Homepage, https://memra.co
10
- Project-URL: Repository, https://github.com/memra-platform/memra-sdk
11
- Classifier: Development Status :: 3 - Alpha
12
- Classifier: Intended Audience :: Developers
13
- Classifier: License :: OSI Approved :: MIT License
14
- Classifier: Operating System :: OS Independent
15
- Classifier: Programming Language :: Python :: 3
16
- Classifier: Programming Language :: Python :: 3.8
17
- Classifier: Programming Language :: Python :: 3.9
18
- Classifier: Programming Language :: Python :: 3.10
19
- Classifier: Programming Language :: Python :: 3.11
20
- Requires-Python: >=3.8
21
- Description-Content-Type: text/markdown
22
- License-File: LICENSE
23
- Requires-Dist: pydantic>=1.8.0
24
- Requires-Dist: httpx>=0.24.0
25
- Requires-Dist: typing-extensions>=4.0.0
26
- Requires-Dist: aiohttp>=3.8.0
27
- Requires-Dist: aiohttp-cors>=0.7.0
28
- Provides-Extra: dev
29
- Requires-Dist: pytest>=6.0; extra == "dev"
30
- Requires-Dist: pytest-asyncio; extra == "dev"
31
- Requires-Dist: black; extra == "dev"
32
- Requires-Dist: flake8; extra == "dev"
33
- Provides-Extra: mcp
34
- Requires-Dist: psycopg2-binary>=2.9.0; extra == "mcp"
35
- Dynamic: author
36
- Dynamic: home-page
37
- Dynamic: license-file
38
- Dynamic: requires-python
39
-
40
- # Memra SDK
41
-
42
- The core Memra framework for building AI-powered business workflows.
43
-
44
- ## Installation
45
-
46
- ```bash
47
- pip install memra
48
- ```
49
-
50
- ## Quick Start
51
-
52
- ```python
53
- from memra import Agent, Department, LLM, ExecutionEngine
54
-
55
- # Define an agent
56
- agent = Agent(
57
- role="Data Analyst",
58
- job="Analyze customer data",
59
- llm=LLM(model="llama-3.2-11b-vision-preview"),
60
- sops=["Load data", "Perform analysis", "Generate report"],
61
- output_key="analysis_result"
62
- )
63
-
64
- # Create a department
65
- department = Department(
66
- name="Analytics",
67
- mission="Provide data insights",
68
- agents=[agent],
69
- workflow_order=["Data Analyst"]
70
- )
71
-
72
- # Execute the workflow
73
- engine = ExecutionEngine()
74
- result = engine.execute_department(department, {"data": "customer_data.csv"})
75
- ```
76
-
77
- ## Core Components
78
-
79
- ### Agent
80
- An AI worker that performs specific tasks using LLMs and tools.
81
-
82
- ### Department
83
- A team of agents working together to accomplish a mission.
84
-
85
- ### ExecutionEngine
86
- Orchestrates the execution of departments and their workflows.
87
-
88
- ### LLM
89
- Configuration for language models used by agents.
90
-
91
- ## Examples
92
-
93
- See the `examples/` directory for basic usage examples:
94
- - `simple_text_to_sql.py` - Basic text-to-SQL conversion
95
- - `ask_questions.py` - Simple question answering
96
-
97
- ## Documentation
98
-
99
- For detailed documentation, visit [docs.memra.co](https://docs.memra.co)
100
-
101
- Documentation is also available locally in the `examples/` directory.
102
-
103
- ## Example: Propane Delivery Workflow
104
-
105
- See the `examples/propane_delivery.py` file for a complete example of how to use Memra to orchestrate a propane delivery workflow.
106
-
107
- ## 🔍 Smart File Discovery
108
-
109
- Memra includes intelligent file discovery and management capabilities:
110
-
111
- ### File Discovery Tools
112
- - **FileDiscovery**: Automatically scan directories for files matching patterns
113
- - **FileCopy**: Copy files from external locations to standard processing directories
114
- - **Smart Routing**: Automatically handle file paths and directory management
115
-
116
- ### Example: Smart Invoice Processing
117
- ```python
118
- from memra import Agent
119
-
120
- # Smart agent that discovers and processes files automatically
121
- smart_parser = Agent(
122
- role="Smart Invoice Parser",
123
- job="Discover and process invoice files intelligently",
124
- tools=[
125
- {"name": "FileDiscovery", "hosted_by": "memra"},
126
- {"name": "FileCopy", "hosted_by": "memra"},
127
- {"name": "InvoiceExtractionWorkflow", "hosted_by": "memra"}
128
- ]
129
- )
130
-
131
- # Three modes of operation:
132
- # 1. Auto-discovery: Scan invoices/ directory
133
- # 2. External file: Copy from Downloads to invoices/
134
- # 3. Specific file: Process exact file path
135
- ```
136
-
137
- See `examples/accounts_payable_smart.py` for a complete implementation.
138
-
139
- ## Contributing
140
-
141
- We welcome contributions! Please see our [contributing guide](CONTRIBUTING.md) for details.
142
-
143
- ## License
144
-
145
- MIT License - see LICENSE file for details.
@@ -1,2 +0,0 @@
1
- [console_scripts]
2
- memra = memra.cli:main
File without changes
File without changes