memra 0.2.2__py3-none-any.whl → 0.2.4__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 (57) hide show
  1. memra/__init__.py +6 -2
  2. memra/execution.py +53 -0
  3. memra/tool_registry.py +162 -0
  4. memra-0.2.4.dist-info/METADATA +145 -0
  5. memra-0.2.4.dist-info/RECORD +58 -0
  6. {memra-0.2.2.dist-info → memra-0.2.4.dist-info}/WHEEL +1 -1
  7. memra-0.2.4.dist-info/top_level.txt +4 -0
  8. memra-ops/app.py +710 -0
  9. memra-ops/config/config.py +25 -0
  10. memra-ops/config.py +34 -0
  11. memra-ops/scripts/release.py +133 -0
  12. memra-ops/scripts/start_memra.py +334 -0
  13. memra-ops/scripts/stop_memra.py +132 -0
  14. memra-ops/server_tool_registry.py +188 -0
  15. memra-ops/tests/test_llm_text_to_sql.py +115 -0
  16. memra-ops/tests/test_llm_vs_pattern.py +130 -0
  17. memra-ops/tests/test_mcp_schema_aware.py +124 -0
  18. memra-ops/tests/test_schema_aware_sql.py +139 -0
  19. memra-ops/tests/test_schema_aware_sql_simple.py +66 -0
  20. memra-ops/tests/test_text_to_sql_demo.py +140 -0
  21. memra-ops/tools/mcp_bridge_server.py +851 -0
  22. memra-sdk/examples/accounts_payable.py +215 -0
  23. memra-sdk/examples/accounts_payable_client.py +217 -0
  24. memra-sdk/examples/accounts_payable_mcp.py +200 -0
  25. memra-sdk/examples/ask_questions.py +123 -0
  26. memra-sdk/examples/invoice_processing.py +116 -0
  27. memra-sdk/examples/propane_delivery.py +87 -0
  28. memra-sdk/examples/simple_text_to_sql.py +158 -0
  29. memra-sdk/memra/__init__.py +31 -0
  30. memra-sdk/memra/discovery.py +15 -0
  31. memra-sdk/memra/discovery_client.py +49 -0
  32. memra-sdk/memra/execution.py +481 -0
  33. memra-sdk/memra/models.py +99 -0
  34. memra-sdk/memra/tool_registry.py +343 -0
  35. memra-sdk/memra/tool_registry_client.py +106 -0
  36. memra-sdk/scripts/release.py +133 -0
  37. memra-sdk/setup.py +52 -0
  38. memra-workflows/accounts_payable/accounts_payable.py +215 -0
  39. memra-workflows/accounts_payable/accounts_payable_client.py +216 -0
  40. memra-workflows/accounts_payable/accounts_payable_mcp.py +200 -0
  41. memra-workflows/accounts_payable/accounts_payable_smart.py +221 -0
  42. memra-workflows/invoice_processing/invoice_processing.py +116 -0
  43. memra-workflows/invoice_processing/smart_invoice_processor.py +220 -0
  44. memra-workflows/logic/__init__.py +1 -0
  45. memra-workflows/logic/file_tools.py +50 -0
  46. memra-workflows/logic/invoice_tools.py +501 -0
  47. memra-workflows/logic/propane_agents.py +52 -0
  48. memra-workflows/mcp_bridge_server.py +230 -0
  49. memra-workflows/propane_delivery/propane_delivery.py +87 -0
  50. memra-workflows/text_to_sql/complete_invoice_workflow_with_queries.py +208 -0
  51. memra-workflows/text_to_sql/complete_text_to_sql_system.py +266 -0
  52. memra-workflows/text_to_sql/file_discovery_demo.py +156 -0
  53. memra-0.2.2.dist-info/METADATA +0 -148
  54. memra-0.2.2.dist-info/RECORD +0 -13
  55. memra-0.2.2.dist-info/top_level.txt +0 -1
  56. {memra-0.2.2.dist-info → memra-0.2.4.dist-info}/entry_points.txt +0 -0
  57. {memra-0.2.2.dist-info → memra-0.2.4.dist-info/licenses}/LICENSE +0 -0
memra/__init__.py CHANGED
@@ -6,18 +6,22 @@ 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.2"
9
+ __version__ = "0.2.3"
10
10
 
11
11
  # Core imports
