pygeai 0.6.0b7__py3-none-any.whl → 0.6.0b10__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 (178) hide show
  1. pygeai/_docs/source/conf.py +78 -6
  2. pygeai/_docs/source/content/api_reference/embeddings.rst +31 -1
  3. pygeai/_docs/source/content/api_reference/evaluation.rst +590 -0
  4. pygeai/_docs/source/content/api_reference/feedback.rst +237 -0
  5. pygeai/_docs/source/content/api_reference/files.rst +592 -0
  6. pygeai/_docs/source/content/api_reference/gam.rst +401 -0
  7. pygeai/_docs/source/content/api_reference/proxy.rst +318 -0
  8. pygeai/_docs/source/content/api_reference/secrets.rst +495 -0
  9. pygeai/_docs/source/content/api_reference/usage_limits.rst +390 -0
  10. pygeai/_docs/source/content/api_reference.rst +7 -0
  11. pygeai/_docs/source/content/debugger.rst +376 -83
  12. pygeai/_docs/source/content/migration.rst +528 -0
  13. pygeai/_docs/source/content/modules.rst +1 -1
  14. pygeai/_docs/source/pygeai.cli.rst +8 -0
  15. pygeai/_docs/source/pygeai.tests.cli.rst +16 -0
  16. pygeai/_docs/source/pygeai.tests.core.embeddings.rst +16 -0
  17. pygeai/_docs/source/pygeai.tests.snippets.chat.rst +40 -0
  18. pygeai/_docs/source/pygeai.tests.snippets.dbg.rst +45 -0
  19. pygeai/_docs/source/pygeai.tests.snippets.embeddings.rst +40 -0
  20. pygeai/_docs/source/pygeai.tests.snippets.evaluation.dataset.rst +197 -0
  21. pygeai/_docs/source/pygeai.tests.snippets.evaluation.plan.rst +133 -0
  22. pygeai/_docs/source/pygeai.tests.snippets.evaluation.result.rst +37 -0
  23. pygeai/_docs/source/pygeai.tests.snippets.evaluation.rst +10 -0
  24. pygeai/_docs/source/pygeai.tests.snippets.rst +1 -0
  25. pygeai/admin/clients.py +5 -0
  26. pygeai/assistant/clients.py +7 -0
  27. pygeai/assistant/data_analyst/clients.py +2 -0
  28. pygeai/assistant/rag/clients.py +11 -0
  29. pygeai/chat/clients.py +191 -25
  30. pygeai/chat/endpoints.py +2 -1
  31. pygeai/cli/commands/chat.py +227 -1
  32. pygeai/cli/commands/embeddings.py +56 -8
  33. pygeai/cli/commands/migrate.py +994 -434
  34. pygeai/cli/error_handler.py +116 -0
  35. pygeai/cli/geai.py +28 -10
  36. pygeai/cli/parsers.py +8 -2
  37. pygeai/core/base/clients.py +3 -1
  38. pygeai/core/common/exceptions.py +11 -10
  39. pygeai/core/embeddings/__init__.py +19 -0
  40. pygeai/core/embeddings/clients.py +17 -2
  41. pygeai/core/embeddings/mappers.py +16 -2
  42. pygeai/core/embeddings/responses.py +9 -2
  43. pygeai/core/feedback/clients.py +1 -0
  44. pygeai/core/files/clients.py +5 -7
  45. pygeai/core/files/managers.py +42 -0
  46. pygeai/core/llm/clients.py +4 -0
  47. pygeai/core/plugins/clients.py +1 -0
  48. pygeai/core/rerank/clients.py +1 -0
  49. pygeai/core/secrets/clients.py +6 -0
  50. pygeai/core/services/rest.py +1 -1
  51. pygeai/dbg/__init__.py +3 -0
  52. pygeai/dbg/debugger.py +565 -70
  53. pygeai/evaluation/clients.py +1 -1
  54. pygeai/evaluation/dataset/clients.py +45 -44
  55. pygeai/evaluation/plan/clients.py +27 -26
  56. pygeai/evaluation/result/clients.py +37 -5
  57. pygeai/gam/clients.py +4 -0
  58. pygeai/health/clients.py +1 -0
  59. pygeai/lab/agents/clients.py +8 -1
  60. pygeai/lab/models.py +3 -3
  61. pygeai/lab/processes/clients.py +21 -0
  62. pygeai/lab/strategies/clients.py +4 -0
  63. pygeai/lab/tools/clients.py +1 -0
  64. pygeai/migration/__init__.py +31 -0
  65. pygeai/migration/strategies.py +404 -155
  66. pygeai/migration/tools.py +170 -3
  67. pygeai/organization/clients.py +13 -0
  68. pygeai/organization/limits/clients.py +15 -0
  69. pygeai/proxy/clients.py +3 -1
  70. pygeai/tests/admin/test_clients.py +16 -11
  71. pygeai/tests/assistants/rag/test_clients.py +35 -23
  72. pygeai/tests/assistants/test_clients.py +22 -15
  73. pygeai/tests/auth/test_clients.py +14 -6
  74. pygeai/tests/chat/test_clients.py +211 -1
  75. pygeai/tests/cli/commands/test_embeddings.py +32 -9
  76. pygeai/tests/cli/commands/test_evaluation.py +7 -0
  77. pygeai/tests/cli/commands/test_migrate.py +112 -243
  78. pygeai/tests/cli/test_error_handler.py +225 -0
  79. pygeai/tests/cli/test_geai_driver.py +154 -0
  80. pygeai/tests/cli/test_parsers.py +5 -5
  81. pygeai/tests/core/embeddings/test_clients.py +144 -0
  82. pygeai/tests/core/embeddings/test_managers.py +171 -0
  83. pygeai/tests/core/embeddings/test_mappers.py +142 -0
  84. pygeai/tests/core/feedback/test_clients.py +2 -0
  85. pygeai/tests/core/files/test_clients.py +1 -0
  86. pygeai/tests/core/llm/test_clients.py +14 -9
  87. pygeai/tests/core/plugins/test_clients.py +5 -3
  88. pygeai/tests/core/rerank/test_clients.py +1 -0
  89. pygeai/tests/core/secrets/test_clients.py +19 -13
  90. pygeai/tests/dbg/test_debugger.py +453 -75
  91. pygeai/tests/evaluation/dataset/test_clients.py +3 -1
  92. pygeai/tests/evaluation/plan/test_clients.py +4 -2
  93. pygeai/tests/evaluation/result/test_clients.py +7 -5
  94. pygeai/tests/gam/test_clients.py +1 -1
  95. pygeai/tests/health/test_clients.py +1 -0
  96. pygeai/tests/lab/agents/test_clients.py +9 -0
  97. pygeai/tests/lab/processes/test_clients.py +36 -0
  98. pygeai/tests/lab/processes/test_mappers.py +3 -0
  99. pygeai/tests/lab/strategies/test_clients.py +14 -9
  100. pygeai/tests/migration/test_strategies.py +45 -218
  101. pygeai/tests/migration/test_tools.py +133 -9
  102. pygeai/tests/organization/limits/test_clients.py +17 -0
  103. pygeai/tests/organization/test_clients.py +22 -0
  104. pygeai/tests/proxy/test_clients.py +2 -0
  105. pygeai/tests/proxy/test_integration.py +1 -0
  106. pygeai/tests/snippets/chat/chat_completion_with_reasoning_effort.py +18 -0
  107. pygeai/tests/snippets/chat/get_response.py +15 -0
  108. pygeai/tests/snippets/chat/get_response_streaming.py +20 -0
  109. pygeai/tests/snippets/chat/get_response_with_files.py +16 -0
  110. pygeai/tests/snippets/chat/get_response_with_tools.py +36 -0
  111. pygeai/tests/snippets/dbg/__init__.py +0 -0
  112. pygeai/tests/snippets/dbg/basic_debugging.py +32 -0
  113. pygeai/tests/snippets/dbg/breakpoint_management.py +48 -0
  114. pygeai/tests/snippets/dbg/stack_navigation.py +45 -0
  115. pygeai/tests/snippets/dbg/stepping_example.py +40 -0
  116. pygeai/tests/snippets/embeddings/cache_example.py +31 -0
  117. pygeai/tests/snippets/embeddings/cohere_example.py +41 -0
  118. pygeai/tests/snippets/embeddings/openai_base64_example.py +27 -0
  119. pygeai/tests/snippets/embeddings/openai_example.py +30 -0
  120. pygeai/tests/snippets/embeddings/similarity_example.py +42 -0
  121. pygeai/tests/snippets/evaluation/dataset/__init__.py +0 -0
  122. pygeai/tests/snippets/evaluation/dataset/complete_workflow_example.py +195 -0
  123. pygeai/tests/snippets/evaluation/dataset/create_dataset.py +26 -0
  124. pygeai/tests/snippets/evaluation/dataset/create_dataset_from_file.py +11 -0
  125. pygeai/tests/snippets/evaluation/dataset/create_dataset_row.py +17 -0
  126. pygeai/tests/snippets/evaluation/dataset/create_expected_source.py +18 -0
  127. pygeai/tests/snippets/evaluation/dataset/create_filter_variable.py +19 -0
  128. pygeai/tests/snippets/evaluation/dataset/delete_dataset.py +9 -0
  129. pygeai/tests/snippets/evaluation/dataset/delete_dataset_row.py +10 -0
  130. pygeai/tests/snippets/evaluation/dataset/delete_expected_source.py +15 -0
  131. pygeai/tests/snippets/evaluation/dataset/delete_filter_variable.py +15 -0
  132. pygeai/tests/snippets/evaluation/dataset/get_dataset.py +9 -0
  133. pygeai/tests/snippets/evaluation/dataset/get_dataset_row.py +10 -0
  134. pygeai/tests/snippets/evaluation/dataset/get_expected_source.py +15 -0
  135. pygeai/tests/snippets/evaluation/dataset/get_filter_variable.py +15 -0
  136. pygeai/tests/snippets/evaluation/dataset/list_dataset_rows.py +9 -0
  137. pygeai/tests/snippets/evaluation/dataset/list_datasets.py +6 -0
  138. pygeai/tests/snippets/evaluation/dataset/list_expected_sources.py +10 -0
  139. pygeai/tests/snippets/evaluation/dataset/list_filter_variables.py +10 -0
  140. pygeai/tests/snippets/evaluation/dataset/update_dataset.py +15 -0
  141. pygeai/tests/snippets/evaluation/dataset/update_dataset_row.py +20 -0
  142. pygeai/tests/snippets/evaluation/dataset/update_expected_source.py +18 -0
  143. pygeai/tests/snippets/evaluation/dataset/update_filter_variable.py +19 -0
  144. pygeai/tests/snippets/evaluation/dataset/upload_dataset_rows_file.py +10 -0
  145. pygeai/tests/snippets/evaluation/plan/__init__.py +0 -0
  146. pygeai/tests/snippets/evaluation/plan/add_plan_system_metric.py +13 -0
  147. pygeai/tests/snippets/evaluation/plan/complete_workflow_example.py +136 -0
  148. pygeai/tests/snippets/evaluation/plan/create_evaluation_plan.py +24 -0
  149. pygeai/tests/snippets/evaluation/plan/create_rag_evaluation_plan.py +22 -0
  150. pygeai/tests/snippets/evaluation/plan/delete_evaluation_plan.py +9 -0
  151. pygeai/tests/snippets/evaluation/plan/delete_plan_system_metric.py +13 -0
  152. pygeai/tests/snippets/evaluation/plan/execute_evaluation_plan.py +11 -0
  153. pygeai/tests/snippets/evaluation/plan/get_evaluation_plan.py +9 -0
  154. pygeai/tests/snippets/evaluation/plan/get_plan_system_metric.py +13 -0
  155. pygeai/tests/snippets/evaluation/plan/get_system_metric.py +9 -0
  156. pygeai/tests/snippets/evaluation/plan/list_evaluation_plans.py +7 -0
  157. pygeai/tests/snippets/evaluation/plan/list_plan_system_metrics.py +9 -0
  158. pygeai/tests/snippets/evaluation/plan/list_system_metrics.py +7 -0
  159. pygeai/tests/snippets/evaluation/plan/update_evaluation_plan.py +22 -0
  160. pygeai/tests/snippets/evaluation/plan/update_plan_system_metric.py +14 -0
  161. pygeai/tests/snippets/evaluation/result/__init__.py +0 -0
  162. pygeai/tests/snippets/evaluation/result/complete_workflow_example.py +150 -0
  163. pygeai/tests/snippets/evaluation/result/get_evaluation_result.py +26 -0
  164. pygeai/tests/snippets/evaluation/result/list_evaluation_results.py +17 -0
  165. pygeai/tests/snippets/migrate/__init__.py +45 -0
  166. pygeai/tests/snippets/migrate/agent_migration.py +110 -0
  167. pygeai/tests/snippets/migrate/assistant_migration.py +64 -0
  168. pygeai/tests/snippets/migrate/orchestrator_examples.py +179 -0
  169. pygeai/tests/snippets/migrate/process_migration.py +64 -0
  170. pygeai/tests/snippets/migrate/project_migration.py +42 -0
  171. pygeai/tests/snippets/migrate/tool_migration.py +64 -0
  172. pygeai/tests/snippets/organization/create_project.py +2 -2
  173. {pygeai-0.6.0b7.dist-info → pygeai-0.6.0b10.dist-info}/METADATA +1 -1
  174. {pygeai-0.6.0b7.dist-info → pygeai-0.6.0b10.dist-info}/RECORD +178 -96
  175. {pygeai-0.6.0b7.dist-info → pygeai-0.6.0b10.dist-info}/WHEEL +0 -0
  176. {pygeai-0.6.0b7.dist-info → pygeai-0.6.0b10.dist-info}/entry_points.txt +0 -0
  177. {pygeai-0.6.0b7.dist-info → pygeai-0.6.0b10.dist-info}/licenses/LICENSE +0 -0
  178. {pygeai-0.6.0b7.dist-info → pygeai-0.6.0b10.dist-info}/top_level.txt +0 -0
