jarviscore-framework 0.1.1__py3-none-any.whl → 0.2.0__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 (85) hide show
  1. examples/autoagent_distributed_example.py +211 -0
  2. examples/custom_profile_decorator.py +134 -0
  3. examples/custom_profile_wrap.py +168 -0
  4. examples/customagent_distributed_example.py +362 -0
  5. examples/customagent_p2p_example.py +347 -0
  6. jarviscore/__init__.py +49 -36
  7. jarviscore/adapter/__init__.py +15 -9
  8. jarviscore/adapter/decorator.py +23 -19
  9. jarviscore/adapter/wrapper.py +303 -0
  10. jarviscore/cli/scaffold.py +1 -1
  11. jarviscore/cli/smoketest.py +3 -2
  12. jarviscore/core/agent.py +44 -1
  13. jarviscore/core/mesh.py +196 -35
  14. jarviscore/data/examples/autoagent_distributed_example.py +211 -0
  15. jarviscore/data/examples/customagent_distributed_example.py +362 -0
  16. jarviscore/data/examples/customagent_p2p_example.py +347 -0
  17. jarviscore/docs/API_REFERENCE.md +264 -51
  18. jarviscore/docs/AUTOAGENT_GUIDE.md +198 -0
  19. jarviscore/docs/CONFIGURATION.md +35 -21
  20. jarviscore/docs/CUSTOMAGENT_GUIDE.md +415 -0
  21. jarviscore/docs/GETTING_STARTED.md +106 -13
  22. jarviscore/docs/TROUBLESHOOTING.md +144 -6
  23. jarviscore/docs/USER_GUIDE.md +138 -361
  24. jarviscore/orchestration/engine.py +20 -8
  25. jarviscore/p2p/__init__.py +10 -0
  26. jarviscore/p2p/coordinator.py +129 -0
  27. jarviscore/p2p/messages.py +87 -0
  28. jarviscore/p2p/peer_client.py +576 -0
  29. jarviscore/p2p/peer_tool.py +268 -0
  30. {jarviscore_framework-0.1.1.dist-info → jarviscore_framework-0.2.0.dist-info}/METADATA +60 -54
  31. jarviscore_framework-0.2.0.dist-info/RECORD +132 -0
  32. {jarviscore_framework-0.1.1.dist-info → jarviscore_framework-0.2.0.dist-info}/WHEEL +1 -1
  33. {jarviscore_framework-0.1.1.dist-info → jarviscore_framework-0.2.0.dist-info}/top_level.txt +1 -0
  34. test_logs/code_registry/functions/data_generator-558779ed_560ebc37.py +7 -0
  35. test_logs/code_registry/functions/data_generator-5ed3609e_560ebc37.py +7 -0
  36. test_logs/code_registry/functions/data_generator-66da0356_43970bb9.py +25 -0
  37. test_logs/code_registry/functions/data_generator-7a2fac83_583709d9.py +36 -0
  38. test_logs/code_registry/functions/data_generator-888b670f_aa235863.py +9 -0
  39. test_logs/code_registry/functions/data_generator-9ca5f642_aa235863.py +9 -0
  40. test_logs/code_registry/functions/data_generator-bfd90775_560ebc37.py +7 -0
  41. test_logs/code_registry/functions/data_generator-e95d2f7d_aa235863.py +9 -0
  42. test_logs/code_registry/functions/data_generator-f60ca8a2_327eb8c2.py +29 -0
  43. test_logs/code_registry/functions/mathematician-02adf9ee_958658d9.py +19 -0
  44. test_logs/code_registry/functions/mathematician-0706fb57_5df13441.py +23 -0
  45. test_logs/code_registry/functions/mathematician-153c9c4a_ba59c918.py +83 -0
  46. test_logs/code_registry/functions/mathematician-287e61c0_41daa793.py +18 -0
  47. test_logs/code_registry/functions/mathematician-2967af5a_863c2cc6.py +17 -0
  48. test_logs/code_registry/functions/mathematician-303ca6d6_5df13441.py +23 -0
  49. test_logs/code_registry/functions/mathematician-308a4afd_cbf5064d.py +73 -0
  50. test_logs/code_registry/functions/mathematician-353f16e2_0968bcf5.py +18 -0
  51. test_logs/code_registry/functions/mathematician-3c22475a_41daa793.py +17 -0
  52. test_logs/code_registry/functions/mathematician-5bac1029_0968bcf5.py +18 -0
  53. test_logs/code_registry/functions/mathematician-640f76b2_9198780b.py +19 -0
  54. test_logs/code_registry/functions/mathematician-752fa7ea_863c2cc6.py +17 -0
  55. test_logs/code_registry/functions/mathematician-baf9ef39_0968bcf5.py +18 -0
  56. test_logs/code_registry/functions/mathematician-bc8b2a2f_5df13441.py +23 -0
  57. test_logs/code_registry/functions/mathematician-c31e4686_41daa793.py +18 -0
  58. test_logs/code_registry/functions/mathematician-cc84c84c_863c2cc6.py +17 -0
  59. test_logs/code_registry/functions/mathematician-dd7c7144_9198780b.py +19 -0
  60. test_logs/code_registry/functions/mathematician-e671c256_41ea4487.py +74 -0
  61. test_logs/code_registry/functions/report_generator-1a878fcc_18d44bdc.py +47 -0
  62. test_logs/code_registry/functions/report_generator-25c1c331_cea57d0d.py +35 -0
  63. test_logs/code_registry/functions/report_generator-37552117_e711c2b9.py +35 -0
  64. test_logs/code_registry/functions/report_generator-bc662768_e711c2b9.py +35 -0
  65. test_logs/code_registry/functions/report_generator-d6c0e76b_5e7722ec.py +44 -0
  66. test_logs/code_registry/functions/report_generator-f270fb02_680529c3.py +44 -0
  67. test_logs/code_registry/functions/text_processor-11393b14_4370d3ed.py +40 -0
  68. test_logs/code_registry/functions/text_processor-7d02dfc3_d3b569be.py +37 -0
  69. test_logs/code_registry/functions/text_processor-8adb5e32_9168c5fe.py +13 -0
  70. test_logs/code_registry/functions/text_processor-c58ffc19_78b4ceac.py +42 -0
  71. test_logs/code_registry/functions/text_processor-cd5977b1_9168c5fe.py +13 -0
  72. test_logs/code_registry/functions/text_processor-ec1c8773_9168c5fe.py +13 -0
  73. tests/test_01_analyst_standalone.py +124 -0
  74. tests/test_02_assistant_standalone.py +164 -0
  75. tests/test_03_analyst_with_framework.py +945 -0
  76. tests/test_04_assistant_with_framework.py +1002 -0
  77. tests/test_05_integration.py +1301 -0
  78. tests/test_06_real_llm_integration.py +760 -0
  79. tests/test_07_distributed_single_node.py +578 -0
  80. tests/test_08_distributed_multi_node.py +454 -0
  81. tests/test_09_distributed_autoagent.py +509 -0
  82. tests/test_10_distributed_customagent.py +787 -0
  83. tests/test_mesh.py +35 -4
  84. jarviscore_framework-0.1.1.dist-info/RECORD +0 -69
  85. {jarviscore_framework-0.1.1.dist-info → jarviscore_framework-0.2.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,47 @@
1
+ async def main():
2
+ try:
3
+ # Get data from previous step if available, otherwise use provided defaults
4
+ previous_data = {'name': 'John', 'age': 30, 'city': 'NYC'}
5
+
6
+ # Check if we have previous step results
7
+ try:
8
+ if 'step0' in globals().get('previous_step_results', {}):
9
+ previous_data = previous_step_results['step0']
10
+ except:
11
+ pass
12
+
13
+ # Extract person data
14
+ name = previous_data.get('name', 'John')
15
+ age = previous_data.get('age', 30)
16
+ city = previous_data.get('city', 'NYC')
17
+
18
+ # Create formatted text report
19
+ report_lines = [
20
+ "=" * 40,
21
+ "PERSON INFORMATION REPORT",
22
+ "=" * 40,
23
+ "",
24
+ f"Name: {name}",
25
+ f"Age: {age}",
26
+ f"City: {city}",
27
+ "",
28
+ "-" * 40,
29
+ f"Summary: {name} is {age} years old and lives in {city}.",
30
+ "-" * 40,
31
+ "",
32
+ "Report generated successfully.",
33
+ "=" * 40
34
+ ]
35
+
36
+ report = "\n".join(report_lines)
37
+
38
+ result = {
39
+ 'report': report
40
+ }
41
+
42
+ return result
43
+
44
+ except Exception as e:
45
+ return {
46
+ 'report': f"Error generating report: {str(e)}"
47
+ }
@@ -0,0 +1,35 @@
1
+ async def main():
2
+ try:
3
+ # Create invoice header with company name and date
4
+ company_name = "Acme Corp"
5
+ date = "Jan 2024"
6
+
7
+ # Create formatted header
8
+ header_width = 50
9
+ border = "=" * header_width
10
+
11
+ # Center the company name and date
12
+ company_line = company_name.center(header_width)
13
+ date_line = date.center(header_width)
14
+ title_line = "INVOICE".center(header_width)
15
+
16
+ # Build the invoice header
17
+ invoice_header = f"""
18
+ {border}
19
+ {company_line}
20
+ {title_line}
21
+ {date_line}
22
+ {border}
23
+ """
24
+
25
+ result = {
26
+ 'report': invoice_header.strip()
27
+ }
28
+
29
+ return result
30
+
31
+ except Exception as e:
32
+ result = {
33
+ 'report': f"Error generating invoice header: {str(e)}"
34
+ }
35
+ return result
@@ -0,0 +1,35 @@
1
+ async def main():
2
+ try:
3
+ # Create invoice header with company name and date
4
+ company_name = "Acme Corp"
5
+ date = "Jan 2024"
6
+
7
+ # Create formatted header
8
+ width = 50
9
+ border = "=" * width
10
+
11
+ header_lines = [
12
+ border,
13
+ "",
14
+ company_name.center(width),
15
+ "",
16
+ "INVOICE".center(width),
17
+ "",
18
+ f"Date: {date}".center(width),
19
+ "",
20
+ border
21
+ ]
22
+
23
+ report = "\n".join(header_lines)
24
+
25
+ result = {
26
+ 'report': report
27
+ }
28
+
29
+ return result
30
+
31
+ except Exception as e:
32
+ result = {
33
+ 'report': f"Error generating invoice header: {str(e)}"
34
+ }
35
+ return result
@@ -0,0 +1,35 @@
1
+ async def main():
2
+ try:
3
+ # Create invoice header with company name and date
4
+ company_name = "Acme Corp"
5
+ date = "Jan 2024"
6
+
7
+ # Create formatted header
8
+ width = 50
9
+ border = "=" * width
10
+
11
+ header_lines = [
12
+ border,
13
+ "",
14
+ company_name.center(width),
15
+ "",
16
+ "INVOICE".center(width),
17
+ "",
18
+ f"Date: {date}".center(width),
19
+ "",
20
+ border
21
+ ]
22
+
23
+ report = "\n".join(header_lines)
24
+
25
+ result = {
26
+ 'report': report
27
+ }
28
+
29
+ return result
30
+
31
+ except Exception as e:
32
+ result = {
33
+ 'report': f"Error generating invoice header: {str(e)}"
34
+ }
35
+ return result
@@ -0,0 +1,44 @@
1
+ async def main():
2
+ try:
3
+ # Get data from previous step if available, otherwise use provided data
4
+ previous_data = {'name': 'John', 'age': 30, 'city': 'NYC'}
5
+
6
+ # Check if we have previous step results
7
+ try:
8
+ if 'step0' in previous_step_results:
9
+ previous_data = previous_step_results['step0']
10
+ except NameError:
11
+ pass
12
+
13
+ name = previous_data.get('name', 'John')
14
+ age = previous_data.get('age', 30)
15
+ city = previous_data.get('city', 'NYC')
16
+
17
+ # Create formatted text report
18
+ report_lines = [
19
+ "=" * 40,
20
+ "PERSON INFORMATION REPORT",
21
+ "=" * 40,
22
+ "",
23
+ f"{'Name:':<15} {name}",
24
+ f"{'Age:':<15} {age}",
25
+ f"{'City:':<15} {city}",
26
+ "",
27
+ "-" * 40,
28
+ f"Report generated successfully",
29
+ "=" * 40
30
+ ]
31
+
32
+ report = "\n".join(report_lines)
33
+
34
+ result = {
35
+ 'report': report
36
+ }
37
+
38
+ return result
39
+
40
+ except Exception as e:
41
+ result = {
42
+ 'report': f"Error generating report: {str(e)}"
43
+ }
44
+ return result
@@ -0,0 +1,44 @@
1
+ async def main():
2
+ try:
3
+ # Get data from previous step if available, otherwise use provided defaults
4
+ previous_data = {'name': 'John', 'age': 30, 'city': 'NYC'}
5
+
6
+ # Check if we have previous step results
7
+ try:
8
+ if 'step0' in globals().get('previous_step_results', {}):
9
+ previous_data = previous_step_results['step0']
10
+ except:
11
+ pass
12
+
13
+ # Extract person data
14
+ name = previous_data.get('name', 'John')
15
+ age = previous_data.get('age', 30)
16
+ city = previous_data.get('city', 'NYC')
17
+
18
+ # Create formatted text report
19
+ report_lines = [
20
+ "=" * 40,
21
+ "PERSON INFORMATION REPORT",
22
+ "=" * 40,
23
+ "",
24
+ f"Name: {name}",
25
+ f"Age: {age}",
26
+ f"City: {city}",
27
+ "",
28
+ "-" * 40,
29
+ f"Generated for: {name}",
30
+ "=" * 40
31
+ ]
32
+
33
+ report = "\n".join(report_lines)
34
+
35
+ result = {
36
+ 'report': report
37
+ }
38
+
39
+ return result
40
+
41
+ except Exception as e:
42
+ return {
43
+ 'report': f"Error generating report: {str(e)}"
44
+ }
@@ -0,0 +1,40 @@
1
+ def main():
2
+ # Input product list
3
+ product_string = "Widget=$10, Gadget=$25, Tool=$15"
4
+
5
+ try:
6
+ # Split the string by comma and strip whitespace
7
+ products = [item.strip() for item in product_string.split(',')]
8
+
9
+ # Create bulleted list
10
+ bulleted_items = []
11
+ for product in products:
12
+ # Split by '=' to separate name and price
13
+ parts = product.split('=')
14
+ if len(parts) == 2:
15
+ name = parts[0].strip()
16
+ price = parts[1].strip()
17
+ bulleted_items.append(f"• {name}: {price}")
18
+ else:
19
+ bulleted_items.append(f"• {product}")
20
+
21
+ # Join into final bulleted text
22
+ bulleted_text = '\n'.join(bulleted_items)
23
+
24
+ result = {
25
+ 'original': product_string,
26
+ 'bulleted_list': bulleted_text,
27
+ 'item_count': len(bulleted_items),
28
+ 'items': bulleted_items
29
+ }
30
+
31
+ return result
32
+
33
+ except Exception as e:
34
+ return {
35
+ 'error': str(e),
36
+ 'original': product_string,
37
+ 'bulleted_list': None
38
+ }
39
+
40
+ result = main()
@@ -0,0 +1,37 @@
1
+ async def main():
2
+ try:
3
+ # Input product list
4
+ product_string = "Widget=$10, Gadget=$25, Tool=$15"
5
+
6
+ # Parse the product list
7
+ products = product_string.split(", ")
8
+
9
+ # Format as bulleted list
10
+ bulleted_lines = []
11
+ for product in products:
12
+ # Split by = to get name and price
13
+ parts = product.split("=")
14
+ if len(parts) == 2:
15
+ name = parts[0].strip()
16
+ price = parts[1].strip()
17
+ bulleted_lines.append(f"• {name}: {price}")
18
+
19
+ # Join into final bulleted text
20
+ bulleted_text = "\n".join(bulleted_lines)
21
+
22
+ result = {
23
+ "original": product_string,
24
+ "bulleted_list": bulleted_text,
25
+ "item_count": len(bulleted_lines),
26
+ "items": [{"name": p.split("=")[0].strip(), "price": p.split("=")[1].strip()} for p in products]
27
+ }
28
+
29
+ return result
30
+
31
+ except Exception as e:
32
+ result = {
33
+ "error": str(e),
34
+ "bulleted_list": "",
35
+ "item_count": 0
36
+ }
37
+ return result
@@ -0,0 +1,13 @@
1
+ async def main():
2
+ words = ["apple", "banana", "cherry", "date", "elderberry"]
3
+
4
+ word_lengths = {word: len(word) for word in words}
5
+ total_characters = sum(word_lengths.values())
6
+
7
+ result = {
8
+ "words": words,
9
+ "individual_lengths": word_lengths,
10
+ "total_characters": total_characters
11
+ }
12
+
13
+ return result
@@ -0,0 +1,42 @@
1
+ def main():
2
+ # Input product list
3
+ product_string = "Widget=$10, Gadget=$25, Tool=$15"
4
+
5
+ try:
6
+ # Split the string by comma and strip whitespace
7
+ products = [item.strip() for item in product_string.split(",")]
8
+
9
+ # Create bulleted list
10
+ bulleted_items = []
11
+ for product in products:
12
+ # Split by = to get name and price
13
+ parts = product.split("=")
14
+ if len(parts) == 2:
15
+ name = parts[0].strip()
16
+ price = parts[1].strip()
17
+ bulleted_items.append(f"• {name}: {price}")
18
+ else:
19
+ bulleted_items.append(f"• {product}")
20
+
21
+ # Join into final bulleted text
22
+ bulleted_text = "\n".join(bulleted_items)
23
+
24
+ result = {
25
+ "original": product_string,
26
+ "bulleted_list": bulleted_text,
27
+ "item_count": len(bulleted_items),
28
+ "items": bulleted_items
29
+ }
30
+
31
+ return result
32
+
33
+ except Exception as e:
34
+ return {
35
+ "error": str(e),
36
+ "original": product_string,
37
+ "bulleted_list": "",
38
+ "item_count": 0,
39
+ "items": []
40
+ }
41
+
42
+ result = main()
@@ -0,0 +1,13 @@
1
+ async def main():
2
+ words = ["apple", "banana", "cherry", "date", "elderberry"]
3
+
4
+ word_lengths = {word: len(word) for word in words}
5
+ total_characters = sum(word_lengths.values())
6
+
7
+ result = {
8
+ "words": words,
9
+ "individual_lengths": word_lengths,
10
+ "total_characters": total_characters
11
+ }
12
+
13
+ return result
@@ -0,0 +1,13 @@
1
+ async def main():
2
+ words = ["apple", "banana", "cherry", "date", "elderberry"]
3
+
4
+ word_lengths = {word: len(word) for word in words}
5
+ total_characters = sum(word_lengths.values())
6
+
7
+ result = {
8
+ "words": words,
9
+ "individual_lengths": word_lengths,
10
+ "total_characters": total_characters
11
+ }
12
+
13
+ return result
@@ -0,0 +1,124 @@
1
+ """
2
+ Test 1: Standalone Analyst
3
+
4
+ The Analyst agent working alone - no framework.
5
+ Can analyze data, but cannot receive requests from other agents.
6
+ """
7
+
8
+
9
+ class Analyst:
10
+ """
11
+ Standalone Analyst agent.
12
+
13
+ Capabilities:
14
+ - Analyze data
15
+ - Generate reports
16
+ - Provide recommendations
17
+ """
18
+
19
+ def __init__(self):
20
+ self.name = "analyst"
21
+ self.analyses_count = 0
22
+
23
+ def analyze(self, data: str) -> dict:
24
+ """Analyze data and return insights."""
25
+ self.analyses_count += 1
26
+ return {
27
+ "id": self.analyses_count,
28
+ "input": data,
29
+ "summary": f"Analysis of '{data}' shows positive trends",
30
+ "confidence": 0.85,
31
+ "recommendation": "Proceed with caution"
32
+ }
33
+
34
+ def generate_report(self, analysis: dict) -> str:
35
+ """Generate a text report from analysis."""
36
+ return (
37
+ f"Report #{analysis['id']}\n"
38
+ f"Summary: {analysis['summary']}\n"
39
+ f"Confidence: {analysis['confidence']}\n"
40
+ f"Recommendation: {analysis['recommendation']}"
41
+ )
42
+
43
+
44
+ # ═══════════════════════════════════════════════════════════════════════════════
45
+ # TESTS
46
+ # ═══════════════════════════════════════════════════════════════════════════════
47
+
48
+ def test_analyst_init():
49
+ """Analyst initializes correctly."""
50
+ analyst = Analyst()
51
+ assert analyst.name == "analyst"
52
+ assert analyst.analyses_count == 0
53
+ print("✓ Analyst initialized")
54
+
55
+
56
+ def test_analyst_analyze():
57
+ """Analyst can analyze data."""
58
+ analyst = Analyst()
59
+ result = analyst.analyze("Q4 sales data")
60
+
61
+ assert result["id"] == 1
62
+ assert result["confidence"] == 0.85
63
+ assert "Q4 sales data" in result["summary"]
64
+ print(f"✓ Analysis: {result['summary']}")
65
+
66
+
67
+ def test_analyst_multiple_analyses():
68
+ """Analyst tracks analysis count."""
69
+ analyst = Analyst()
70
+
71
+ analyst.analyze("data 1")
72
+ analyst.analyze("data 2")
73
+ result = analyst.analyze("data 3")
74
+
75
+ assert analyst.analyses_count == 3
76
+ assert result["id"] == 3
77
+ print(f"✓ Multiple analyses: count = {analyst.analyses_count}")
78
+
79
+
80
+ def test_analyst_generate_report():
81
+ """Analyst can generate reports."""
82
+ analyst = Analyst()
83
+ analysis = analyst.analyze("market trends")
84
+ report = analyst.generate_report(analysis)
85
+
86
+ assert "Report #1" in report
87
+ assert "market trends" in report
88
+ print(f"✓ Report generated:\n{report}")
89
+
90
+
91
+ def test_analyst_cannot_receive_requests():
92
+ """Analyst has NO way to receive external requests."""
93
+ analyst = Analyst()
94
+
95
+ # No peers
96
+ assert not hasattr(analyst, 'peers')
97
+
98
+ # No receive method
99
+ assert not hasattr(analyst, 'receive')
100
+
101
+ # No way to listen for incoming messages
102
+ assert not hasattr(analyst, 'run')
103
+
104
+ print("✓ Analyst CANNOT receive external requests (limitation)")
105
+
106
+
107
+ # ═══════════════════════════════════════════════════════════════════════════════
108
+ # RUN
109
+ # ═══════════════════════════════════════════════════════════════════════════════
110
+
111
+ if __name__ == "__main__":
112
+ print("\n" + "="*60)
113
+ print("TEST 1: STANDALONE ANALYST")
114
+ print("="*60 + "\n")
115
+
116
+ test_analyst_init()
117
+ test_analyst_analyze()
118
+ test_analyst_multiple_analyses()
119
+ test_analyst_generate_report()
120
+ test_analyst_cannot_receive_requests()
121
+
122
+ print("\n" + "-"*60)
123
+ print("Analyst works, but cannot receive requests from others.")
124
+ print("-"*60 + "\n")