12
- from .models import Agent, Department, Tool
12
+ from .models import Agent, Department, Tool, LLM
13
13
  from .execution import ExecutionEngine
14
+ from .discovery_client import check_api_health, get_api_status
14
15
 
15
16
  # Make key classes available at package level
16
17
  __all__ = [
17
18
  "Agent",
18
19
  "Department",
19
20
  "Tool",
21
+ "LLM",
20
22
  "ExecutionEngine",
23
+ "check_api_health",
24
+ "get_api_status",
21
25
  "__version__"
22
26
  ]
23
27
 
memra/execution.py CHANGED
@@ -216,6 +216,21 @@ class ExecutionEngine:
216
216
  # Use local registry for MCP and other local tools
217
217
  print(f"🏠 {agent.role}: Using local registry for {tool_name}")
218
218
  config_to_pass = tool_spec.get("config") if isinstance(tool_spec, dict) else tool_spec.config
219
+
220
+ # For MCP tools, merge department context MCP configuration
221
+ if hosted_by == "mcp":
222
+ mcp_config = {}
223
+ dept_context = context.get("department_context", {})
224
+ if "mcp_bridge_url" in dept_context:
225
+ mcp_config["bridge_url"] = dept_context["mcp_bridge_url"]
226
+ if "mcp_bridge_secret" in dept_context:
227
+ mcp_config["bridge_secret"] = dept_context["mcp_bridge_secret"]
228
+
229
+ # Merge with tool-specific config if it exists
230
+ if config_to_pass:
231
+ mcp_config.update(config_to_pass)
232
+ config_to_pass = mcp_config
233
+
219
234
  print(f"🔧 {agent.role}: Config for {tool_name}: {config_to_pass}")
220
235
  tool_result = self.tool_registry.execute_tool(
221
236
  tool_name,
@@ -325,6 +340,44 @@ class ExecutionEngine:
325
340
  not tool_data.get("_mock", False) # Not mock data
326
341
  )
327
342
 
343
+ elif tool_name == "FileDiscovery":
344
+ # Real work if it actually discovered files in a real directory
345
+ return (
346
+ "files" in tool_data and
347
+ isinstance(tool_data["files"], list) and
348
+ "directory" in tool_data and
349
+ tool_data.get("success", False) == True
350
+ )
351
+
352
+ elif tool_name == "FileCopy":
353
+ # Real work if it actually copied a file
354
+ return (
355
+ "destination_path" in tool_data and
356
+ "source_path" in tool_data and
357
+ tool_data.get("success", False) == True and
358
+ tool_data.get("operation") == "copy_completed"
359
+ )
360
+
361
+ elif tool_name == "TextToSQL":
362
+ # Real work if it actually executed SQL and returned real results
363
+ return (
364
+ "generated_sql" in tool_data and
365
+ "results" in tool_data and
366
+ isinstance(tool_data["results"], list) and
367
+ tool_data.get("success", False) == True and
368
+ not tool_data.get("_mock", False) # Not mock data
369
+ )
370
+
371
+ elif tool_name == "SQLExecutor":
372
+ # Real work if it actually executed SQL and returned real results
373
+ return (
374
+ "query" in tool_data and
375
+ "results" in tool_data and
376
+ isinstance(tool_data["results"], list) and
377
+ "row_count" in tool_data and
378
+ not tool_data.get("_mock", False) # Not mock data
379
+ )
380
+
328
381
  # Default to mock work
329
382
  return False
330
383
 
memra/tool_registry.py CHANGED
@@ -24,6 +24,8 @@ class ToolRegistry:
24
24
  ("OCRTool", "Perform OCR on images and documents"),
25
25
  ("InvoiceExtractionWorkflow", "Extract structured data from invoices"),
26
26
  ("FileReader", "Read files from the filesystem"),
27
+ ("FileDiscovery", "Discover and list files in directories"),
28
+ ("FileCopy", "Copy files to standard processing directories"),
27
29
  ]
28
30
 
29
31
  for tool_name, description in server_tools:
@@ -33,6 +35,9 @@ class ToolRegistry:
33
35
  mcp_tools = [
34
36
  ("DataValidator", "Validate data against schemas"),
35
37
  ("PostgresInsert", "Insert data into PostgreSQL database"),
38
+ ("TextToSQL", "Convert natural language questions to SQL queries and execute them"),
39
+ ("SQLExecutor", "Execute SQL queries against PostgreSQL database"),
40
+ ("TextToSQLGenerator", "Generate SQL from natural language questions"),
36
41
  ]
