pygeai 0.5.0__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/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/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 +1 -1
- pygeai/tests/integration/chat/test_generate_image.py +1 -1
- pygeai/tests/integration/lab/agents/test_agents_list.py +1 -1
- pygeai/tests/integration/lab/agents/test_create_agent.py +3 -3
- pygeai/tests/integration/lab/agents/test_create_sharing_link.py +1 -1
- 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 +3 -3
- pygeai/tests/integration/lab/processes/test_create_process.py +1 -1
- 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 +1 -1
- 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 +1 -1
- pygeai/tests/integration/lab/reasoning_strategies/test_get_reasoning_strategy.py +1 -1
- pygeai/tests/integration/lab/reasoning_strategies/test_list_reasoning_strategies.py +1 -1
- pygeai/tests/integration/lab/reasoning_strategies/test_update_reasoning_strategy.py +1 -1
- pygeai/tests/integration/lab/tools/test_create_tool.py +1 -1
- pygeai/tests/integration/lab/tools/test_delete_tool.py +1 -1
- pygeai/tests/integration/lab/tools/test_get_parameter.py +1 -1
- pygeai/tests/integration/lab/tools/test_get_tool.py +1 -1
- 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 +1 -1
- 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-0.5.0.dist-info → pygeai-0.6.0b3.dist-info}/METADATA +1 -1
- {pygeai-0.5.0.dist-info → pygeai-0.6.0b3.dist-info}/RECORD +79 -53
- {pygeai-0.5.0.dist-info → pygeai-0.6.0b3.dist-info}/WHEEL +0 -0
- {pygeai-0.5.0.dist-info → pygeai-0.6.0b3.dist-info}/entry_points.txt +0 -0
- {pygeai-0.5.0.dist-info → pygeai-0.6.0b3.dist-info}/licenses/LICENSE +0 -0
- {pygeai-0.5.0.dist-info → pygeai-0.6.0b3.dist-info}/top_level.txt +0 -0
pygeai/core/files/responses.py
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
from typing import Optional
|
|
1
2
|
from pydantic.main import BaseModel
|
|
2
3
|
|
|
3
4
|
|
|
4
5
|
class UploadFileResponse(BaseModel):
|
|
5
|
-
id: str
|
|
6
|
-
url: str
|
|
7
|
-
success: bool
|
|
6
|
+
id: Optional[str] = None
|
|
7
|
+
url: Optional[str] = None
|
|
8
|
+
success: Optional[bool] = None
|
|
8
9
|
|
|
9
10
|
def to_dict(self):
|
|
10
11
|
return {
|
pygeai/lab/clients.py
CHANGED
|
@@ -8,12 +8,12 @@ class AILabClient(BaseClient):
|
|
|
8
8
|
|
|
9
9
|
def __init__(self, api_key: str = None, base_url: str = None, alias: str = None, project_id: str = None):
|
|
10
10
|
super().__init__(api_key, base_url, alias)
|
|
11
|
-
self.project_id = project_id if project_id else self.__get_project_id()
|
|
11
|
+
self.project_id = project_id if project_id else self.__get_project_id(api_key, base_url, alias)
|
|
12
12
|
|
|
13
|
-
def __get_project_id(self):
|
|
13
|
+
def __get_project_id(self, api_key: str = None, base_url: str = None, alias: str = None):
|
|
14
14
|
response = None
|
|
15
15
|
try:
|
|
16
|
-
response = AdminClient().validate_api_token()
|
|
16
|
+
response = AdminClient(api_key=api_key, base_url=base_url, alias=alias).validate_api_token()
|
|
17
17
|
return response.get("projectId")
|
|
18
18
|
except Exception as e:
|
|
19
19
|
logger.error(f"Error retrieving project_id from GEAI. Response: {response}: {e}")
|
pygeai/lab/tools/clients.py
CHANGED
|
@@ -261,8 +261,8 @@ class ToolClient(AILabClient):
|
|
|
261
261
|
raise APIResponseError(f"API returned an error: {response.text}")
|
|
262
262
|
|
|
263
263
|
if response.status_code != 204:
|
|
264
|
-
logger.error(f"Unable to delete tool {tool_id or tool_name}
|
|
265
|
-
raise InvalidAPIResponseException(f"Unable to delete tool {tool_id or tool_name}
|
|
264
|
+
logger.error(f"Unable to delete tool {tool_id or tool_name} in project {self.project_id}: JSON parsing error (status {response.status_code}). Response: {response.text}")
|
|
265
|
+
raise InvalidAPIResponseException(f"Unable to delete tool {tool_id or tool_name} in project {self.project_id}: {response.text}")
|
|
266
266
|
else:
|
|
267
267
|
return {}
|
|
268
268
|
|
|
@@ -522,8 +522,8 @@ class ToolClient(AILabClient):
|
|
|
522
522
|
data=data
|
|
523
523
|
)
|
|
524
524
|
if response.status_code != 204:
|
|
525
|
-
logger.error(f"Unable to set
|
|
526
|
-
raise InvalidAPIResponseException(f"Unable to set
|
|
525
|
+
logger.error(f"Unable to set parameters for tool {tool_id or tool_public_name} in project {self.project_id}: JSON parsing error (status {response.status_code}). Response: {response.text}")
|
|
526
|
+
raise InvalidAPIResponseException(f"Unable to set parameters for tool {tool_id or tool_public_name} in project {self.project_id}: {response.text}")
|
|
527
527
|
else:
|
|
528
528
|
return {}
|
|
529
529
|
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
from unittest.mock import patch, MagicMock
|
|
3
|
+
from json import JSONDecodeError
|
|
4
|
+
|
|
5
|
+
from pygeai.admin.clients import AdminClient
|
|
6
|
+
from pygeai.core.common.exceptions import InvalidAPIResponseException
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TestAdminClient(unittest.TestCase):
|
|
10
|
+
"""
|
|
11
|
+
python -m unittest pygeai.tests.admin.test_clients.TestAdminClient
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
def setUp(self):
|
|
15
|
+
self.client = AdminClient()
|
|
16
|
+
self.mock_response = MagicMock()
|
|
17
|
+
|
|
18
|
+
@patch('pygeai.core.services.rest.ApiService.get')
|
|
19
|
+
def test_validate_api_token_success(self, mock_get):
|
|
20
|
+
self.mock_response.json.return_value = {"organizationId": "org-123", "projectId": "proj-123"}
|
|
21
|
+
mock_get.return_value = self.mock_response
|
|
22
|
+
|
|
23
|
+
result = self.client.validate_api_token()
|
|
24
|
+
|
|
25
|
+
mock_get.assert_called_once()
|
|
26
|
+
self.assertEqual(result, {"organizationId": "org-123", "projectId": "proj-123"})
|
|
27
|
+
|
|
28
|
+
@patch('pygeai.core.services.rest.ApiService.get')
|
|
29
|
+
def test_validate_api_token_json_decode_error(self, mock_get):
|
|
30
|
+
self.mock_response.json.side_effect = JSONDecodeError("error", "doc", 0)
|
|
31
|
+
self.mock_response.status_code = 500
|
|
32
|
+
self.mock_response.text = "Invalid response"
|
|
33
|
+
mock_get.return_value = self.mock_response
|
|
34
|
+
|
|
35
|
+
with self.assertRaises(InvalidAPIResponseException) as context:
|
|
36
|
+
self.client.validate_api_token()
|
|
37
|
+
self.assertIn("Unable to validate API token", str(context.exception))
|
|
38
|
+
|
|
39
|
+
@patch('pygeai.core.services.rest.ApiService.get')
|
|
40
|
+
def test_get_authorized_organizations_success(self, mock_get):
|
|
41
|
+
self.mock_response.json.return_value = {"organizations": ["org1", "org2"]}
|
|
42
|
+
mock_get.return_value = self.mock_response
|
|
43
|
+
|
|
44
|
+
result = self.client.get_authorized_organizations()
|
|
45
|
+
|
|
46
|
+
mock_get.assert_called_once()
|
|
47
|
+
self.assertEqual(result, {"organizations": ["org1", "org2"]})
|
|
48
|
+
|
|
49
|
+
@patch('pygeai.core.services.rest.ApiService.get')
|
|
50
|
+
def test_get_authorized_organizations_json_decode_error(self, mock_get):
|
|
51
|
+
self.mock_response.json.side_effect = JSONDecodeError("error", "doc", 0)
|
|
52
|
+
self.mock_response.status_code = 500
|
|
53
|
+
self.mock_response.text = "Invalid response"
|
|
54
|
+
mock_get.return_value = self.mock_response
|
|
55
|
+
|
|
56
|
+
with self.assertRaises(InvalidAPIResponseException) as context:
|
|
57
|
+
self.client.get_authorized_organizations()
|
|
58
|
+
self.assertIn("Unable to retrieve authorized organizations", str(context.exception))
|
|
59
|
+
|
|
60
|
+
@patch('pygeai.core.services.rest.ApiService.get')
|
|
61
|
+
def test_get_authorized_projects_by_organization_success(self, mock_get):
|
|
62
|
+
self.mock_response.json.return_value = {"projects": ["proj1", "proj2"]}
|
|
63
|
+
mock_get.return_value = self.mock_response
|
|
64
|
+
|
|
65
|
+
result = self.client.get_authorized_projects_by_organization("org-123")
|
|
66
|
+
|
|
67
|
+
mock_get.assert_called_once()
|
|
68
|
+
call_args = mock_get.call_args
|
|
69
|
+
self.assertEqual(call_args[1]['params']['organization'], "org-123")
|
|
70
|
+
self.assertEqual(result, {"projects": ["proj1", "proj2"]})
|
|
71
|
+
|
|
72
|
+
@patch('pygeai.core.services.rest.ApiService.get')
|
|
73
|
+
def test_get_authorized_projects_by_organization_json_decode_error(self, mock_get):
|
|
74
|
+
self.mock_response.json.side_effect = JSONDecodeError("error", "doc", 0)
|
|
75
|
+
self.mock_response.status_code = 500
|
|
76
|
+
self.mock_response.text = "Invalid response"
|
|
77
|
+
mock_get.return_value = self.mock_response
|
|
78
|
+
|
|
79
|
+
with self.assertRaises(InvalidAPIResponseException) as context:
|
|
80
|
+
self.client.get_authorized_projects_by_organization("org-123")
|
|
81
|
+
self.assertIn("Unable to retrieve authorized projects for organization", str(context.exception))
|
|
82
|
+
|
|
83
|
+
@patch('pygeai.core.services.rest.ApiService.get')
|
|
84
|
+
def test_get_project_visibility_success(self, mock_get):
|
|
85
|
+
self.mock_response.json.return_value = {}
|
|
86
|
+
mock_get.return_value = self.mock_response
|
|
87
|
+
|
|
88
|
+
result = self.client.get_project_visibility(
|
|
89
|
+
organization="org-123",
|
|
90
|
+
project="proj-456",
|
|
91
|
+
access_token="token-789"
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
mock_get.assert_called_once()
|
|
95
|
+
call_args = mock_get.call_args
|
|
96
|
+
self.assertEqual(call_args[1]['params']['organization'], "org-123")
|
|
97
|
+
self.assertEqual(call_args[1]['params']['project'], "proj-456")
|
|
98
|
+
self.assertEqual(call_args[1]['params']['accessToken'], "token-789")
|
|
99
|
+
self.assertEqual(result, {})
|
|
100
|
+
|
|
101
|
+
@patch('pygeai.core.services.rest.ApiService.get')
|
|
102
|
+
def test_get_project_visibility_json_decode_error(self, mock_get):
|
|
103
|
+
self.mock_response.json.side_effect = JSONDecodeError("error", "doc", 0)
|
|
104
|
+
self.mock_response.status_code = 403
|
|
105
|
+
self.mock_response.text = "Forbidden"
|
|
106
|
+
mock_get.return_value = self.mock_response
|
|
107
|
+
|
|
108
|
+
with self.assertRaises(InvalidAPIResponseException) as context:
|
|
109
|
+
self.client.get_project_visibility("org-123", "proj-456", "token-789")
|
|
110
|
+
self.assertIn("Unable to retrieve project visibility", str(context.exception))
|
|
111
|
+
|
|
112
|
+
@patch('pygeai.core.services.rest.ApiService.get')
|
|
113
|
+
def test_get_project_api_token_success(self, mock_get):
|
|
114
|
+
self.mock_response.json.return_value = {"apiToken": "api-token-123"}
|
|
115
|
+
mock_get.return_value = self.mock_response
|
|
116
|
+
|
|
117
|
+
result = self.client.get_project_api_token(
|
|
118
|
+
organization="org-123",
|
|
119
|
+
project="proj-456",
|
|
120
|
+
access_token="token-789"
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
mock_get.assert_called_once()
|
|
124
|
+
call_args = mock_get.call_args
|
|
125
|
+
self.assertEqual(call_args[1]['params']['organization'], "org-123")
|
|
126
|
+
self.assertEqual(call_args[1]['params']['project'], "proj-456")
|
|
127
|
+
self.assertEqual(call_args[1]['params']['accessToken'], "token-789")
|
|
128
|
+
self.assertEqual(result, {"apiToken": "api-token-123"})
|
|
129
|
+
|
|
130
|
+
@patch('pygeai.core.services.rest.ApiService.get')
|
|
131
|
+
def test_get_project_api_token_json_decode_error(self, mock_get):
|
|
132
|
+
self.mock_response.json.side_effect = JSONDecodeError("error", "doc", 0)
|
|
133
|
+
self.mock_response.status_code = 401
|
|
134
|
+
self.mock_response.text = "Unauthorized"
|
|
135
|
+
mock_get.return_value = self.mock_response
|
|
136
|
+
|
|
137
|
+
with self.assertRaises(InvalidAPIResponseException) as context:
|
|
138
|
+
self.client.get_project_api_token("org-123", "proj-456", "token-789")
|
|
139
|
+
self.assertIn("Unable to retrieve project API token", str(context.exception))
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
if __name__ == '__main__':
|
|
143
|
+
unittest.main()
|
|
File without changes
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
from unittest.mock import patch, MagicMock
|
|
3
|
+
from json import JSONDecodeError
|
|
4
|
+
|
|
5
|
+
from pygeai.auth.clients import AuthClient
|
|
6
|
+
from pygeai.core.common.exceptions import InvalidAPIResponseException
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TestAuthClient(unittest.TestCase):
|
|
10
|
+
"""
|
|
11
|
+
python -m unittest pygeai.tests.auth.test_clients.TestAuthClient
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
def setUp(self):
|
|
15
|
+
self.client = AuthClient()
|
|
16
|
+
self.mock_response = MagicMock()
|
|
17
|
+
|
|
18
|
+
@patch('pygeai.core.services.rest.ApiService.get')
|
|
19
|
+
def test_get_oauth2_access_token_success(self, mock_get):
|
|
20
|
+
self.mock_response.json.return_value = {"access_token": "token-123", "token_type": "Bearer"}
|
|
21
|
+
mock_get.return_value = self.mock_response
|
|
22
|
+
|
|
23
|
+
result = self.client.get_oauth2_access_token(
|
|
24
|
+
client_id="client-123",
|
|
25
|
+
username="user@example.com",
|
|
26
|
+
password="password123"
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
mock_get.assert_called_once()
|
|
30
|
+
call_args = mock_get.call_args
|
|
31
|
+
self.assertEqual(call_args[1]['params']['client_id'], "client-123")
|
|
32
|
+
self.assertEqual(call_args[1]['params']['username'], "user@example.com")
|
|
33
|
+
self.assertEqual(call_args[1]['params']['password'], "password123")
|
|
34
|
+
self.assertEqual(call_args[1]['params']['scope'], "gam_user_data gam_user_roles")
|
|
35
|
+
self.assertEqual(result, {"access_token": "token-123", "token_type": "Bearer"})
|
|
36
|
+
|
|
37
|
+
@patch('pygeai.core.services.rest.ApiService.get')
|
|
38
|
+
def test_get_oauth2_access_token_custom_scope(self, mock_get):
|
|
39
|
+
self.mock_response.json.return_value = {"access_token": "token-123"}
|
|
40
|
+
mock_get.return_value = self.mock_response
|
|
41
|
+
|
|
42
|
+
result = self.client.get_oauth2_access_token(
|
|
43
|
+
client_id="client-123",
|
|
44
|
+
username="user@example.com",
|
|
45
|
+
password="password123",
|
|
46
|
+
scope="custom_scope"
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
call_args = mock_get.call_args
|
|
50
|
+
self.assertEqual(call_args[1]['params']['scope'], "custom_scope")
|
|
51
|
+
|
|
52
|
+
@patch('pygeai.core.services.rest.ApiService.get')
|
|
53
|
+
def test_get_oauth2_access_token_json_decode_error(self, mock_get):
|
|
54
|
+
self.mock_response.json.side_effect = JSONDecodeError("error", "doc", 0)
|
|
55
|
+
self.mock_response.status_code = 401
|
|
56
|
+
self.mock_response.text = "Invalid credentials"
|
|
57
|
+
mock_get.return_value = self.mock_response
|
|
58
|
+
|
|
59
|
+
with self.assertRaises(InvalidAPIResponseException) as context:
|
|
60
|
+
self.client.get_oauth2_access_token(
|
|
61
|
+
client_id="client-123",
|
|
62
|
+
username="user@example.com",
|
|
63
|
+
password="wrong"
|
|
64
|
+
)
|
|
65
|
+
self.assertIn("Unable to obtain Oauth2 access token", str(context.exception))
|
|
66
|
+
|
|
67
|
+
@patch.object(AuthClient, 'api_service', create=True)
|
|
68
|
+
def test_get_user_profile_information_success(self, mock_api_service):
|
|
69
|
+
self.mock_response.json.return_value = {
|
|
70
|
+
"user_id": "user-123",
|
|
71
|
+
"email": "user@example.com",
|
|
72
|
+
"name": "Test User"
|
|
73
|
+
}
|
|
74
|
+
mock_api_service.get.return_value = self.mock_response
|
|
75
|
+
mock_api_service.token = None
|
|
76
|
+
|
|
77
|
+
client = AuthClient()
|
|
78
|
+
client.api_service = mock_api_service
|
|
79
|
+
result = client.get_user_profile_information("access-token-123")
|
|
80
|
+
|
|
81
|
+
mock_api_service.get.assert_called_once()
|
|
82
|
+
self.assertEqual(result, {
|
|
83
|
+
"user_id": "user-123",
|
|
84
|
+
"email": "user@example.com",
|
|
85
|
+
"name": "Test User"
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
@patch.object(AuthClient, 'api_service', create=True)
|
|
89
|
+
def test_get_user_profile_information_json_decode_error(self, mock_api_service):
|
|
90
|
+
self.mock_response.json.side_effect = JSONDecodeError("error", "doc", 0)
|
|
91
|
+
self.mock_response.status_code = 401
|
|
92
|
+
self.mock_response.text = "Invalid token"
|
|
93
|
+
mock_api_service.get.return_value = self.mock_response
|
|
94
|
+
mock_api_service.token = None
|
|
95
|
+
|
|
96
|
+
client = AuthClient()
|
|
97
|
+
client.api_service = mock_api_service
|
|
98
|
+
|
|
99
|
+
with self.assertRaises(InvalidAPIResponseException) as context:
|
|
100
|
+
client.get_user_profile_information("invalid-token")
|
|
101
|
+
self.assertIn("Unable to retrieve user profile information", str(context.exception))
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
if __name__ == '__main__':
|
|
105
|
+
unittest.main()
|
|
@@ -61,11 +61,17 @@ class TestAILab(unittest.TestCase):
|
|
|
61
61
|
show_help()
|
|
62
62
|
mock_stdout.assert_called_once()
|
|
63
63
|
|
|
64
|
-
def
|
|
64
|
+
def test_list_agents_auto_fetch_project_id(self):
|
|
65
65
|
option_list = []
|
|
66
|
-
with
|
|
66
|
+
with patch('pygeai.cli.commands.lab.ai_lab.AgentClient') as mock_client, \
|
|
67
|
+
patch('pygeai.cli.commands.lab.ai_lab.Console.write_stdout') as mock_stdout:
|
|
68
|
+
mock_client_instance = MagicMock()
|
|
69
|
+
mock_client_instance.project_id = "auto_fetched_proj"
|
|
70
|
+
mock_client.return_value = mock_client_instance
|
|
71
|
+
mock_client_instance.list_agents.return_value = []
|
|
67
72
|
list_agents(option_list)
|
|
68
|
-
|
|
73
|
+
mock_client.assert_called_once_with(project_id=None)
|
|
74
|
+
mock_stdout.assert_called_once_with("Agent list: \n[]")
|
|
69
75
|
|
|
70
76
|
def test_list_agents_success(self):
|
|
71
77
|
option_list = [(Option("project_id", ["--project-id"], "", True), "proj123")]
|
|
@@ -76,7 +82,7 @@ class TestAILab(unittest.TestCase):
|
|
|
76
82
|
mock_client_instance.list_agents.return_value = [{"id": "agent1"}]
|
|
77
83
|
list_agents(option_list)
|
|
78
84
|
mock_client_instance.list_agents.assert_called_once_with(
|
|
79
|
-
|
|
85
|
+
status="", start="", count="", access_scope="public",
|
|
80
86
|
allow_drafts=True, allow_external=False
|
|
81
87
|
)
|
|
82
88
|
mock_stdout.assert_called_once_with("Agent list: \n[{'id': 'agent1'}]")
|
|
@@ -126,7 +132,7 @@ class TestAILab(unittest.TestCase):
|
|
|
126
132
|
option_list = []
|
|
127
133
|
with self.assertRaises(MissingRequirementException) as cm:
|
|
128
134
|
get_agent(option_list)
|
|
129
|
-
self.assertEqual(str(cm.exception), "
|
|
135
|
+
self.assertEqual(str(cm.exception), "Agent ID must be specified.")
|
|
130
136
|
|
|
131
137
|
def test_get_agent_success(self):
|
|
132
138
|
option_list = [
|
|
@@ -140,7 +146,7 @@ class TestAILab(unittest.TestCase):
|
|
|
140
146
|
mock_client_instance.get_agent.return_value = {"id": "agent1"}
|
|
141
147
|
get_agent(option_list)
|
|
142
148
|
mock_client_instance.get_agent.assert_called_once_with(
|
|
143
|
-
|
|
149
|
+
agent_id="agent1", revision=0, version=0, allow_drafts=True
|
|
144
150
|
)
|
|
145
151
|
mock_stdout.assert_called_once_with("Agent detail: \n{'id': 'agent1'}")
|
|
146
152
|
|
|
@@ -156,7 +162,7 @@ class TestAILab(unittest.TestCase):
|
|
|
156
162
|
mock_client_instance.create_sharing_link.return_value = {"token": "share123"}
|
|
157
163
|
create_sharing_link(option_list)
|
|
158
164
|
mock_client_instance.create_sharing_link.assert_called_once_with(
|
|
159
|
-
|
|
165
|
+
agent_id="agent1"
|
|
160
166
|
)
|
|
161
167
|
mock_stdout.assert_called_once_with("Sharing token: \n{'token': 'share123'}")
|
|
162
168
|
|
|
@@ -173,7 +179,7 @@ class TestAILab(unittest.TestCase):
|
|
|
173
179
|
mock_client_instance.publish_agent_revision.return_value = {"status": "published"}
|
|
174
180
|
publish_agent_revision(option_list)
|
|
175
181
|
mock_client_instance.publish_agent_revision.assert_called_once_with(
|
|
176
|
-
|
|
182
|
+
agent_id="agent1", revision="1"
|
|
177
183
|
)
|
|
178
184
|
mock_stdout.assert_called_once_with("Published revision detail: \n{'status': 'published'}")
|
|
179
185
|
|
|
@@ -189,7 +195,7 @@ class TestAILab(unittest.TestCase):
|
|
|
189
195
|
mock_client_instance.delete_agent.return_value = {"status": "deleted"}
|
|
190
196
|
delete_agent(option_list)
|
|
191
197
|
mock_client_instance.delete_agent.assert_called_once_with(
|
|
192
|
-
|
|
198
|
+
agent_id="agent1"
|
|
193
199
|
)
|
|
194
200
|
mock_stdout.assert_called_once_with("Deleted agent detail: \n{'status': 'deleted'}")
|
|
195
201
|
|
|
@@ -254,7 +260,7 @@ class TestAILab(unittest.TestCase):
|
|
|
254
260
|
mock_client_instance.list_tools.return_value = [{"id": "tool1"}]
|
|
255
261
|
list_tools(option_list)
|
|
256
262
|
mock_client_instance.list_tools.assert_called_once_with(
|
|
257
|
-
|
|
263
|
+
id="", count="100", access_scope="public",
|
|
258
264
|
allow_drafts=True, scope="api", allow_external=True
|
|
259
265
|
)
|
|
260
266
|
mock_stdout.assert_called_once_with("Tool list: \n[{'id': 'tool1'}]")
|
|
@@ -271,7 +277,7 @@ class TestAILab(unittest.TestCase):
|
|
|
271
277
|
mock_client_instance.get_tool.return_value = {"id": "tool1"}
|
|
272
278
|
get_tool(option_list)
|
|
273
279
|
mock_client_instance.get_tool.assert_called_once_with(
|
|
274
|
-
|
|
280
|
+
tool_id="tool1", revision=0, version=0, allow_drafts=True
|
|
275
281
|
)
|
|
276
282
|
mock_stdout.assert_called_once_with("Tool detail: \n{'id': 'tool1'}")
|
|
277
283
|
|
|
@@ -287,7 +293,7 @@ class TestAILab(unittest.TestCase):
|
|
|
287
293
|
mock_client_instance.delete_tool.return_value = {"status": "deleted"}
|
|
288
294
|
delete_tool(option_list)
|
|
289
295
|
mock_client_instance.delete_tool.assert_called_once_with(
|
|
290
|
-
|
|
296
|
+
tool_id="tool1", tool_name=None
|
|
291
297
|
)
|
|
292
298
|
mock_stdout.assert_called_once_with("Deleted tool detail: \n{'status': 'deleted'}")
|
|
293
299
|
|
|
@@ -320,7 +326,7 @@ class TestAILab(unittest.TestCase):
|
|
|
320
326
|
mock_client_instance.publish_tool_revision.return_value = {"status": "published"}
|
|
321
327
|
publish_tool_revision(option_list)
|
|
322
328
|
mock_client_instance.publish_tool_revision.assert_called_once_with(
|
|
323
|
-
|
|
329
|
+
tool_id="tool1", revision="1"
|
|
324
330
|
)
|
|
325
331
|
mock_stdout.assert_called_once_with("Published revision detail: \n{'status': 'published'}")
|
|
326
332
|
|
|
@@ -336,7 +342,7 @@ class TestAILab(unittest.TestCase):
|
|
|
336
342
|
mock_client_instance.get_parameter.return_value = {"key": "param1"}
|
|
337
343
|
get_parameter(option_list)
|
|
338
344
|
mock_client_instance.get_parameter.assert_called_once_with(
|
|
339
|
-
|
|
345
|
+
tool_id="tool1", tool_public_name=None, revision=0, version=0, allow_drafts=True
|
|
340
346
|
)
|
|
341
347
|
mock_stdout.assert_called_once_with("Parameter detail: \n{'key': 'param1'}")
|
|
342
348
|
|
|
@@ -354,7 +360,7 @@ class TestAILab(unittest.TestCase):
|
|
|
354
360
|
mock_client_instance.set_parameter.return_value = {"status": "set"}
|
|
355
361
|
set_parameter(option_list)
|
|
356
362
|
mock_client_instance.set_parameter.assert_called_once_with(
|
|
357
|
-
|
|
363
|
+
tool_id="tool1", tool_public_name=None, parameters=[{"key": "param1", "dataType": "String"}]
|
|
358
364
|
)
|
|
359
365
|
mock_stdout.assert_called_once_with("Set parameter detail: \n{'status': 'set'}")
|
|
360
366
|
|
|
@@ -419,7 +425,7 @@ class TestAILab(unittest.TestCase):
|
|
|
419
425
|
mock_client_instance.get_reasoning_strategy.return_value = {"id": "rs1"}
|
|
420
426
|
get_reasoning_strategy(option_list)
|
|
421
427
|
mock_client_instance.get_reasoning_strategy.assert_called_once_with(
|
|
422
|
-
|
|
428
|
+
reasoning_strategy_id="rs1", reasoning_strategy_name=None
|
|
423
429
|
)
|
|
424
430
|
mock_stdout.assert_called_once_with("Reasoning strategy detail: \n{'id': 'rs1'}")
|
|
425
431
|
|
|
@@ -466,7 +472,7 @@ class TestAILab(unittest.TestCase):
|
|
|
466
472
|
mock_client_instance.get_process.return_value = {"id": "proc1"}
|
|
467
473
|
get_process(option_list)
|
|
468
474
|
mock_client_instance.get_process.assert_called_once_with(
|
|
469
|
-
|
|
475
|
+
process_id="proc1", process_name=None, revision="0", version=0, allow_drafts=True
|
|
470
476
|
)
|
|
471
477
|
mock_stdout.assert_called_once_with("Process detail: \n{'id': 'proc1'}")
|
|
472
478
|
|
|
@@ -479,7 +485,7 @@ class TestAILab(unittest.TestCase):
|
|
|
479
485
|
mock_client_instance.list_processes.return_value = [{"id": "proc1"}]
|
|
480
486
|
list_processes(option_list)
|
|
481
487
|
mock_client_instance.list_processes.assert_called_once_with(
|
|
482
|
-
|
|
488
|
+
id=None, name=None, status=None, start="0", count="100", allow_draft=True
|
|
483
489
|
)
|
|
484
490
|
mock_stdout.assert_called_once_with("Process list: \n[{'id': 'proc1'}]")
|
|
485
491
|
|
|
@@ -495,7 +501,7 @@ class TestAILab(unittest.TestCase):
|
|
|
495
501
|
mock_client_instance.list_process_instances.return_value = [{"id": "inst1"}]
|
|
496
502
|
list_processes_instances(option_list)
|
|
497
503
|
mock_client_instance.list_process_instances.assert_called_once_with(
|
|
498
|
-
|
|
504
|
+
process_id="proc1", is_active=True, start="0", count="10"
|
|
499
505
|
)
|
|
500
506
|
mock_stdout.assert_called_once_with("Process instances list: \n[{'id': 'inst1'}]")
|
|
501
507
|
|
|
@@ -511,7 +517,7 @@ class TestAILab(unittest.TestCase):
|
|
|
511
517
|
mock_client_instance.delete_process.return_value = {"status": "deleted"}
|
|
512
518
|
delete_process(option_list)
|
|
513
519
|
mock_client_instance.delete_process.assert_called_once_with(
|
|
514
|
-
|
|
520
|
+
process_id="proc1", process_name=None
|
|
515
521
|
)
|
|
516
522
|
mock_stdout.assert_called_once_with("Delete process result: \n{'status': 'deleted'}")
|
|
517
523
|
|
|
@@ -528,7 +534,7 @@ class TestAILab(unittest.TestCase):
|
|
|
528
534
|
mock_client_instance.publish_process_revision.return_value = {"status": "published"}
|
|
529
535
|
publish_process_revision(option_list)
|
|
530
536
|
mock_client_instance.publish_process_revision.assert_called_once_with(
|
|
531
|
-
|
|
537
|
+
process_id="proc1", process_name=None, revision="1"
|
|
532
538
|
)
|
|
533
539
|
mock_stdout.assert_called_once_with("Published process revision detail: \n{'status': 'published'}")
|
|
534
540
|
|
|
@@ -559,7 +565,7 @@ class TestAILab(unittest.TestCase):
|
|
|
559
565
|
mock_client_instance.get_task.return_value = {"id": "task1"}
|
|
560
566
|
get_task(option_list)
|
|
561
567
|
mock_client_instance.get_task.assert_called_once_with(
|
|
562
|
-
|
|
568
|
+
task_id="task1", task_name=None
|
|
563
569
|
)
|
|
564
570
|
mock_stdout.assert_called_once_with("Task detail: \n{'id': 'task1'}")
|
|
565
571
|
|
|
@@ -572,7 +578,7 @@ class TestAILab(unittest.TestCase):
|
|
|
572
578
|
mock_client_instance.list_tasks.return_value = [{"id": "task1"}]
|
|
573
579
|
list_tasks(option_list)
|
|
574
580
|
mock_client_instance.list_tasks.assert_called_once_with(
|
|
575
|
-
|
|
581
|
+
id=None, start="0", count="100", allow_drafts=True
|
|
576
582
|
)
|
|
577
583
|
mock_stdout.assert_called_once_with("Task list: \n[{'id': 'task1'}]")
|
|
578
584
|
|
|
@@ -603,7 +609,7 @@ class TestAILab(unittest.TestCase):
|
|
|
603
609
|
mock_client_instance.delete_task.return_value = {"status": "deleted"}
|
|
604
610
|
delete_task(option_list)
|
|
605
611
|
mock_client_instance.delete_task.assert_called_once_with(
|
|
606
|
-
|
|
612
|
+
task_id="task1", task_name=None
|
|
607
613
|
)
|
|
608
614
|
mock_stdout.assert_called_once_with("Delete task result: \n{'status': 'deleted'}")
|
|
609
615
|
|
|
@@ -620,7 +626,7 @@ class TestAILab(unittest.TestCase):
|
|
|
620
626
|
mock_client_instance.publish_task_revision.return_value = {"status": "published"}
|
|
621
627
|
publish_task_revision(option_list)
|
|
622
628
|
mock_client_instance.publish_task_revision.assert_called_once_with(
|
|
623
|
-
|
|
629
|
+
task_id="task1", task_name=None, revision="1"
|
|
624
630
|
)
|
|
625
631
|
mock_stdout.assert_called_once_with("Published task revision detail: \n{'status': 'published'}")
|
|
626
632
|
|
|
@@ -636,7 +642,7 @@ class TestAILab(unittest.TestCase):
|
|
|
636
642
|
mock_client_instance.start_instance.return_value = {"id": "inst1"}
|
|
637
643
|
start_instance(option_list)
|
|
638
644
|
mock_client_instance.start_instance.assert_called_once_with(
|
|
639
|
-
|
|
645
|
+
process_name="proc1", subject=None, variables=None
|
|
640
646
|
)
|
|
641
647
|
mock_stdout.assert_called_once_with("Started instance detail: \n{'id': 'inst1'}")
|
|
642
648
|
|
|
@@ -652,7 +658,7 @@ class TestAILab(unittest.TestCase):
|
|
|
652
658
|
mock_client_instance.abort_instance.return_value = {"status": "aborted"}
|
|
653
659
|
abort_instance(option_list)
|
|
654
660
|
mock_client_instance.abort_instance.assert_called_once_with(
|
|
655
|
-
|
|
661
|
+
instance_id="inst1"
|
|
656
662
|
)
|
|
657
663
|
mock_stdout.assert_called_once_with("Abort instance result: \n{'status': 'aborted'}")
|
|
658
664
|
|
|
@@ -668,7 +674,7 @@ class TestAILab(unittest.TestCase):
|
|
|
668
674
|
mock_client_instance.get_instance.return_value = {"id": "inst1"}
|
|
669
675
|
get_instance(option_list)
|
|
670
676
|
mock_client_instance.get_instance.assert_called_once_with(
|
|
671
|
-
|
|
677
|
+
instance_id="inst1"
|
|
672
678
|
)
|
|
673
679
|
mock_stdout.assert_called_once_with("Instance detail: \n{'id': 'inst1'}")
|
|
674
680
|
|
|
@@ -684,7 +690,7 @@ class TestAILab(unittest.TestCase):
|
|
|
684
690
|
mock_client_instance.get_thread_information.return_value = {"id": "thread1"}
|
|
685
691
|
get_thread_information(option_list)
|
|
686
692
|
mock_client_instance.get_thread_information.assert_called_once_with(
|
|
687
|
-
|
|
693
|
+
thread_id="thread1"
|
|
688
694
|
)
|
|
689
695
|
mock_stdout.assert_called_once_with("Thread information: \n{'id': 'thread1'}")
|
|
690
696
|
|
|
@@ -701,7 +707,7 @@ class TestAILab(unittest.TestCase):
|
|
|
701
707
|
mock_client_instance.send_user_signal.return_value = {"status": "sent"}
|
|
702
708
|
send_user_signal(option_list)
|
|
703
709
|
mock_client_instance.send_user_signal.assert_called_once_with(
|
|
704
|
-
|
|
710
|
+
instance_id="inst1", signal_name="signal1"
|
|
705
711
|
)
|
|
706
712
|
mock_stdout.assert_called_once_with("Send user signal result: \n{'status': 'sent'}")
|
|
707
713
|
|
|
@@ -717,7 +723,7 @@ class TestAILab(unittest.TestCase):
|
|
|
717
723
|
mock_client_instance.create_kb.return_value = {"id": "kb1"}
|
|
718
724
|
create_kb(option_list)
|
|
719
725
|
mock_client_instance.create_kb.assert_called_once_with(
|
|
720
|
-
|
|
726
|
+
name="kb1", artifacts=None, metadata=None
|
|
721
727
|
)
|
|
722
728
|
mock_stdout.assert_called_once_with("Created knowledge base detail: \n{'id': 'kb1'}")
|
|
723
729
|
|
|
@@ -733,7 +739,7 @@ class TestAILab(unittest.TestCase):
|
|
|
733
739
|
mock_client_instance.get_kb.return_value = {"id": "kb1"}
|
|
734
740
|
get_kb(option_list)
|
|
735
741
|
mock_client_instance.get_kb.assert_called_once_with(
|
|
736
|
-
|
|
742
|
+
kb_id="kb1", kb_name=None
|
|
737
743
|
)
|
|
738
744
|
mock_stdout.assert_called_once_with("Knowledge base detail: \n{'id': 'kb1'}")
|
|
739
745
|
|
|
@@ -746,7 +752,7 @@ class TestAILab(unittest.TestCase):
|
|
|
746
752
|
mock_client_instance.list_kbs.return_value = [{"id": "kb1"}]
|
|
747
753
|
list_kbs(option_list)
|
|
748
754
|
mock_client_instance.list_kbs.assert_called_once_with(
|
|
749
|
-
|
|
755
|
+
name=None, start="0", count="100"
|
|
750
756
|
)
|
|
751
757
|
mock_stdout.assert_called_once_with("Knowledge base list: \n[{'id': 'kb1'}]")
|
|
752
758
|
|
|
@@ -762,7 +768,7 @@ class TestAILab(unittest.TestCase):
|
|
|
762
768
|
mock_client_instance.delete_kb.return_value = {"status": "deleted"}
|
|
763
769
|
delete_kb(option_list)
|
|
764
770
|
mock_client_instance.delete_kb.assert_called_once_with(
|
|
765
|
-
|
|
771
|
+
kb_id="kb1", kb_name=None
|
|
766
772
|
)
|
|
767
773
|
mock_stdout.assert_called_once_with("Delete knowledge base result: \n{'status': 'deleted'}")
|
|
768
774
|
|
|
@@ -775,6 +781,6 @@ class TestAILab(unittest.TestCase):
|
|
|
775
781
|
mock_client_instance.list_jobs.return_value = [{"id": "job1"}]
|
|
776
782
|
list_jobs(option_list)
|
|
777
783
|
mock_client_instance.list_jobs.assert_called_once_with(
|
|
778
|
-
|
|
784
|
+
start="0", count="100", topic=None, token=None, name=None
|
|
779
785
|
)
|
|
780
786
|
mock_stdout.assert_called_once_with("Job list: \n[{'id': 'job1'}]")
|