@@ -1,7 +1,7 @@
1
1
  import unittest
2
2
  from unittest.mock import Mock
3
3
 
4
- from pygeai.migration.tools import MigrationTool
4
+ from pygeai.migration.tools import MigrationTool, MigrationPlan, MigrationOrchestrator
5
5
  from pygeai.migration.strategies import MigrationStrategy
6
6
 
7
7
 
@@ -11,25 +11,149 @@ class TestMigrationTool(unittest.TestCase):
11
11
  """
12
12
 
13
13
  def setUp(self):
14
- """Set up test fixtures"""
15
14
  self.mock_strategy = Mock(spec=MigrationStrategy)
16
15
 
17
16
  def test_migration_tool_initialization(self):
18
- """Test MigrationTool initialization with a strategy"""
19
17
  tool = MigrationTool(self.mock_strategy)
20
- self.assertEqual(tool.strategy, self.mock_strategy)
18
+ self.assertEqual(tool._strategy, self.mock_strategy)
21
19
 
22
20
  def test_migration_tool_set_strategy(self):
23
- """Test setting a new strategy on MigrationTool"""
24
21
  tool = MigrationTool(self.mock_strategy)
25
22
  new_strategy = Mock(spec=MigrationStrategy)
26
23
  tool.set_strategy(new_strategy)
27
-
28
- self.assertEqual(tool.strategy, new_strategy)
24
+ self.assertEqual(tool._strategy, new_strategy)
29
25
 
30
26
  def test_migration_tool_run_migration(self):
31
- """Test running migration with the strategy"""
32
27
  tool = MigrationTool(self.mock_strategy)
33
28
  tool.run_migration()
29
+ self.mock_strategy.migrate.assert_called_once()
30
+
31
+
32
+ class TestMigrationPlan(unittest.TestCase):
33
+ """
34
+ python -m unittest pygeai.tests.migration.test_tools.TestMigrationPlan
35
+ """
36
+
37
+ def test_migration_plan_initialization(self):
38
+ strategies = [Mock(spec=MigrationStrategy), Mock(spec=MigrationStrategy)]
39
+ plan = MigrationPlan(strategies=strategies)
40
+ self.assertEqual(len(plan.strategies), 2)
41
+ self.assertEqual(plan.dependencies, {})
42
+ self.assertFalse(plan.dry_run)
43
+ self.assertTrue(plan.stop_on_error)
44
+
45
+ def test_migration_plan_with_dependencies(self):
46
+ strategies = [Mock(spec=MigrationStrategy), Mock(spec=MigrationStrategy)]
47
+ dependencies = {1: [0]}
48
+ plan = MigrationPlan(strategies=strategies, dependencies=dependencies)
49
+ self.assertEqual(plan.dependencies, {1: [0]})
50
+
51
+
52
+ class TestMigrationOrchestrator(unittest.TestCase):
53
+ """
54
+ python -m unittest pygeai.tests.migration.test_tools.TestMigrationOrchestrator
55
+ """
56
+
57
+ def setUp(self):
58
+ self.strategy1 = Mock(spec=MigrationStrategy)
59
+ self.strategy2 = Mock(spec=MigrationStrategy)
60
+ self.strategy3 = Mock(spec=MigrationStrategy)
61
+
62
+ def test_orchestrator_simple_execution(self):
63
+ plan = MigrationPlan(strategies=[self.strategy1, self.strategy2])
64
+ orchestrator = MigrationOrchestrator(plan)
65
+
66
+ result = orchestrator.execute()
67
+
68
+ self.strategy1.migrate.assert_called_once()
69
+ self.strategy2.migrate.assert_called_once()
70
+ self.assertEqual(result['total'], 2)
71
+ self.assertEqual(result['completed'], 2)
72
+ self.assertEqual(result['failed'], 0)
73
+ self.assertEqual(result['success_rate'], 1.0)
74
+
75
+ def test_orchestrator_with_dependencies(self):
76
+ plan = MigrationPlan(
77
+ strategies=[self.strategy1, self.strategy2, self.strategy3],
78
+ dependencies={1: [0], 2: [1]}
79
+ )
80
+ orchestrator = MigrationOrchestrator(plan)
81
+
82
+ result = orchestrator.execute()
83
+
84
+ self.assertEqual(result['completed'], 3)
85
+ self.assertEqual(result['completed_indices'], [0, 1, 2])
86
+
87
+ def test_orchestrator_stop_on_error(self):
88
+ self.strategy1.migrate.side_effect = Exception("Migration failed")
89
+ plan = MigrationPlan(
90
+ strategies=[self.strategy1, self.strategy2],
91
+ stop_on_error=True
92
+ )
93
+ orchestrator = MigrationOrchestrator(plan)
94
+
95
+ with self.assertRaises(ValueError) as context:
96
+ orchestrator.execute()
97
+
98
+ self.assertIn("Migration failed at strategy", str(context.exception))
99
+ self.strategy1.migrate.assert_called_once()
100
+ self.strategy2.migrate.assert_not_called()
101
+
102
+ def test_orchestrator_continue_on_error(self):
103
+ self.strategy1.migrate.side_effect = Exception("Migration failed")
104
+ plan = MigrationPlan(
105
+ strategies=[self.strategy1, self.strategy2],
106
+ stop_on_error=False
107
+ )
108
+ orchestrator = MigrationOrchestrator(plan)
109
+
110
+ result = orchestrator.execute()
111
+
112
+ self.strategy1.migrate.assert_called_once()
113
+ self.strategy2.migrate.assert_called_once()
114
+ self.assertEqual(result['completed'], 1)
115
+ self.assertEqual(result['failed'], 1)
116
+ self.assertEqual(result['success_rate'], 0.5)
117
+
118
+ def test_orchestrator_dry_run(self):
119
+ plan = MigrationPlan(
120
+ strategies=[self.strategy1, self.strategy2],
121
+ dry_run=True
122
+ )
123
+ orchestrator = MigrationOrchestrator(plan)
124
+
125
+ result = orchestrator.execute()
126
+
127
+ self.strategy1.migrate.assert_not_called()
128
+ self.strategy2.migrate.assert_not_called()
129
+ self.assertTrue(result['valid'])
130
+ self.assertEqual(result['execution_order'], [0, 1])
131
+
132
+ def test_orchestrator_circular_dependency(self):
133
+ plan = MigrationPlan(
134
+ strategies=[self.strategy1, self.strategy2],
135
+ dependencies={0: [1], 1: [0]}
136
+ )
137
+ orchestrator = MigrationOrchestrator(plan)
138
+
139
+ with self.assertRaises(ValueError) as context:
140
+ orchestrator.execute()
141
+
142
+ self.assertIn("Circular dependency", str(context.exception))
143
+
144
+ def test_orchestrator_dry_run_circular_dependency(self):
145
+ plan = MigrationPlan(
146
+ strategies=[self.strategy1, self.strategy2],
147
+ dependencies={0: [1], 1: [0]},
148
+ dry_run=True
149
+ )
150
+ orchestrator = MigrationOrchestrator(plan)
151
+
152
+ result = orchestrator.execute()
153
+
154
+ self.assertFalse(result['valid'])
155
+ self.assertIn("Circular dependency", result['error'])
156
+
34
157
 
35
- self.mock_strategy.migrate.assert_called_once()
158
+ if __name__ == '__main__':
159
+ unittest.main()
@@ -47,6 +47,7 @@ class TestUsageLimitClient(unittest.TestCase):
47
47
  def test_set_organization_usage_limit_success(self, mock_post):
48
48
  mock_response = mock_post.return_value
49
49
  mock_response.json.return_value = self.valid_response
50
+ mock_response.status_code = 200
50
51
 
51
52
  result = self.client.set_organization_usage_limit(self.organization, self.valid_usage_limit)
52
53
 
@@ -79,6 +80,7 @@ class TestUsageLimitClient(unittest.TestCase):
79
80
  invalid_usage_limit["renewalStatus"] = "InvalidStatus"
80
81
  mock_response = mock_post.return_value
81
82
  mock_response.json.return_value = {"error": "Invalid renewal status"}
83
+ mock_response.status_code = 200
82
84
 
83
85
  result = self.client.set_organization_usage_limit(self.organization, invalid_usage_limit)
84
86
 
@@ -94,6 +96,7 @@ class TestUsageLimitClient(unittest.TestCase):
94
96
  def test_get_organization_latest_usage_limit_success(self, mock_get):
95
97
  mock_response = mock_get.return_value
96
98
  mock_response.json.return_value = self.valid_response
99
+ mock_response.status_code = 200
97
100
 
98
101
  result = self.client.get_organization_latest_usage_limit(self.organization)
99
102
 
@@ -123,6 +126,7 @@ class TestUsageLimitClient(unittest.TestCase):
123
126
  response = {"limits": [self.valid_response]}
124
127
  mock_response = mock_get.return_value
125
128
  mock_response.json.return_value = response
129
+ mock_response.status_code = 200
126
130
 
127
131
  result = self.client.get_all_usage_limits_from_organization(self.organization)
128
132
 
@@ -153,6 +157,7 @@ class TestUsageLimitClient(unittest.TestCase):
153
157
  response = {"status": "deleted"}
154
158
  mock_response = mock_delete.return_value
155
159
  mock_response.json.return_value = response
160
+ mock_response.status_code = 200
156
161
 
157
162
  result = self.client.delete_usage_limit_from_organization(self.organization, self.limit_id)
158
163
 
@@ -183,6 +188,7 @@ class TestUsageLimitClient(unittest.TestCase):
183
188
  response["hardLimit"] = hard_limit
184
189
  mock_response = mock_put.return_value
185
190
  mock_response.json.return_value = response
191
+ mock_response.status_code = 200
186
192
 
187
193
  result = self.client.set_organization_hard_limit(self.organization, self.limit_id, hard_limit)
188
194
 
@@ -217,6 +223,7 @@ class TestUsageLimitClient(unittest.TestCase):
217
223
  response["softLimit"] = soft_limit
218
224
  mock_response = mock_put.return_value
219
225
  mock_response.json.return_value = response
226
+ mock_response.status_code = 200
220
227
 
221
228
  result = self.client.set_organization_soft_limit(self.organization, self.limit_id, soft_limit)
222
229
 
@@ -251,6 +258,7 @@ class TestUsageLimitClient(unittest.TestCase):
251
258
  response["renewalStatus"] = renewal_status
252
259
  mock_response = mock_put.return_value
253
260
  mock_response.json.return_value = response
261
+ mock_response.status_code = 200
254
262
 
255
263
  result = self.client.set_organization_renewal_status(self.organization, self.limit_id, renewal_status)
256
264
 
@@ -282,6 +290,7 @@ class TestUsageLimitClient(unittest.TestCase):
282
290
  def test_set_project_usage_limit_success(self, mock_post):
283
291
  mock_response = mock_post.return_value
284
292
  mock_response.json.return_value = self.valid_response
293
+ mock_response.status_code = 200
285
294
 
286
295
  result = self.client.set_project_usage_limit(self.organization, self.project, self.valid_usage_limit)
287
296
 
@@ -314,6 +323,7 @@ class TestUsageLimitClient(unittest.TestCase):
314
323
  invalid_usage_limit["subscriptionType"] = "InvalidType"
315
324
  mock_response = mock_post.return_value
316
325
  mock_response.json.return_value = {"error": "Invalid subscription type"}
326
+ mock_response.status_code = 200
317
327
 
318
328
  result = self.client.set_project_usage_limit(self.organization, self.project, invalid_usage_limit)
319
329
 
@@ -330,6 +340,7 @@ class TestUsageLimitClient(unittest.TestCase):
330
340
  response = {"limits": [self.valid_response]}
331
341
  mock_response = mock_get.return_value
332
342
  mock_response.json.return_value = response
343
+ mock_response.status_code = 200
333
344
 
334
345
  result = self.client.get_all_usage_limits_from_project(self.organization, self.project)
335
346
 
@@ -359,6 +370,7 @@ class TestUsageLimitClient(unittest.TestCase):
359
370
  def test_get_latest_usage_limit_from_project_success(self, mock_get):
360
371
  mock_response = mock_get.return_value
361
372
  mock_response.json.return_value = self.valid_response
373
+ mock_response.status_code = 200
362
374
 
363
375
  result = self.client.get_latest_usage_limit_from_project(self.organization, self.project)
364
376
 
@@ -387,6 +399,7 @@ class TestUsageLimitClient(unittest.TestCase):
387
399
  def test_get_active_usage_limit_from_project_success(self, mock_get):
388
400
  mock_response = mock_get.return_value
389
401
  mock_response.json.return_value = self.valid_response
402
+ mock_response.status_code = 200
390
403
 
391
404
  result = self.client.get_active_usage_limit_from_project(self.organization, self.project)
392
405
 
@@ -416,6 +429,7 @@ class TestUsageLimitClient(unittest.TestCase):
416
429
  response = {"status": "deleted"}
417
430
  mock_response = mock_delete.return_value
418
431
  mock_response.json.return_value = response
432
+ mock_response.status_code = 200
419
433
 
420
434
  result = self.client.delete_usage_limit_from_project(self.organization, self.project, self.limit_id)
421
435
 
@@ -446,6 +460,7 @@ class TestUsageLimitClient(unittest.TestCase):
446
460
  response["hardLimit"] = hard_limit
447
461
  mock_response = mock_put.return_value
448
462
  mock_response.json.return_value = response
463
+ mock_response.status_code = 200
449
464
 
450
465
  result = self.client.set_hard_limit_for_active_usage_limit_from_project(
451
466
  self.organization, self.project, self.limit_id, hard_limit
@@ -484,6 +499,7 @@ class TestUsageLimitClient(unittest.TestCase):
484
499
  response["softLimit"] = soft_limit
485
500
  mock_response = mock_put.return_value
486
501
  mock_response.json.return_value = response
502
+ mock_response.status_code = 200
487
503
 
488
504
  result = self.client.set_soft_limit_for_active_usage_limit_from_project(
489
505
  self.organization, self.project, self.limit_id, soft_limit
@@ -522,6 +538,7 @@ class TestUsageLimitClient(unittest.TestCase):
522
538
  response["renewalStatus"] = renewal_status
523
539
  mock_response = mock_put.return_value
524
540
  mock_response.json.return_value = response
541
+ mock_response.status_code = 200
525
542
 
526
543
  result = self.client.set_project_renewal_status(self.organization, self.project, self.limit_id, renewal_status)
527
544
 
@@ -21,6 +21,7 @@ class TestOrganizationClient(unittest.TestCase):
21
21
  def test_get_assistant_list_success(self, mock_get):
22
22
  mock_response = mock_get.return_value
23
23
  mock_response.json.return_value = {"assistants": [{"name": "assistant1"}, {"name": "assistant2"}]}
24
+ mock_response.status_code = 200
24
25
 
25
26
  result = self.client.get_assistant_list(detail="summary")
26
27
 
@@ -47,6 +48,7 @@ class TestOrganizationClient(unittest.TestCase):
47
48
  def test_get_project_list_success(self, mock_get):
48
49
  mock_response = mock_get.return_value
49
50
  mock_response.json.return_value = {"projects": [{"name": "project1"}, {"name": "project2"}]}
51
+ mock_response.status_code = 200
50
52
 
51
53
  result = self.client.get_project_list(detail="summary")
52
54
 
@@ -60,6 +62,7 @@ class TestOrganizationClient(unittest.TestCase):
60
62
  def test_get_project_list_with_name(self, mock_get):
61
63
  mock_response = mock_get.return_value
62
64
  mock_response.json.return_value = {"projects": [{"name": "specific_project"}]}
65
+ mock_response.status_code = 200
63
66
 
64
67
  result = self.client.get_project_list(detail="full", name="specific_project")
65
68
 
@@ -88,6 +91,7 @@ class TestOrganizationClient(unittest.TestCase):
88
91
  def test_get_project_data_success(self, mock_get):
89
92
  mock_response = mock_get.return_value
90
93
  mock_response.json.return_value = {"project": {"id": "123", "name": "project1"}}
94
+ mock_response.status_code = 200
91
95
 
92
96
  result = self.client.get_project_data(project_id="123")
93
97
 
@@ -112,6 +116,7 @@ class TestOrganizationClient(unittest.TestCase):
112
116
  def test_create_project_success(self, mock_post):
113
117
  mock_response = mock_post.return_value
114
118
  mock_response.json.return_value = {"project": {"id": "123", "name": "project1"}}
119
+ mock_response.status_code = 200
115
120
 
116
121
  result = self.client.create_project(name="project1", email="admin@example.com", description="A test project")
117
122
 
@@ -130,6 +135,7 @@ class TestOrganizationClient(unittest.TestCase):
130
135
  def test_create_project_with_usage_limit(self, mock_post):
131
136
  mock_response = mock_post.return_value
132
137
  mock_response.json.return_value = {"project": {"id": "123", "name": "project1"}}
138
+ mock_response.status_code = 200
133
139
 
134
140
  usage_limit = {"type": "Requests", "threshold": 1000}
135
141
  result = self.client.create_project(
@@ -172,6 +178,7 @@ class TestOrganizationClient(unittest.TestCase):
172
178
  def test_update_project_success(self, mock_put):
173
179
  mock_response = mock_put.return_value
174
180
  mock_response.json.return_value = {"project": {"id": "123", "name": "updated_project"}}
181
+ mock_response.status_code = 200
175
182
 
176
183
  result = self.client.update_project(project_id="123", name="updated_project", description="Updated description")
177
184
 
@@ -202,6 +209,7 @@ class TestOrganizationClient(unittest.TestCase):
202
209
  def test_delete_project_success(self, mock_delete):
203
210
  mock_response = mock_delete.return_value
204
211
  mock_response.json.return_value = {"status": "deleted"}
212
+ mock_response.status_code = 200
205
213
 
206
214
  result = self.client.delete_project(project_id="123")
207
215
 
@@ -226,6 +234,7 @@ class TestOrganizationClient(unittest.TestCase):
226
234
  def test_get_project_tokens_success(self, mock_get):
227
235
  mock_response = mock_get.return_value
228
236
  mock_response.json.return_value = {"tokens": ["token1", "token2"]}
237
+ mock_response.status_code = 200
229
238
 
230
239
  result = self.client.get_project_tokens(project_id="123")
231
240
 
@@ -252,6 +261,7 @@ class TestOrganizationClient(unittest.TestCase):
252
261
  def test_export_request_data_success(self, mock_get):
253
262
  mock_response = mock_get.return_value
254
263
  mock_response.json.return_value = {"requests": [{"id": "1", "status": "pending"}]}
264
+ mock_response.status_code = 200
255
265
 
256
266
  result = self.client.export_request_data()
257
267
 
@@ -267,6 +277,7 @@ class TestOrganizationClient(unittest.TestCase):
267
277
  def test_export_request_data_with_params(self, mock_get):
268
278
  mock_response = mock_get.return_value
269
279
  mock_response.json.return_value = {"requests": [{"id": "1", "status": "completed"}]}
280
+ mock_response.status_code = 200
270
281
 
271
282
  result = self.client.export_request_data(assistant_name="assistant1", status="completed", skip=10, count=5)
272
283
 
@@ -298,6 +309,7 @@ class TestOrganizationClient(unittest.TestCase):
298
309
  def test_get_memberships_success(self, mock_get):
299
310
  mock_response = mock_get.return_value
300
311
  mock_response.json.return_value = {
312
+
301
313
  "count": 1,
302
314
  "pages": 1,
303
315
  "organizationsMemberships": [
@@ -308,6 +320,7 @@ class TestOrganizationClient(unittest.TestCase):
308
320
  }
309
321
  ]
310
322
  }
323
+ mock_response.status_code = 200
311
324
 
312
325
  result = self.client.get_memberships()
313
326
 
@@ -322,6 +335,7 @@ class TestOrganizationClient(unittest.TestCase):
322
335
  def test_get_memberships_with_params(self, mock_get):
323
336
  mock_response = mock_get.return_value
324
337
  mock_response.json.return_value = {"count": 0, "pages": 0, "organizationsMemberships": []}
338
+ mock_response.status_code = 200
325
339
 
326
340
  result = self.client.get_memberships(
327
341
  email="test@example.com",
@@ -361,6 +375,7 @@ class TestOrganizationClient(unittest.TestCase):
361
375
  def test_get_project_memberships_success(self, mock_get):
362
376
  mock_response = mock_get.return_value
363
377
  mock_response.json.return_value = {
378
+
364
379
  "count": 1,
365
380
  "pages": 1,
366
381
  "projectsMemberships": [
@@ -373,6 +388,7 @@ class TestOrganizationClient(unittest.TestCase):
373
388
  }
374
389
  ]
375
390
  }
391
+ mock_response.status_code = 200
376
392
 
377
393
  result = self.client.get_project_memberships()
378
394
 
@@ -399,10 +415,12 @@ class TestOrganizationClient(unittest.TestCase):
399
415
  def test_get_project_roles_success(self, mock_get):
400
416
  mock_response = mock_get.return_value
401
417
  mock_response.json.return_value = {
418
+
402
419
  "roles": [
403
420
  {"id": "role-1", "name": "Admin", "externalId": "admin-ext", "type": "backend", "origin": "system"}
404
421
  ]
405
422
  }
423
+ mock_response.status_code = 200
406
424
 
407
425
  result = self.client.get_project_roles(project_id="proj-123")
408
426
 
@@ -426,10 +444,12 @@ class TestOrganizationClient(unittest.TestCase):
426
444
  def test_get_project_members_success(self, mock_get):
427
445
  mock_response = mock_get.return_value
428
446
  mock_response.json.return_value = {
447
+
429
448
  "members": [
430
449
  {"email": "user@example.com", "roles": []}
431
450
  ]
432
451
  }
452
+ mock_response.status_code = 200
433
453
 
434
454
  result = self.client.get_project_members(project_id="proj-123")
435
455
 
@@ -453,10 +473,12 @@ class TestOrganizationClient(unittest.TestCase):
453
473
  def test_get_organization_members_success(self, mock_get):
454
474
  mock_response = mock_get.return_value
455
475
  mock_response.json.return_value = {
476
+
456
477
  "members": [
457
478
  {"email": "user@example.com", "roles": []}
458
479
  ]
459
480
  }
481
+ mock_response.status_code = 200
460
482
 
461
483
  result = self.client.get_organization_members(organization_id="org-123")
462
484
 
@@ -247,6 +247,7 @@ class TestProxyClient(unittest.TestCase):
247
247
  """Test successful request."""
248
248
  mock_response = Mock()
249
249
  mock_response.json.return_value = {"status": "success"}
250
+ mock_response.status_code = 200
250
251
  mock_response.raise_for_status.return_value = None
251
252
  mock_session.return_value.request.return_value = mock_response
252
253
 
@@ -311,6 +312,7 @@ class TestProxyClient(unittest.TestCase):
311
312
  mock_response = Mock()
312
313
  mock_response.json.side_effect = ValueError("Invalid JSON")
313
314
  mock_response.text = "plain text response"
315
+ mock_response.status_code = 200
314
316
  mock_response.raise_for_status.return_value = None
315
317
  mock_session.return_value.request.return_value = mock_response
316
318
 
@@ -230,6 +230,7 @@ class TestProxyIntegration(unittest.IsolatedAsyncioTestCase):
230
230
  # Mock response
231
231
  mock_response = Mock()
232
232
  mock_response.json.return_value = {"status": "success", "data": "test_data"}
233
+ mock_response.status_code = 200
233
234
  mock_response.raise_for_status.return_value = None
234
235
  mock_session.return_value.request.return_value = mock_response
235
236
 
@@ -0,0 +1,18 @@
1
+ from pygeai.chat.clients import ChatClient
2
+
3
+ client = ChatClient()
4
+
5
+ messages = [
6
+ {
7
+ "role": "user",
8
+ "content": "Explain quantum computing in simple terms"
9
+ }
10
+ ]
11
+
12
+ response = client.chat_completion(
13
+ model="openai/gpt-4o",
14
+ messages=messages,
15
+ reasoning_effort="high"
16
+ )
17
+
18
+ print(response)
@@ -0,0 +1,15 @@
1
+ from pygeai.chat.clients import ChatClient
2
+
3
+ client = ChatClient()
4
+
5
+ model = "openai/o1-pro"
6
+ input_text = "What is the weather like in Paris today?"
7
+
8
+ response = client.get_response(
9
+ model=model,
10
+ input=input_text,
11
+ temperature=0.7,
12
+ max_output_tokens=1000
13
+ )
14
+
15
+ print(response)
@@ -0,0 +1,20 @@
1
+ from pygeai.chat.clients import ChatClient
2
+
3
+ client = ChatClient()
4
+
5
+ model = "openai/o1-pro"
6
+ input_text = "Tell me a short story about a robot"
7
+
8
+ response = client.get_response(
9
+ model=model,
10
+ input=input_text,
11
+ stream=True,
12
+ temperature=0.7,
13
+ max_output_tokens=500
14
+ )
15
+
16
+ print("Streaming response:")
17
+ for chunk in response:
18
+ print(chunk, end='', flush=True)
19
+
20
+ print("\n\nStreaming complete!")
@@ -0,0 +1,16 @@
1
+ from pygeai.chat.clients import ChatClient
2
+
3
+ client = ChatClient()
4
+
5
+ model = "openai/o1-pro"
6
+ input_text = "Please analyze this image and describe what you see"
7
+ files = ["files/image.svg", "files/document.pdf"]
8
+
9
+ response = client.get_response(
10
+ model=model,
11
+ input=input_text,
12
+ files=files,
13
+ temperature=0.7
14
+ )
15
+
16
+ print(response)
@@ -0,0 +1,36 @@
1
+ from pygeai.chat.clients import ChatClient
2
+
3
+ client = ChatClient()
4
+
5
+ model = "openai/o1-pro"
6
+ input_text = "What is the weather like in Paris today?"
7
+
8
+ tools = [
9
+ {
10
+ "type": "function",
11
+ "name": "get_weather",
12
+ "description": "Get current temperature for a given location.",
13
+ "parameters": {
14
+ "type": "object",
15
+ "properties": {
16
+ "location": {
17
+ "type": "string",
18
+ "description": "City and country e.g. Paris, France"
19
+ }
20
+ },
21
+ "required": ["location"],
22
+ "additionalProperties": False
23
+ }
24
+ }
25
+ ]
26
+
27
+ response = client.get_response(
28
+ model=model,
29
+ input=input_text,
30
+ tools=tools,
31
+ tool_choice="auto",
32
+ temperature=1.0,
33
+ reasoning={"effort": "medium"}
34
+ )
35
+
36
+ print(response)
File without changes
@@ -0,0 +1,32 @@
1
+ """
2
+ Basic debugging example with geai-dbg.
3
+
4
+ This demonstrates setting breakpoints and inspecting variables.
5
+ """
6
+ from pygeai.dbg.debugger import Debugger
7
+
8
+
9
+ def example_function(x, y):
10
+ """A simple function to debug."""
11
+ result = x + y
12
+ print(f"Result: {result}")
13
+ return result
14
+
15
+
16
+ def main():
17
+ """Main entry point."""
18
+ a = 10
19
+ b = 20
20
+ c = example_function(a, b)
21
+ print(f"Final value: {c}")
22
+
23
+
24
+ if __name__ == "__main__":
25
+ dbg = Debugger(target=main, module_filter="__main__")
26
+ dbg.add_breakpoint(module="__main__", function_name="example_function")
27
+
28
+ print("Starting debugger...")
29
+ print("Type 'h' for help")
30
+ print("Try commands like: 'p x', 'p y', 'locals', 's', 'n', 'c'")
31
+
32
+ dbg.run()
@@ -0,0 +1,48 @@
1
+ """
2
+ Demonstrates breakpoint management (add, list, remove, enable/disable).
3
+ """
4
+ from pygeai.dbg.debugger import Debugger
5
+
6
+
7
+ def func_a():
8
+ """Function A."""
9
+ print("In function A")
10
+ return "A"
11
+
12
+
13
+ def func_b():
14
+ """Function B."""
15
+ print("In function B")
16
+ return "B"
17
+
18
+
19
+ def func_c():
20
+ """Function C."""
21
+ print("In function C")
22
+ return "C"
23
+
24
+
25
+ def main():
26
+ """Main entry point."""
27
+ results = []
28
+ results.append(func_a())
29
+ results.append(func_b())
30
+ results.append(func_c())
31
+ print(f"Results: {results}")
32
+
33
+
34
+ if __name__ == "__main__":
35
+ dbg = Debugger(target=main, module_filter="__main__")
36
+
37
+ print("Starting debugger...")
38
+ print("No breakpoints set initially. At first function, try:")
39
+ print(" 'b func_b' - add breakpoint on func_b")
40
+ print(" 'b __main__:func_c' - add breakpoint on specific module:function")
41
+ print(" 'b' - list all breakpoints")
42
+ print(" 'dis func_b' - disable breakpoint on func_b")
43
+ print(" 'en func_b' - enable breakpoint on func_b")
44
+ print(" 'cl func_b' - remove breakpoint on func_b")
45
+ print(" 'c' - continue to next breakpoint")
46
+
47
+ dbg.add_breakpoint(module="__main__", function_name="func_a")
48
+ dbg.run()