37
42
 
38
43
  for tool_name, description in mcp_tools:
@@ -123,24 +128,32 @@ class ToolRegistry:
123
128
  last_error = None
124
129
  for endpoint in endpoints_to_try:
125
130
  try:
131
+ logger.info(f"Trying endpoint: {endpoint}")
126
132
  with httpx.Client(timeout=60.0) as client:
127
133
  response = client.post(endpoint, json=payload, headers=headers)
128
134
 
135
+ logger.info(f"Response status for {endpoint}: {response.status_code}")
136
+
129
137
  if response.status_code == 200:
130
138
  result = response.json()
131
139
  logger.info(f"MCP tool {tool_name} executed successfully via {endpoint}")
132
140
  return result
133
141
  elif response.status_code == 404:
142
+ logger.info(f"Endpoint {endpoint} returned 404, trying next...")
134
143
  continue # Try next endpoint
135
144
  else:
145
+ logger.error(f"Endpoint {endpoint} returned {response.status_code}: {response.text}")
136
146
  response.raise_for_status()
137
147
 
138
148
  except httpx.HTTPStatusError as e:
139
149
  if e.response.status_code == 404:
150
+ logger.info(f"Endpoint {endpoint} returned 404, trying next...")
140
151
  continue # Try next endpoint
152
+ logger.error(f"HTTP error for {endpoint}: {e.response.status_code} - {e.response.text}")
141
153
  last_error = e
142
154
  continue
143
155
  except Exception as e:
156
+ logger.error(f"Exception for {endpoint}: {str(e)}")
144
157
  last_error = e
145
158
  continue
146
159
 
@@ -169,6 +182,155 @@ class ToolRegistry:
169
182
  "_mock": True
170
183
  }
171
184
  }
