pygeai 0.4.0b12__py3-none-any.whl → 0.6.0b3__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.
- pygeai/__init__.py +1 -1
- pygeai/auth/__init__.py +0 -0
- pygeai/auth/clients.py +55 -0
- pygeai/auth/endpoints.py +2 -0
- pygeai/cli/__init__.py +0 -1
- pygeai/cli/commands/auth.py +123 -0
- pygeai/cli/commands/base.py +22 -1
- pygeai/cli/commands/docs.py +105 -0
- pygeai/cli/texts/help.py +157 -24
- pygeai/core/base/session.py +1 -1
- pygeai/core/files/responses.py +4 -3
- pygeai/lab/clients.py +3 -3
- pygeai/lab/tools/clients.py +4 -4
- pygeai/tests/admin/test_clients.py +143 -0
- pygeai/tests/auth/__init__.py +0 -0
- pygeai/tests/auth/test_clients.py +105 -0
- pygeai/tests/cli/commands/lab/test_ai_lab.py +41 -35
- pygeai/tests/cli/commands/lab/test_spec.py +24 -56
- pygeai/tests/cli/commands/test_chat.py +21 -3
- pygeai/tests/cli/commands/test_evaluation.py +649 -0
- pygeai/tests/cli/commands/test_secrets.py +171 -0
- pygeai/tests/cli/docker/__init__.py +0 -0
- pygeai/tests/core/base/data/models.py +7 -0
- pygeai/tests/core/base/test_mappers.py +43 -11
- pygeai/tests/core/base/test_models.py +3 -1
- pygeai/tests/core/base/test_responses.py +53 -0
- pygeai/tests/core/common/test_config.py +2 -3
- pygeai/tests/core/files/test_mappers.py +137 -0
- pygeai/tests/core/plugins/__init__.py +0 -0
- pygeai/tests/core/plugins/test_clients.py +64 -0
- pygeai/tests/evaluation/__init__.py +0 -0
- pygeai/tests/evaluation/dataset/__init__.py +0 -0
- pygeai/tests/evaluation/dataset/test_clients.py +263 -0
- pygeai/tests/evaluation/plan/__init__.py +0 -0
- pygeai/tests/evaluation/plan/test_clients.py +193 -0
- pygeai/tests/evaluation/result/__init__.py +0 -0
- pygeai/tests/evaluation/result/test_clients.py +64 -0
- pygeai/tests/integration/assistants/rag/test_create_rag.py +24 -5
- pygeai/tests/integration/chat/test_generate_image.py +2 -6
- pygeai/tests/integration/lab/agents/test_agents_list.py +1 -1
- pygeai/tests/integration/lab/agents/test_create_agent.py +16 -10
- pygeai/tests/integration/lab/agents/test_create_sharing_link.py +5 -2
- pygeai/tests/integration/lab/agents/test_delete_agent.py +2 -2
- pygeai/tests/integration/lab/agents/test_get_agent.py +1 -1
- pygeai/tests/integration/lab/agents/test_publish_agent_revision.py +2 -2
- pygeai/tests/integration/lab/agents/test_update_agent.py +18 -21
- pygeai/tests/integration/lab/processes/__init__.py +0 -0
- pygeai/tests/integration/lab/processes/test_create_process.py +345 -0
- pygeai/tests/integration/lab/processes/test_create_task.py +211 -0
- pygeai/tests/integration/lab/processes/test_delete_process.py +111 -0
- pygeai/tests/integration/lab/processes/test_get_process.py +201 -0
- pygeai/tests/integration/lab/processes/test_list_process_instances.py +91 -0
- pygeai/tests/integration/lab/processes/test_list_processes.py +138 -0
- pygeai/tests/integration/lab/processes/test_publish_process_revision.py +232 -0
- pygeai/tests/integration/lab/processes/test_update_process.py +289 -0
- pygeai/tests/integration/lab/reasoning_strategies/__init__.py +0 -0
- pygeai/tests/integration/lab/reasoning_strategies/test_get_reasoning_strategy.py +70 -0
- pygeai/tests/integration/lab/reasoning_strategies/test_list_reasoning_strategies.py +93 -0
- pygeai/tests/integration/lab/reasoning_strategies/test_update_reasoning_strategy.py +149 -0
- pygeai/tests/integration/lab/tools/test_create_tool.py +13 -17
- pygeai/tests/integration/lab/tools/test_delete_tool.py +4 -4
- pygeai/tests/integration/lab/tools/test_get_parameter.py +1 -1
- pygeai/tests/integration/lab/tools/test_get_tool.py +4 -4
- pygeai/tests/integration/lab/tools/test_list_tools.py +1 -1
- pygeai/tests/integration/lab/tools/test_publish_tool_revision.py +1 -1
- pygeai/tests/integration/lab/tools/test_set_parameter.py +1 -1
- pygeai/tests/integration/lab/tools/test_update_tool.py +9 -10
- pygeai/tests/lab/agents/test_clients.py +17 -34
- pygeai/tests/lab/processes/test_clients.py +30 -93
- pygeai/tests/lab/processes/test_mappers.py +12 -71
- pygeai/tests/lab/strategies/test_clients.py +63 -63
- pygeai/tests/lab/test_managers.py +3 -6
- pygeai/tests/lab/test_models.py +9 -8
- pygeai/tests/lab/tools/test_clients.py +22 -45
- pygeai/tests/migration/test_strategies.py +16 -16
- pygeai/tests/organization/test_mappers.py +11 -4
- pygeai/tests/organization/test_responses.py +137 -0
- pygeai/tests/snippets/lab/agentic_flow_example_4.py +23 -23
- pygeai/tests/snippets/lab/samples/summarize_files.py +3 -3
- pygeai/tests/snippets/lab/use_cases/file_summarizer_example.py +3 -3
- pygeai/tests/snippets/lab/use_cases/file_summarizer_example_2.py +11 -11
- pygeai/tests/snippets/lab/use_cases/update_web_reader.py +1 -2
- {pygeai-0.4.0b12.dist-info → pygeai-0.6.0b3.dist-info}/METADATA +44 -16
- {pygeai-0.4.0b12.dist-info → pygeai-0.6.0b3.dist-info}/RECORD +88 -53
- {pygeai-0.4.0b12.dist-info → pygeai-0.6.0b3.dist-info}/WHEEL +0 -0
- {pygeai-0.4.0b12.dist-info → pygeai-0.6.0b3.dist-info}/entry_points.txt +0 -0
- {pygeai-0.4.0b12.dist-info → pygeai-0.6.0b3.dist-info}/licenses/LICENSE +0 -0
- {pygeai-0.4.0b12.dist-info → pygeai-0.6.0b3.dist-info}/top_level.txt +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import unittest
|
|
2
|
-
from unittest.mock import patch
|
|
2
|
+
from unittest.mock import patch
|
|
3
3
|
from json import JSONDecodeError
|
|
4
4
|
from pygeai.lab.strategies.clients import ReasoningStrategyClient
|
|
5
5
|
from pygeai.core.common.exceptions import InvalidAPIResponseException
|
|
@@ -10,18 +10,16 @@ class TestReasoningStrategyClient(unittest.TestCase):
|
|
|
10
10
|
python -m unittest pygeai.tests.lab.strategies.test_clients.TestReasoningStrategyClient
|
|
11
11
|
"""
|
|
12
12
|
def setUp(self):
|
|
13
|
-
with patch('pygeai.core.base.clients.BaseClient.__init__', return_value=None):
|
|
14
|
-
self.client = ReasoningStrategyClient()
|
|
15
|
-
self.mock_response = MagicMock()
|
|
16
|
-
self.client.api_service = MagicMock()
|
|
17
13
|
self.project_id = "project-123"
|
|
14
|
+
self.client = ReasoningStrategyClient(api_key="test_key", base_url="https://test.url", project_id=self.project_id)
|
|
18
15
|
self.reasoning_strategy_id = "strat-123"
|
|
19
16
|
self.reasoning_strategy_name = "TestStrategy"
|
|
20
17
|
|
|
21
|
-
|
|
18
|
+
@patch("pygeai.core.services.rest.ApiService.get")
|
|
19
|
+
def test_list_reasoning_strategies_success(self, mock_get):
|
|
22
20
|
expected_response = {"strategies": [{"id": "strat-1", "name": "Strategy1"}]}
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
mock_response = mock_get.return_value
|
|
22
|
+
mock_response.json.return_value = expected_response
|
|
25
23
|
|
|
26
24
|
result = self.client.list_reasoning_strategies(
|
|
27
25
|
name="Strategy1",
|
|
@@ -32,8 +30,8 @@ class TestReasoningStrategyClient(unittest.TestCase):
|
|
|
32
30
|
)
|
|
33
31
|
|
|
34
32
|
self.assertEqual(result, expected_response)
|
|
35
|
-
|
|
36
|
-
call_args =
|
|
33
|
+
mock_get.assert_called_once()
|
|
34
|
+
call_args = mock_get.call_args
|
|
37
35
|
params = call_args[1]['params']
|
|
38
36
|
self.assertEqual(params['name'], "Strategy1")
|
|
39
37
|
self.assertEqual(params['start'], "0")
|
|
@@ -41,16 +39,17 @@ class TestReasoningStrategyClient(unittest.TestCase):
|
|
|
41
39
|
self.assertTrue(params['allowExternal'])
|
|
42
40
|
self.assertEqual(params['accessScope'], "public")
|
|
43
41
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
42
|
+
@patch("pygeai.core.services.rest.ApiService.get")
|
|
43
|
+
def test_list_reasoning_strategies_json_decode_error(self, mock_get):
|
|
44
|
+
mock_response = mock_get.return_value
|
|
45
|
+
mock_response.json.side_effect = JSONDecodeError("Invalid JSON", "", 0)
|
|
46
|
+
mock_response.text = "Raw response text"
|
|
47
|
+
mock_response.status_code = 500
|
|
49
48
|
|
|
50
49
|
with self.assertRaises(InvalidAPIResponseException) as context:
|
|
51
50
|
self.client.list_reasoning_strategies()
|
|
52
51
|
|
|
53
|
-
|
|
52
|
+
mock_get.assert_called_once()
|
|
54
53
|
self.assertIn("Unable to list reasoning strategies", str(context.exception))
|
|
55
54
|
|
|
56
55
|
def test_list_reasoning_strategies_invalid_access_scope(self):
|
|
@@ -59,7 +58,8 @@ class TestReasoningStrategyClient(unittest.TestCase):
|
|
|
59
58
|
|
|
60
59
|
self.assertEqual(str(context.exception), "Access scope must be either 'public' or 'private'.")
|
|
61
60
|
|
|
62
|
-
|
|
61
|
+
@patch("pygeai.core.services.rest.ApiService.post")
|
|
62
|
+
def test_create_reasoning_strategy_success(self, mock_post):
|
|
63
63
|
name = "TestStrategy"
|
|
64
64
|
system_prompt = "Test system prompt"
|
|
65
65
|
access_scope = "public"
|
|
@@ -67,11 +67,10 @@ class TestReasoningStrategyClient(unittest.TestCase):
|
|
|
67
67
|
localized_descriptions = [{"language": "english", "description": "Test description"}]
|
|
68
68
|
automatic_publish = True
|
|
69
69
|
expected_response = {"id": "strat-123", "name": name}
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
mock_response = mock_post.return_value
|
|
71
|
+
mock_response.json.return_value = expected_response
|
|
72
72
|
|
|
73
73
|
result = self.client.create_reasoning_strategy(
|
|
74
|
-
project_id=self.project_id,
|
|
75
74
|
name=name,
|
|
76
75
|
system_prompt=system_prompt,
|
|
77
76
|
access_scope=access_scope,
|
|
@@ -81,8 +80,8 @@ class TestReasoningStrategyClient(unittest.TestCase):
|
|
|
81
80
|
)
|
|
82
81
|
|
|
83
82
|
self.assertEqual(result, expected_response)
|
|
84
|
-
|
|
85
|
-
call_args =
|
|
83
|
+
mock_post.assert_called_once()
|
|
84
|
+
call_args = mock_post.call_args
|
|
86
85
|
data = call_args[1]['data']['strategyDefinition']
|
|
87
86
|
self.assertEqual(data['name'], name)
|
|
88
87
|
self.assertEqual(data['systemPrompt'], system_prompt)
|
|
@@ -93,25 +92,26 @@ class TestReasoningStrategyClient(unittest.TestCase):
|
|
|
93
92
|
headers = call_args[1]['headers']
|
|
94
93
|
self.assertEqual(headers['ProjectId'], self.project_id)
|
|
95
94
|
|
|
96
|
-
|
|
95
|
+
@patch("pygeai.core.services.rest.ApiService.post")
|
|
96
|
+
def test_create_reasoning_strategy_json_decode_error(self, mock_post):
|
|
97
97
|
name = "TestStrategy"
|
|
98
98
|
system_prompt = "Test system prompt"
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
99
|
+
mock_response = mock_post.return_value
|
|
100
|
+
mock_response.json.side_effect = JSONDecodeError("Invalid JSON", "", 0)
|
|
101
|
+
mock_response.text = "Raw response text"
|
|
102
|
+
mock_response.status_code = 500
|
|
103
103
|
|
|
104
104
|
with self.assertRaises(InvalidAPIResponseException) as context:
|
|
105
105
|
self.client.create_reasoning_strategy(
|
|
106
|
-
project_id=self.project_id,
|
|
107
106
|
name=name,
|
|
108
107
|
system_prompt=system_prompt
|
|
109
108
|
)
|
|
110
109
|
|
|
111
|
-
|
|
110
|
+
mock_post.assert_called_once()
|
|
112
111
|
self.assertIn("Unable to create reasoning strategy", str(context.exception))
|
|
113
112
|
|
|
114
|
-
|
|
113
|
+
@patch("pygeai.core.services.rest.ApiService.put")
|
|
114
|
+
def test_update_reasoning_strategy_success(self, mock_put):
|
|
115
115
|
name = "UpdatedStrategy"
|
|
116
116
|
system_prompt = "Updated prompt"
|
|
117
117
|
access_scope = "private"
|
|
@@ -120,11 +120,10 @@ class TestReasoningStrategyClient(unittest.TestCase):
|
|
|
120
120
|
automatic_publish = True
|
|
121
121
|
upsert = False
|
|
122
122
|
expected_response = {"id": self.reasoning_strategy_id, "name": name}
|
|
123
|
-
|
|
124
|
-
|
|
123
|
+
mock_response = mock_put.return_value
|
|
124
|
+
mock_response.json.return_value = expected_response
|
|
125
125
|
|
|
126
126
|
result = self.client.update_reasoning_strategy(
|
|
127
|
-
project_id=self.project_id,
|
|
128
127
|
reasoning_strategy_id=self.reasoning_strategy_id,
|
|
129
128
|
name=name,
|
|
130
129
|
system_prompt=system_prompt,
|
|
@@ -136,8 +135,8 @@ class TestReasoningStrategyClient(unittest.TestCase):
|
|
|
136
135
|
)
|
|
137
136
|
|
|
138
137
|
self.assertEqual(result, expected_response)
|
|
139
|
-
|
|
140
|
-
call_args =
|
|
138
|
+
mock_put.assert_called_once()
|
|
139
|
+
call_args = mock_put.call_args
|
|
141
140
|
data = call_args[1]['data']['strategyDefinition']
|
|
142
141
|
self.assertEqual(data['name'], name)
|
|
143
142
|
self.assertEqual(data['systemPrompt'], system_prompt)
|
|
@@ -148,27 +147,26 @@ class TestReasoningStrategyClient(unittest.TestCase):
|
|
|
148
147
|
headers = call_args[1]['headers']
|
|
149
148
|
self.assertEqual(headers['ProjectId'], self.project_id)
|
|
150
149
|
|
|
151
|
-
|
|
150
|
+
@patch("pygeai.core.services.rest.ApiService.put")
|
|
151
|
+
def test_update_reasoning_strategy_json_decode_error(self, mock_put):
|
|
152
152
|
name = "UpdatedStrategy"
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
153
|
+
mock_response = mock_put.return_value
|
|
154
|
+
mock_response.json.side_effect = JSONDecodeError("Invalid JSON", "", 0)
|
|
155
|
+
mock_response.text = "Raw response text"
|
|
156
|
+
mock_response.status_code = 500
|
|
157
157
|
|
|
158
158
|
with self.assertRaises(InvalidAPIResponseException) as context:
|
|
159
159
|
self.client.update_reasoning_strategy(
|
|
160
|
-
project_id=self.project_id,
|
|
161
160
|
reasoning_strategy_id=self.reasoning_strategy_id,
|
|
162
161
|
name=name
|
|
163
162
|
)
|
|
164
163
|
|
|
165
|
-
|
|
164
|
+
mock_put.assert_called_once()
|
|
166
165
|
self.assertIn("Unable to update reasoning strategy", str(context.exception))
|
|
167
166
|
|
|
168
167
|
def test_update_reasoning_strategy_invalid_access_scope(self):
|
|
169
168
|
with self.assertRaises(ValueError) as context:
|
|
170
169
|
self.client.update_reasoning_strategy(
|
|
171
|
-
project_id=self.project_id,
|
|
172
170
|
reasoning_strategy_id=self.reasoning_strategy_id,
|
|
173
171
|
access_scope="invalid"
|
|
174
172
|
)
|
|
@@ -178,59 +176,61 @@ class TestReasoningStrategyClient(unittest.TestCase):
|
|
|
178
176
|
def test_update_reasoning_strategy_invalid_type(self):
|
|
179
177
|
with self.assertRaises(ValueError) as context:
|
|
180
178
|
self.client.update_reasoning_strategy(
|
|
181
|
-
project_id=self.project_id,
|
|
182
179
|
reasoning_strategy_id=self.reasoning_strategy_id,
|
|
183
180
|
strategy_type="invalid"
|
|
184
181
|
)
|
|
185
182
|
|
|
186
183
|
self.assertEqual(str(context.exception), "Type must be 'addendum'.")
|
|
187
184
|
|
|
188
|
-
|
|
185
|
+
@patch("pygeai.core.services.rest.ApiService.get")
|
|
186
|
+
def test_get_reasoning_strategy_success_with_id(self, mock_get):
|
|
189
187
|
expected_response = {"id": self.reasoning_strategy_id, "name": "TestStrategy"}
|
|
190
|
-
|
|
191
|
-
|
|
188
|
+
mock_response = mock_get.return_value
|
|
189
|
+
mock_response.json.return_value = expected_response
|
|
192
190
|
|
|
193
191
|
result = self.client.get_reasoning_strategy(
|
|
194
|
-
project_id=self.project_id,
|
|
195
192
|
reasoning_strategy_id=self.reasoning_strategy_id
|
|
196
193
|
)
|
|
197
194
|
|
|
198
195
|
self.assertEqual(result, expected_response)
|
|
199
|
-
|
|
200
|
-
headers =
|
|
196
|
+
mock_get.assert_called_once()
|
|
197
|
+
headers = mock_get.call_args[1]['headers']
|
|
201
198
|
self.assertEqual(headers['ProjectId'], self.project_id)
|
|
202
199
|
|
|
203
|
-
|
|
200
|
+
@patch("pygeai.core.services.rest.ApiService.get")
|
|
201
|
+
def test_get_reasoning_strategy_success_with_name(self, mock_get):
|
|
204
202
|
expected_response = {"name": self.reasoning_strategy_name}
|
|
205
|
-
|
|
206
|
-
|
|
203
|
+
mock_response = mock_get.return_value
|
|
204
|
+
mock_response.json.return_value = expected_response
|
|
207
205
|
|
|
208
206
|
result = self.client.get_reasoning_strategy(
|
|
209
|
-
project_id=self.project_id,
|
|
210
207
|
reasoning_strategy_name=self.reasoning_strategy_name
|
|
211
208
|
)
|
|
212
209
|
|
|
213
210
|
self.assertEqual(result, expected_response)
|
|
214
|
-
|
|
211
|
+
mock_get.assert_called_once()
|
|
215
212
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
213
|
+
@patch("pygeai.core.services.rest.ApiService.get")
|
|
214
|
+
def test_get_reasoning_strategy_json_decode_error(self, mock_get):
|
|
215
|
+
mock_response = mock_get.return_value
|
|
216
|
+
mock_response.json.side_effect = JSONDecodeError("Invalid JSON", "", 0)
|
|
217
|
+
mock_response.text = "Raw response text"
|
|
218
|
+
mock_response.status_code = 500
|
|
221
219
|
|
|
222
220
|
with self.assertRaises(InvalidAPIResponseException) as context:
|
|
223
221
|
self.client.get_reasoning_strategy(
|
|
224
|
-
project_id=self.project_id,
|
|
225
222
|
reasoning_strategy_id=self.reasoning_strategy_id
|
|
226
223
|
)
|
|
227
224
|
|
|
228
|
-
|
|
225
|
+
mock_get.assert_called_once()
|
|
229
226
|
self.assertIn("Unable to retrieve reasoning strategy", str(context.exception))
|
|
230
227
|
|
|
231
228
|
def test_get_reasoning_strategy_invalid_input(self):
|
|
232
229
|
with self.assertRaises(ValueError) as context:
|
|
233
|
-
self.client.get_reasoning_strategy(
|
|
230
|
+
self.client.get_reasoning_strategy()
|
|
234
231
|
|
|
235
232
|
self.assertEqual(str(context.exception), "Either reasoning_strategy_id or reasoning_strategy_name must be provided.")
|
|
236
233
|
|
|
234
|
+
|
|
235
|
+
if __name__ == '__main__':
|
|
236
|
+
unittest.main()
|
|
@@ -205,17 +205,14 @@ class TestAILabManager(unittest.TestCase):
|
|
|
205
205
|
self.assertIsInstance(result, list)
|
|
206
206
|
|
|
207
207
|
@patch('pygeai.lab.tools.clients.ToolClient.set_parameter')
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
mock_set_parameter.return_value = {"data": "test_data"}
|
|
211
|
-
mock_map_to_tool.return_value = Tool(id=self.tool_id, name="test_tool", description="test_desc")
|
|
208
|
+
def test_set_parameter_success(self, mock_set_parameter):
|
|
209
|
+
mock_set_parameter.return_value = {"status": "success"}
|
|
212
210
|
parameters = [ToolParameter(key="test_key", data_type="String", description="test_desc", is_required=True)]
|
|
213
211
|
|
|
214
212
|
result = self.manager.set_parameter(tool_id=self.tool_id, parameters=parameters)
|
|
215
213
|
|
|
216
214
|
mock_set_parameter.assert_called_once()
|
|
217
|
-
|
|
218
|
-
self.assertIsInstance(result, Tool)
|
|
215
|
+
self.assertIsNotNone(result)
|
|
219
216
|
|
|
220
217
|
@patch('pygeai.lab.strategies.clients.ReasoningStrategyClient.list_reasoning_strategies')
|
|
221
218
|
@patch('pygeai.lab.strategies.mappers.ReasoningStrategyMapper.map_to_reasoning_strategy_list')
|
pygeai/tests/lab/test_models.py
CHANGED
|
@@ -772,12 +772,12 @@ class TestLabModels(TestCase):
|
|
|
772
772
|
"name": "ApiTool",
|
|
773
773
|
"description": "API tool",
|
|
774
774
|
"scope": "api"
|
|
775
|
-
# Missing open_api or open_api_json
|
|
775
|
+
# Missing open_api or open_api_json - validation currently commented out
|
|
776
776
|
}
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
self.
|
|
780
|
-
|
|
777
|
+
# Validation is currently commented out in the model, so this should not raise
|
|
778
|
+
tool = Tool.model_validate(tool_data)
|
|
779
|
+
self.assertEqual(tool.name, "ApiTool")
|
|
780
|
+
self.assertEqual(tool.scope, "api")
|
|
781
781
|
|
|
782
782
|
def test_tool_duplicate_parameter_keys(self):
|
|
783
783
|
tool_data = {
|
|
@@ -789,9 +789,10 @@ class TestLabModels(TestCase):
|
|
|
789
789
|
{"key": "param1", "dataType": "Integer", "description": "Param 1 duplicate", "isRequired": False}
|
|
790
790
|
]
|
|
791
791
|
}
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
self.
|
|
792
|
+
# Validation is currently commented out in the model, so this should not raise
|
|
793
|
+
tool = Tool.model_validate(tool_data)
|
|
794
|
+
self.assertEqual(tool.name, "DuplicateTool")
|
|
795
|
+
self.assertEqual(len(tool.parameters), 2)
|
|
795
796
|
|
|
796
797
|
def test_knowledge_base_invalid_artifacts(self):
|
|
797
798
|
kb_data = {
|
|
@@ -15,8 +15,8 @@ class TestToolClient(unittest.TestCase):
|
|
|
15
15
|
"""
|
|
16
16
|
|
|
17
17
|
def setUp(self):
|
|
18
|
-
self.tool_client = ToolClient()
|
|
19
18
|
self.project_id = "project-123"
|
|
19
|
+
self.tool_client = ToolClient(api_key="test_key", base_url="https://test.url", project_id=self.project_id)
|
|
20
20
|
self.tool_id = "tool-123"
|
|
21
21
|
self.tool_name = "TestTool"
|
|
22
22
|
self.tool_public_name = "test-tool"
|
|
@@ -36,10 +36,10 @@ class TestToolClient(unittest.TestCase):
|
|
|
36
36
|
automatic_publish = True
|
|
37
37
|
expected_response = {"id": "tool-123", "name": name}
|
|
38
38
|
mock_response = mock_post.return_value
|
|
39
|
+
mock_response.status_code = 200
|
|
39
40
|
mock_response.json.return_value = expected_response
|
|
40
41
|
|
|
41
42
|
result = self.tool_client.create_tool(
|
|
42
|
-
project_id=self.project_id,
|
|
43
43
|
name=name,
|
|
44
44
|
description=description,
|
|
45
45
|
scope=scope,
|
|
@@ -74,7 +74,6 @@ class TestToolClient(unittest.TestCase):
|
|
|
74
74
|
def test_create_tool_invalid_scope(self):
|
|
75
75
|
with self.assertRaises(ValueError) as context:
|
|
76
76
|
self.tool_client.create_tool(
|
|
77
|
-
project_id=self.project_id,
|
|
78
77
|
name="TestTool",
|
|
79
78
|
scope="invalid_scope"
|
|
80
79
|
)
|
|
@@ -83,7 +82,6 @@ class TestToolClient(unittest.TestCase):
|
|
|
83
82
|
def test_create_tool_invalid_access_scope(self):
|
|
84
83
|
with self.assertRaises(ValueError) as context:
|
|
85
84
|
self.tool_client.create_tool(
|
|
86
|
-
project_id=self.project_id,
|
|
87
85
|
name="TestTool",
|
|
88
86
|
access_scope="invalid_access"
|
|
89
87
|
)
|
|
@@ -92,7 +90,6 @@ class TestToolClient(unittest.TestCase):
|
|
|
92
90
|
def test_create_tool_invalid_report_events(self):
|
|
93
91
|
with self.assertRaises(ValueError) as context:
|
|
94
92
|
self.tool_client.create_tool(
|
|
95
|
-
project_id=self.project_id,
|
|
96
93
|
name="TestTool",
|
|
97
94
|
report_events="invalid_event"
|
|
98
95
|
)
|
|
@@ -108,7 +105,6 @@ class TestToolClient(unittest.TestCase):
|
|
|
108
105
|
|
|
109
106
|
with self.assertRaises(InvalidAPIResponseException) as context:
|
|
110
107
|
self.tool_client.create_tool(
|
|
111
|
-
project_id=self.project_id,
|
|
112
108
|
name=name
|
|
113
109
|
)
|
|
114
110
|
|
|
@@ -119,10 +115,10 @@ class TestToolClient(unittest.TestCase):
|
|
|
119
115
|
def test_list_tools_success(self, mock_get):
|
|
120
116
|
expected_response = {"tools": [{"id": "tool-1", "name": "Tool1"}]}
|
|
121
117
|
mock_response = mock_get.return_value
|
|
118
|
+
mock_response.status_code = 200
|
|
122
119
|
mock_response.json.return_value = expected_response
|
|
123
120
|
|
|
124
121
|
result = self.tool_client.list_tools(
|
|
125
|
-
project_id=self.project_id,
|
|
126
122
|
id="tool-1",
|
|
127
123
|
count="50",
|
|
128
124
|
access_scope="public",
|
|
@@ -150,7 +146,6 @@ class TestToolClient(unittest.TestCase):
|
|
|
150
146
|
def test_list_tools_invalid_scope(self):
|
|
151
147
|
with self.assertRaises(ValueError) as context:
|
|
152
148
|
self.tool_client.list_tools(
|
|
153
|
-
project_id=self.project_id,
|
|
154
149
|
scope="invalid_scope"
|
|
155
150
|
)
|
|
156
151
|
self.assertEqual(str(context.exception), f"Scope must be one of {', '.join(VALID_SCOPES)}.")
|
|
@@ -164,7 +159,6 @@ class TestToolClient(unittest.TestCase):
|
|
|
164
159
|
|
|
165
160
|
with self.assertRaises(InvalidAPIResponseException) as context:
|
|
166
161
|
self.tool_client.list_tools(
|
|
167
|
-
project_id=self.project_id,
|
|
168
162
|
scope="api"
|
|
169
163
|
)
|
|
170
164
|
|
|
@@ -175,10 +169,10 @@ class TestToolClient(unittest.TestCase):
|
|
|
175
169
|
def test_get_tool_success(self, mock_get):
|
|
176
170
|
expected_response = {"id": self.tool_id, "name": "TestTool"}
|
|
177
171
|
mock_response = mock_get.return_value
|
|
172
|
+
mock_response.status_code = 200
|
|
178
173
|
mock_response.json.return_value = expected_response
|
|
179
174
|
|
|
180
175
|
result = self.tool_client.get_tool(
|
|
181
|
-
project_id=self.project_id,
|
|
182
176
|
tool_id=self.tool_id,
|
|
183
177
|
revision="1",
|
|
184
178
|
version=0,
|
|
@@ -207,7 +201,6 @@ class TestToolClient(unittest.TestCase):
|
|
|
207
201
|
|
|
208
202
|
with self.assertRaises(InvalidAPIResponseException) as context:
|
|
209
203
|
self.tool_client.get_tool(
|
|
210
|
-
project_id=self.project_id,
|
|
211
204
|
tool_id=self.tool_id
|
|
212
205
|
)
|
|
213
206
|
|
|
@@ -216,16 +209,14 @@ class TestToolClient(unittest.TestCase):
|
|
|
216
209
|
|
|
217
210
|
@patch("pygeai.core.services.rest.ApiService.delete")
|
|
218
211
|
def test_delete_tool_success_with_id(self, mock_delete):
|
|
219
|
-
expected_response = {"status": "deleted"}
|
|
220
212
|
mock_response = mock_delete.return_value
|
|
221
|
-
mock_response.
|
|
213
|
+
mock_response.status_code = 204
|
|
222
214
|
|
|
223
215
|
result = self.tool_client.delete_tool(
|
|
224
|
-
project_id=self.project_id,
|
|
225
216
|
tool_id=self.tool_id
|
|
226
217
|
)
|
|
227
218
|
|
|
228
|
-
self.assertEqual(result,
|
|
219
|
+
self.assertEqual(result, {})
|
|
229
220
|
mock_delete.assert_called_once_with(
|
|
230
221
|
endpoint=DELETE_TOOL_V2.format(toolId=self.tool_id),
|
|
231
222
|
headers=mock_delete.call_args[1]['headers']
|
|
@@ -235,16 +226,14 @@ class TestToolClient(unittest.TestCase):
|
|
|
235
226
|
|
|
236
227
|
@patch("pygeai.core.services.rest.ApiService.delete")
|
|
237
228
|
def test_delete_tool_success_with_name(self, mock_delete):
|
|
238
|
-
expected_response = {"status": "deleted"}
|
|
239
229
|
mock_response = mock_delete.return_value
|
|
240
|
-
mock_response.
|
|
230
|
+
mock_response.status_code = 204
|
|
241
231
|
|
|
242
232
|
result = self.tool_client.delete_tool(
|
|
243
|
-
project_id=self.project_id,
|
|
244
233
|
tool_name=self.tool_name
|
|
245
234
|
)
|
|
246
235
|
|
|
247
|
-
self.assertEqual(result,
|
|
236
|
+
self.assertEqual(result, {})
|
|
248
237
|
mock_delete.assert_called_once_with(
|
|
249
238
|
endpoint=DELETE_TOOL_V2.format(toolId=self.tool_name),
|
|
250
239
|
headers=mock_delete.call_args[1]['headers']
|
|
@@ -254,7 +243,7 @@ class TestToolClient(unittest.TestCase):
|
|
|
254
243
|
|
|
255
244
|
def test_delete_tool_invalid_input(self):
|
|
256
245
|
with self.assertRaises(ValueError) as context:
|
|
257
|
-
self.tool_client.delete_tool(
|
|
246
|
+
self.tool_client.delete_tool()
|
|
258
247
|
self.assertEqual(str(context.exception), "Either tool_id or tool_name must be provided.")
|
|
259
248
|
|
|
260
249
|
@patch("pygeai.core.services.rest.ApiService.delete")
|
|
@@ -266,11 +255,10 @@ class TestToolClient(unittest.TestCase):
|
|
|
266
255
|
|
|
267
256
|
with self.assertRaises(InvalidAPIResponseException) as context:
|
|
268
257
|
self.tool_client.delete_tool(
|
|
269
|
-
project_id=self.project_id,
|
|
270
258
|
tool_id=self.tool_id
|
|
271
259
|
)
|
|
272
260
|
|
|
273
|
-
self.assertEqual(str(context.exception), f"Unable to delete tool {self.tool_id}
|
|
261
|
+
self.assertEqual(str(context.exception), f"Unable to delete tool {self.tool_id} in project {self.project_id}: Invalid JSON response")
|
|
274
262
|
mock_delete.assert_called_once()
|
|
275
263
|
|
|
276
264
|
@patch("pygeai.core.services.rest.ApiService.put")
|
|
@@ -288,10 +276,10 @@ class TestToolClient(unittest.TestCase):
|
|
|
288
276
|
upsert = False
|
|
289
277
|
expected_response = {"id": self.tool_id, "name": name}
|
|
290
278
|
mock_response = mock_put.return_value
|
|
279
|
+
mock_response.status_code = 200
|
|
291
280
|
mock_response.json.return_value = expected_response
|
|
292
281
|
|
|
293
282
|
result = self.tool_client.update_tool(
|
|
294
|
-
project_id=self.project_id,
|
|
295
283
|
tool_id=self.tool_id,
|
|
296
284
|
name=name,
|
|
297
285
|
description=description,
|
|
@@ -333,10 +321,10 @@ class TestToolClient(unittest.TestCase):
|
|
|
333
321
|
name = "UpsertedTool"
|
|
334
322
|
expected_response = {"id": self.tool_id, "name": name}
|
|
335
323
|
mock_response = mock_put.return_value
|
|
324
|
+
mock_response.status_code = 200
|
|
336
325
|
mock_response.json.return_value = expected_response
|
|
337
326
|
|
|
338
327
|
result = self.tool_client.update_tool(
|
|
339
|
-
project_id=self.project_id,
|
|
340
328
|
tool_id=self.tool_id,
|
|
341
329
|
name=name,
|
|
342
330
|
upsert=True
|
|
@@ -352,7 +340,6 @@ class TestToolClient(unittest.TestCase):
|
|
|
352
340
|
def test_update_tool_invalid_scope(self):
|
|
353
341
|
with self.assertRaises(ValueError) as context:
|
|
354
342
|
self.tool_client.update_tool(
|
|
355
|
-
project_id=self.project_id,
|
|
356
343
|
tool_id=self.tool_id,
|
|
357
344
|
scope="invalid_scope"
|
|
358
345
|
)
|
|
@@ -361,7 +348,6 @@ class TestToolClient(unittest.TestCase):
|
|
|
361
348
|
def test_update_tool_invalid_access_scope(self):
|
|
362
349
|
with self.assertRaises(ValueError) as context:
|
|
363
350
|
self.tool_client.update_tool(
|
|
364
|
-
project_id=self.project_id,
|
|
365
351
|
tool_id=self.tool_id,
|
|
366
352
|
access_scope="invalid_access"
|
|
367
353
|
)
|
|
@@ -370,7 +356,6 @@ class TestToolClient(unittest.TestCase):
|
|
|
370
356
|
def test_update_tool_invalid_report_events(self):
|
|
371
357
|
with self.assertRaises(ValueError) as context:
|
|
372
358
|
self.tool_client.update_tool(
|
|
373
|
-
project_id=self.project_id,
|
|
374
359
|
tool_id=self.tool_id,
|
|
375
360
|
report_events="invalid_event"
|
|
376
361
|
)
|
|
@@ -385,7 +370,6 @@ class TestToolClient(unittest.TestCase):
|
|
|
385
370
|
|
|
386
371
|
with self.assertRaises(InvalidAPIResponseException) as context:
|
|
387
372
|
self.tool_client.update_tool(
|
|
388
|
-
project_id=self.project_id,
|
|
389
373
|
tool_id=self.tool_id,
|
|
390
374
|
name="UpdatedTool"
|
|
391
375
|
)
|
|
@@ -398,10 +382,10 @@ class TestToolClient(unittest.TestCase):
|
|
|
398
382
|
revision = "2"
|
|
399
383
|
expected_response = {"status": "published"}
|
|
400
384
|
mock_response = mock_post.return_value
|
|
385
|
+
mock_response.status_code = 200
|
|
401
386
|
mock_response.json.return_value = expected_response
|
|
402
387
|
|
|
403
388
|
result = self.tool_client.publish_tool_revision(
|
|
404
|
-
project_id=self.project_id,
|
|
405
389
|
tool_id=self.tool_id,
|
|
406
390
|
revision=revision
|
|
407
391
|
)
|
|
@@ -425,7 +409,6 @@ class TestToolClient(unittest.TestCase):
|
|
|
425
409
|
|
|
426
410
|
with self.assertRaises(InvalidAPIResponseException) as context:
|
|
427
411
|
self.tool_client.publish_tool_revision(
|
|
428
|
-
project_id=self.project_id,
|
|
429
412
|
tool_id=self.tool_id,
|
|
430
413
|
revision=revision
|
|
431
414
|
)
|
|
@@ -437,10 +420,10 @@ class TestToolClient(unittest.TestCase):
|
|
|
437
420
|
def test_get_parameter_success_with_id(self, mock_get):
|
|
438
421
|
expected_response = {"parameters": [{"key": "param1"}]}
|
|
439
422
|
mock_response = mock_get.return_value
|
|
423
|
+
mock_response.status_code = 200
|
|
440
424
|
mock_response.json.return_value = expected_response
|
|
441
425
|
|
|
442
426
|
result = self.tool_client.get_parameter(
|
|
443
|
-
project_id=self.project_id,
|
|
444
427
|
tool_id=self.tool_id,
|
|
445
428
|
revision="1",
|
|
446
429
|
version=0,
|
|
@@ -464,10 +447,10 @@ class TestToolClient(unittest.TestCase):
|
|
|
464
447
|
def test_get_parameter_success_with_public_name(self, mock_get):
|
|
465
448
|
expected_response = {"parameters": [{"key": "param1"}]}
|
|
466
449
|
mock_response = mock_get.return_value
|
|
450
|
+
mock_response.status_code = 200
|
|
467
451
|
mock_response.json.return_value = expected_response
|
|
468
452
|
|
|
469
453
|
result = self.tool_client.get_parameter(
|
|
470
|
-
project_id=self.project_id,
|
|
471
454
|
tool_public_name=self.tool_public_name,
|
|
472
455
|
revision="1",
|
|
473
456
|
version=0,
|
|
@@ -487,7 +470,7 @@ class TestToolClient(unittest.TestCase):
|
|
|
487
470
|
|
|
488
471
|
def test_get_parameter_invalid_input(self):
|
|
489
472
|
with self.assertRaises(ValueError) as context:
|
|
490
|
-
self.tool_client.get_parameter(
|
|
473
|
+
self.tool_client.get_parameter()
|
|
491
474
|
self.assertEqual(str(context.exception), "Either tool_id or tool_public_name must be provided.")
|
|
492
475
|
|
|
493
476
|
@patch("pygeai.core.services.rest.ApiService.get")
|
|
@@ -499,7 +482,6 @@ class TestToolClient(unittest.TestCase):
|
|
|
499
482
|
|
|
500
483
|
with self.assertRaises(InvalidAPIResponseException) as context:
|
|
501
484
|
self.tool_client.get_parameter(
|
|
502
|
-
project_id=self.project_id,
|
|
503
485
|
tool_id=self.tool_id
|
|
504
486
|
)
|
|
505
487
|
|
|
@@ -508,17 +490,15 @@ class TestToolClient(unittest.TestCase):
|
|
|
508
490
|
|
|
509
491
|
@patch("pygeai.core.services.rest.ApiService.post")
|
|
510
492
|
def test_set_parameter_success_with_id(self, mock_post):
|
|
511
|
-
expected_response = {"status": "updated"}
|
|
512
493
|
mock_response = mock_post.return_value
|
|
513
|
-
mock_response.
|
|
494
|
+
mock_response.status_code = 204
|
|
514
495
|
|
|
515
496
|
result = self.tool_client.set_parameter(
|
|
516
|
-
project_id=self.project_id,
|
|
517
497
|
tool_id=self.tool_id,
|
|
518
498
|
parameters=self.parameters
|
|
519
499
|
)
|
|
520
500
|
|
|
521
|
-
self.assertEqual(result,
|
|
501
|
+
self.assertEqual(result, {})
|
|
522
502
|
mock_post.assert_called_once_with(
|
|
523
503
|
endpoint=SET_PARAMETER_V2.format(toolPublicName=self.tool_id),
|
|
524
504
|
headers=mock_post.call_args[1]['headers'],
|
|
@@ -529,17 +509,15 @@ class TestToolClient(unittest.TestCase):
|
|
|
529
509
|
|
|
530
510
|
@patch("pygeai.core.services.rest.ApiService.post")
|
|
531
511
|
def test_set_parameter_success_with_public_name(self, mock_post):
|
|
532
|
-
expected_response = {"status": "updated"}
|
|
533
512
|
mock_response = mock_post.return_value
|
|
534
|
-
mock_response.
|
|
513
|
+
mock_response.status_code = 204
|
|
535
514
|
|
|
536
515
|
result = self.tool_client.set_parameter(
|
|
537
|
-
project_id=self.project_id,
|
|
538
516
|
tool_public_name=self.tool_public_name,
|
|
539
517
|
parameters=self.parameters
|
|
540
518
|
)
|
|
541
519
|
|
|
542
|
-
self.assertEqual(result,
|
|
520
|
+
self.assertEqual(result, {})
|
|
543
521
|
mock_post.assert_called_once_with(
|
|
544
522
|
endpoint=SET_PARAMETER_V2.format(toolPublicName=self.tool_public_name),
|
|
545
523
|
headers=mock_post.call_args[1]['headers'],
|
|
@@ -548,11 +526,11 @@ class TestToolClient(unittest.TestCase):
|
|
|
548
526
|
|
|
549
527
|
def test_set_parameter_invalid_input(self):
|
|
550
528
|
with self.assertRaises(ValueError) as context:
|
|
551
|
-
self.tool_client.set_parameter(
|
|
529
|
+
self.tool_client.set_parameter(parameters=self.parameters)
|
|
552
530
|
self.assertEqual(str(context.exception), "Either tool_id or tool_public_name must be provided.")
|
|
553
531
|
|
|
554
532
|
with self.assertRaises(ValueError) as context:
|
|
555
|
-
self.tool_client.set_parameter(
|
|
533
|
+
self.tool_client.set_parameter(tool_id=self.tool_id, parameters=[])
|
|
556
534
|
self.assertEqual(str(context.exception), "Parameters list must be provided and non-empty.")
|
|
557
535
|
|
|
558
536
|
@patch("pygeai.core.services.rest.ApiService.post")
|
|
@@ -564,7 +542,6 @@ class TestToolClient(unittest.TestCase):
|
|
|
564
542
|
|
|
565
543
|
with self.assertRaises(InvalidAPIResponseException) as context:
|
|
566
544
|
self.tool_client.set_parameter(
|
|
567
|
-
project_id=self.project_id,
|
|
568
545
|
tool_id=self.tool_id,
|
|
569
546
|
parameters=self.parameters
|
|
570
547
|
)
|