185
+ elif tool_name == "FileDiscovery":
186
+ # Mock file discovery - in real implementation, would scan directories
187
+ directory = input_data.get("directory", "invoices")
188
+ file_pattern = input_data.get("pattern", "*.pdf")
189
+
190
+ # Simulate finding files in the directory
191
+ mock_files = [
192
+ {
193
+ "filename": "10352259310.PDF",
194
+ "path": f"{directory}/10352259310.PDF",
195
+ "size": "542KB",
196
+ "modified": "2024-05-28",
197
+ "type": "PDF"
198
+ }
199
+ ]
200
+
201
+ return {
202
+ "success": True,
203
+ "data": {
204
+ "directory": directory,
205
+ "pattern": file_pattern,
206
+ "files_found": len(mock_files),
207
+ "files": mock_files,
208
+ "message": f"Found {len(mock_files)} files in {directory}/ directory"
209
+ }
210
+ }
211
+
212
+ elif tool_name == "FileCopy":
213
+ # Mock file copy - in real implementation, would copy files
214
+ source_path = input_data.get("source_path", "")
215
+ destination_dir = input_data.get("destination_dir", "invoices")
216
+
217
+ if not source_path:
218
+ return {
219
+ "success": False,
220
+ "error": "Source path is required"
221
+ }
222
+
223
+ # Extract filename from path
224
+ import os
225
+ filename = os.path.basename(source_path)
226
+ destination_path = f"{destination_dir}/{filename}"
227
+
228
+ return {
229
+ "success": True,
230
+ "data": {
231
+ "source_path": source_path,
232
+ "destination_path": destination_path,
233
+ "message": f"File copied from {source_path} to {destination_path}",
234
+ "file_size": "245KB",
235
+ "operation": "copy_completed"
236
+ }
237
+ }
238
+ elif tool_name == "TextToSQL":
239
+ # Mock text-to-SQL - in real implementation, would use LLM to generate SQL
240
+ question = input_data.get("question", "")
241
+ schema = input_data.get("schema", {})
242
+
243
+ if not question:
244
+ return {
245
+ "success": False,
246
+ "error": "Question is required for text-to-SQL conversion"
247
+ }
248
+
249
+ # Simulate SQL generation and execution
250
+ mock_sql = "SELECT vendor_name, invoice_number, total_amount FROM invoices WHERE vendor_name ILIKE '%air liquide%' ORDER BY invoice_date DESC LIMIT 5;"
251
+ mock_results = [
252
+ {
253
+ "vendor_name": "Air Liquide Canada Inc.",
254
+ "invoice_number": "INV-12345",
255
+ "total_amount": 1234.56
256
+ },
257
+ {
258
+ "vendor_name": "Air Liquide Canada Inc.",
259
+ "invoice_number": "INV-67890",
260
+ "total_amount": 2345.67
261
+ }
262
+ ]
263
+
264
+ return {
265
+ "success": True,
266
+ "data": {
267
+ "question": question,
268
+ "generated_sql": mock_sql,
269
+ "results": mock_results,
270
+ "row_count": len(mock_results),
271
+ "message": f"Found {len(mock_results)} results for: {question}",
272
+ "_mock": True
273
+ }
274
+ }
275
+ elif tool_name == "SQLExecutor":
276
+ # Mock SQL execution
277
+ sql_query = input_data.get("sql_query", "")
278
+
279
+ if not sql_query:
280
+ return {
281
+ "success": False,
282
+ "error": "SQL query is required"
283
+ }
284
+
285
+ # Mock results based on query type
286
+ if sql_query.upper().startswith("SELECT"):
287
+ mock_results = [
288
+ {"vendor_name": "Air Liquide Canada Inc.", "invoice_number": "INV-12345", "total_amount": 1234.56},
289
+ {"vendor_name": "Air Liquide Canada Inc.", "invoice_number": "INV-67890", "total_amount": 2345.67}
290
+ ]
291
+ return {
292
+ "success": True,
293
+ "data": {
294
+ "query": sql_query,
295
+ "results": mock_results,
296
+ "row_count": len(mock_results),
297
+ "columns": ["vendor_name", "invoice_number", "total_amount"],
298
+ "_mock": True
299
+ }
300
+ }
301
+ else:
302
+ return {
303
+ "success": True,
304
+ "data": {
305
+ "query": sql_query,
306
+ "affected_rows": 1,
307
+ "message": "Query executed successfully",
308
+ "_mock": True
309
+ }
310
+ }
311
+ elif tool_name == "TextToSQLGenerator":
312
+ # Mock SQL generation
313
+ question = input_data.get("question", "")
314
+
315
+ if not question:
316
+ return {
317
+ "success": False,
318
+ "error": "Question is required for SQL generation"
319
+ }
320
+
321
+ # Generate mock SQL based on question
322
+ mock_sql = "SELECT * FROM invoices WHERE vendor_name ILIKE '%air liquide%'"
323
+
324
+ return {
325
+ "success": True,
326
+ "data": {
327
+ "question": question,
328
+ "generated_sql": mock_sql,
329
+ "explanation": "Generated SQL query based on natural language question",
330
+ "confidence": "medium",
331
+ "_mock": True
332
+ }
333
+ }
172
334
  else:
173
335
  return {
174
336
  "success": False,
@@ -0,0 +1,145 @@
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.
@@ -0,0 +1,58 @@
1
+ memra/__init__.py,sha256=zVO29fnEDclBI9x9SFVzF9uJYAKhPDTNrMFMWuw6JC8,787
2
+ memra/discovery.py,sha256=yJIQnrDQu1nyzKykCIuzG_5SW5dIXHCEBLLKRWacIoY,480
3
+ memra/discovery_client.py,sha256=AbnKn6qhyrf7vmOvknEeDzH4tiGHsqPHtDaein_qaW0,1271
4
+ memra/execution.py,sha256=oA66YKds6-8YXQJ7ppCj39C09xuXG1z8GWfF9Tm8Ml0,23861
5
+ memra/models.py,sha256=sXMPRnMB_mUVtJdBFyd0ElCf_uh1yqx7iLssIYNm0vI,3333
6
+ memra/tool_registry.py,sha256=PDuWtiX_LX-vhKnx4JeL_ndUwG-oJ6bdhGe6iQeCDBw,15361
7
+ memra/tool_registry_client.py,sha256=uzMQ4COvRams9vuPLcqcdljUpDlAYU_tyFxrRhrA0Lc,4009
8
+ memra-0.2.4.dist-info/licenses/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ memra-ops/app.py,sha256=eyswUTeTvKdPSVy5RHMDW9ijUXdBfYB1qDtwCdkDGDM,26057
10
+ memra-ops/config.py,sha256=6mBbS_stoEIhJDBqdJOalryAnyWeHbDy81mU1j08ids,969
11
+ memra-ops/server_tool_registry.py,sha256=LYiLUL08M72Poaqt_rWt11BGMFlZKSSWjbW9SnfynEI,8212
12
+ memra-ops/config/config.py,sha256=7dcT9W5b_nWrVAylbdeOaA60_NJlhv2YLyEILTcNKtI,600
13
+ memra-ops/scripts/release.py,sha256=riQ-jz7-vnd1cSfQdU1eUZmVDyuWym1nmZW65lGetiI,4218
14
+ memra-ops/scripts/start_memra.py,sha256=VR7WESQXgvPuzZEFMhtmABSR7IzYixsnpgtoPcECLK0,11987
15
+ memra-ops/scripts/stop_memra.py,sha256=yyTu4jxjUbxTrvobQ-UhpNk-eWB8bCFjcBPGW1scIJg,4591
16
+ memra-ops/tests/test_llm_text_to_sql.py,sha256=IDL7FEzlm2Dr9pRCcJQ6SGddF9VBDfHonwztrDpxBGU,4099
17
+ memra-ops/tests/test_llm_vs_pattern.py,sha256=ZATV1fS7C6Jn-N4-UB5LzuRjbiO1ctZq3gNoIud2RWc,4880
18
+ memra-ops/tests/test_mcp_schema_aware.py,sha256=H5NmGxS3LWo9xoodqVeliJyHco7ZjGOtHg80ep1SHzw,4537
19
+ memra-ops/tests/test_schema_aware_sql.py,sha256=b_XPtv7eldR2ARBVlriTHMA1nwqYUcMgthL8mHpewuM,4645
20
+ memra-ops/tests/test_schema_aware_sql_simple.py,sha256=8f8zijkTwvIqVHM3B5oVviRfFS-U6bfC43fk9hcWsoE,2309
21
+ memra-ops/tests/test_text_to_sql_demo.py,sha256=5mmpSwXZ8r8sj3J9iCYkFx0SgwyXPe-7Prie1hL6cis,5092
22
+ memra-ops/tools/mcp_bridge_server.py,sha256=IKUNusZovPdR0_6Bv_XejmAk27lnHrM1uOE8xPVnM8s,35051
23
+ memra-sdk/setup.py,sha256=ZeDcO25CHXm1rHoDZbWI2BE6B7s7LUa9XvFmUu_YEtk,1513
24
+ memra-sdk/examples/accounts_payable.py,sha256=PfpXKrGOUu6NpkNcHy6cN6TtsXfnsJZhUv-KGlOvDqY,7990
25
+ memra-sdk/examples/accounts_payable_client.py,sha256=tLHHCydEpasLHTHd4YULhSxFy6zs81X5PZHav0dlQ2I,7816
26
+ memra-sdk/examples/accounts_payable_mcp.py,sha256=lOgwDfMVKxifQi70GmeXQnpZiIFrZnNj5_JSZ9qsdBw,7344
27
+ memra-sdk/examples/ask_questions.py,sha256=jek7EVXXZ_vODlMy_hQGQCkN9vYBfaW7SOWsIQRV2GY,3830
28
+ memra-sdk/examples/invoice_processing.py,sha256=STe3ri65WH_Ss84qiRWuGZTpDZke5GoJf8LEqOAc5ys,3980
29
+ memra-sdk/examples/propane_delivery.py,sha256=ryvIxDjM9GJY9T6fFIqJgHOcX2PEMkfF_t_3E5CyZW4,2539
30
+ memra-sdk/examples/simple_text_to_sql.py,sha256=NnpKo9nFpmPQ089zcSx4wwG6_tSHTmGJSS7LPs55NA0,5314
31
+ memra-sdk/memra/__init__.py,sha256=zVO29fnEDclBI9x9SFVzF9uJYAKhPDTNrMFMWuw6JC8,787
32
+ memra-sdk/memra/discovery.py,sha256=yJIQnrDQu1nyzKykCIuzG_5SW5dIXHCEBLLKRWacIoY,480
33
+ memra-sdk/memra/discovery_client.py,sha256=AbnKn6qhyrf7vmOvknEeDzH4tiGHsqPHtDaein_qaW0,1271
34
+ memra-sdk/memra/execution.py,sha256=P7tAur0SEMtX6uLlfxTfCZBgMLIRj6Wl3dsv2EA9fHc,23443
35
+ memra-sdk/memra/models.py,sha256=sXMPRnMB_mUVtJdBFyd0ElCf_uh1yqx7iLssIYNm0vI,3333
36
+ memra-sdk/memra/tool_registry.py,sha256=P2TafpiqV19yzi0jVrQQrXFGBpQkbmePbRfEW_ai24M,14700
37
+ memra-sdk/memra/tool_registry_client.py,sha256=uzMQ4COvRams9vuPLcqcdljUpDlAYU_tyFxrRhrA0Lc,4009
38
+ memra-sdk/scripts/release.py,sha256=riQ-jz7-vnd1cSfQdU1eUZmVDyuWym1nmZW65lGetiI,4218
39
+ memra-workflows/mcp_bridge_server.py,sha256=6K9fedZiwNpkT7wGAS6IW-HgMYBUC94zu8ppUgftqDg,8528
40
+ memra-workflows/accounts_payable/accounts_payable.py,sha256=rRpviqKZ-g0KPEnI98GbXy-KnyTrN1dLkj0HP9PKlYs,8012
41
+ memra-workflows/accounts_payable/accounts_payable_client.py,sha256=kNu2EQ8d6T6qcKn68FznnMGBeoqtXFbN4PHDVDImapk,7813
42
+ memra-workflows/accounts_payable/accounts_payable_mcp.py,sha256=kySt7PKyIgLbG1Q3jPY1kFPQK8o_3aAmL9vJG2Qcnxc,7366
43
+ memra-workflows/accounts_payable/accounts_payable_smart.py,sha256=g_V6-1qPsLiIOFw-eLT4w-RoljjErF65SuKRzkEeSck,8004
44
+ memra-workflows/invoice_processing/invoice_processing.py,sha256=STe3ri65WH_Ss84qiRWuGZTpDZke5GoJf8LEqOAc5ys,3980
45
+ memra-workflows/invoice_processing/smart_invoice_processor.py,sha256=Ct3ZjNujK4VTlCDgwMWXn6Y7b1dg0a_eIbRP-xm-p3g,7203
46
+ memra-workflows/logic/__init__.py,sha256=kLTdniFpBqOusmRng8W2LSIAmgj-jfM3Agjl_vXYTl8,76
47
+ memra-workflows/logic/file_tools.py,sha256=n6uDwInPZcr74zAJJbA9iZajWgRcKoHYtEKX_lbzsik,1586
48
+ memra-workflows/logic/invoice_tools.py,sha256=wLTI0JqkMYMlFv1z_DPwliIvKbpFBcYh5SnEnhU13Co,20366
49
+ memra-workflows/logic/propane_agents.py,sha256=ZF1RSccn73a5XZVa-1nxgjvubcYzf62g9lr9PoTbGl4,1804
50
+ memra-workflows/propane_delivery/propane_delivery.py,sha256=ryvIxDjM9GJY9T6fFIqJgHOcX2PEMkfF_t_3E5CyZW4,2539
51
+ memra-workflows/text_to_sql/complete_invoice_workflow_with_queries.py,sha256=x4wq3o_ogFnnrI6MQwEhqIiNH-NNwS5SXQUoKd_br7U,7428
52
+ memra-workflows/text_to_sql/complete_text_to_sql_system.py,sha256=Izj4ucXDXTWFY29SWr2YrEf3ZyXH4QCDEljNk4jlpI0,8991
53
+ memra-workflows/text_to_sql/file_discovery_demo.py,sha256=4R_QN0Y6OtHmnX6CvtwDXen122XCDrk-MRBOzxb_x_k,5306
54
+ memra-0.2.4.dist-info/METADATA,sha256=YDEg2IxnhDLka_MA0Ge_cKx_yO2HMFphcGNxnH85t84,4203
55
+ memra-0.2.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
56
+ memra-0.2.4.dist-info/entry_points.txt,sha256=LBVjwWoxWJRzNLgeByPn6xUvWFIRnqnemvAZgIoSt08,41
57
+ memra-0.2.4.dist-info/top_level.txt,sha256=IviXF9qSQY_BidRYund9zFaV-q1VMl6CuizwTAggQks,42
58
+ memra-0.2.4.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.7.0)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -0,0 +1,4 @@
1
+ memra
2
+ memra-ops
3
+ memra-sdk
4
+ memra-workflows