pygeai 0.7.0b1__py3-none-any.whl → 0.7.0b4__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/chat/clients.py +56 -32
- pygeai/cli/commands/base.py +167 -6
- pygeai/cli/commands/migrate.py +2 -3
- pygeai/cli/geai.py +15 -7
- pygeai/cli/texts/help.py +26 -1
- pygeai/core/handlers.py +27 -14
- pygeai/core/utils/console.py +69 -5
- pygeai/core/utils/parsers.py +33 -12
- pygeai/lab/models.py +1 -1
- pygeai/lab/processes/endpoints.py +1 -1
- pygeai/migration/strategies.py +6 -14
- pygeai/tests/chat/test_streaming_json.py +436 -0
- pygeai/tests/cli/commands/test_json_parsing.py +419 -0
- pygeai/tests/core/utils/test_parsers.py +379 -0
- {pygeai-0.7.0b1.dist-info → pygeai-0.7.0b4.dist-info}/METADATA +1 -1
- {pygeai-0.7.0b1.dist-info → pygeai-0.7.0b4.dist-info}/RECORD +20 -17
- {pygeai-0.7.0b1.dist-info → pygeai-0.7.0b4.dist-info}/WHEEL +1 -1
- {pygeai-0.7.0b1.dist-info → pygeai-0.7.0b4.dist-info}/entry_points.txt +0 -0
- {pygeai-0.7.0b1.dist-info → pygeai-0.7.0b4.dist-info}/licenses/LICENSE +0 -0
- {pygeai-0.7.0b1.dist-info → pygeai-0.7.0b4.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
from unittest.mock import Mock
|
|
3
|
+
from json import JSONDecodeError
|
|
4
|
+
|
|
5
|
+
from pygeai.core.utils.parsers import parse_json_response
|
|
6
|
+
from pygeai.core.common.exceptions import InvalidAPIResponseException
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TestParseJsonResponse(unittest.TestCase):
|
|
10
|
+
"""
|
|
11
|
+
Comprehensive tests for parse_json_response() function.
|
|
12
|
+
|
|
13
|
+
Run with:
|
|
14
|
+
python -m unittest pygeai.tests.core.utils.test_parsers.TestParseJsonResponse
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
def test_parse_valid_json_simple(self):
|
|
18
|
+
"""Test parsing simple valid JSON response"""
|
|
19
|
+
mock_response = Mock()
|
|
20
|
+
mock_response.json.return_value = {"key": "value"}
|
|
21
|
+
|
|
22
|
+
result = parse_json_response(mock_response, "test operation")
|
|
23
|
+
|
|
24
|
+
self.assertEqual(result, {"key": "value"})
|
|
25
|
+
mock_response.json.assert_called_once()
|
|
26
|
+
|
|
27
|
+
def test_parse_valid_json_complex(self):
|
|
28
|
+
"""Test parsing complex nested JSON response"""
|
|
29
|
+
complex_data = {
|
|
30
|
+
"data": {
|
|
31
|
+
"items": [1, 2, 3],
|
|
32
|
+
"metadata": {
|
|
33
|
+
"count": 3,
|
|
34
|
+
"nested": {
|
|
35
|
+
"deep": "value"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"status": "success"
|
|
40
|
+
}
|
|
41
|
+
mock_response = Mock()
|
|
42
|
+
mock_response.json.return_value = complex_data
|
|
43
|
+
|
|
44
|
+
result = parse_json_response(mock_response, "fetch data")
|
|
45
|
+
|
|
46
|
+
self.assertEqual(result, complex_data)
|
|
47
|
+
self.assertEqual(result["data"]["items"], [1, 2, 3])
|
|
48
|
+
self.assertEqual(result["data"]["metadata"]["nested"]["deep"], "value")
|
|
49
|
+
|
|
50
|
+
def test_parse_valid_json_empty_object(self):
|
|
51
|
+
"""Test parsing empty JSON object"""
|
|
52
|
+
mock_response = Mock()
|
|
53
|
+
mock_response.json.return_value = {}
|
|
54
|
+
|
|
55
|
+
result = parse_json_response(mock_response, "test operation")
|
|
56
|
+
|
|
57
|
+
self.assertEqual(result, {})
|
|
58
|
+
|
|
59
|
+
def test_parse_valid_json_array(self):
|
|
60
|
+
"""Test parsing JSON array"""
|
|
61
|
+
mock_response = Mock()
|
|
62
|
+
mock_response.json.return_value = [1, 2, 3, 4, 5]
|
|
63
|
+
|
|
64
|
+
result = parse_json_response(mock_response, "get list")
|
|
65
|
+
|
|
66
|
+
self.assertEqual(result, [1, 2, 3, 4, 5])
|
|
67
|
+
|
|
68
|
+
def test_parse_valid_json_null_values(self):
|
|
69
|
+
"""Test parsing JSON with null values"""
|
|
70
|
+
mock_response = Mock()
|
|
71
|
+
mock_response.json.return_value = {
|
|
72
|
+
"field1": None,
|
|
73
|
+
"field2": "value",
|
|
74
|
+
"field3": None
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
result = parse_json_response(mock_response, "test operation")
|
|
78
|
+
|
|
79
|
+
self.assertIsNone(result["field1"])
|
|
80
|
+
self.assertEqual(result["field2"], "value")
|
|
81
|
+
self.assertIsNone(result["field3"])
|
|
82
|
+
|
|
83
|
+
def test_parse_json_decode_error_no_context(self):
|
|
84
|
+
"""Test JSONDecodeError handling without context"""
|
|
85
|
+
mock_response = Mock()
|
|
86
|
+
mock_response.json.side_effect = JSONDecodeError("msg", "doc", 0)
|
|
87
|
+
mock_response.status_code = 500
|
|
88
|
+
mock_response.text = "Invalid JSON"
|
|
89
|
+
|
|
90
|
+
with self.assertRaises(InvalidAPIResponseException) as context:
|
|
91
|
+
parse_json_response(mock_response, "get data")
|
|
92
|
+
|
|
93
|
+
exception_msg = str(context.exception)
|
|
94
|
+
self.assertIn("Unable to get data", exception_msg)
|
|
95
|
+
self.assertIn("Invalid JSON", exception_msg)
|
|
96
|
+
|
|
97
|
+
def test_parse_json_decode_error_single_context(self):
|
|
98
|
+
"""Test JSONDecodeError with single context parameter"""
|
|
99
|
+
mock_response = Mock()
|
|
100
|
+
mock_response.json.side_effect = JSONDecodeError("msg", "doc", 0)
|
|
101
|
+
mock_response.status_code = 404
|
|
102
|
+
mock_response.text = "Not found"
|
|
103
|
+
|
|
104
|
+
with self.assertRaises(InvalidAPIResponseException) as context:
|
|
105
|
+
parse_json_response(
|
|
106
|
+
mock_response,
|
|
107
|
+
"get agent",
|
|
108
|
+
agent_id="agent-123"
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
exception_msg = str(context.exception)
|
|
112
|
+
self.assertIn("Unable to get agent 'agent-123'", exception_msg)
|
|
113
|
+
self.assertIn("Not found", exception_msg)
|
|
114
|
+
|
|
115
|
+
def test_parse_json_decode_error_multiple_context(self):
|
|
116
|
+
"""Test JSONDecodeError with multiple context parameters"""
|
|
117
|
+
mock_response = Mock()
|
|
118
|
+
mock_response.json.side_effect = JSONDecodeError("msg", "doc", 0)
|
|
119
|
+
mock_response.status_code = 400
|
|
120
|
+
mock_response.text = "Bad request"
|
|
121
|
+
|
|
122
|
+
with self.assertRaises(InvalidAPIResponseException) as context:
|
|
123
|
+
parse_json_response(
|
|
124
|
+
mock_response,
|
|
125
|
+
"update agent",
|
|
126
|
+
agent_id="agent-123",
|
|
127
|
+
project_id="proj-456"
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
exception_msg = str(context.exception)
|
|
131
|
+
self.assertIn("Unable to update agent", exception_msg)
|
|
132
|
+
# Should contain both context values
|
|
133
|
+
self.assertIn("agent-123", exception_msg)
|
|
134
|
+
self.assertIn("proj-456", exception_msg)
|
|
135
|
+
|
|
136
|
+
def test_parse_json_different_status_codes(self):
|
|
137
|
+
"""Test error handling with various HTTP status codes"""
|
|
138
|
+
status_codes = [400, 401, 403, 404, 500, 502, 503]
|
|
139
|
+
|
|
140
|
+
for status_code in status_codes:
|
|
141
|
+
with self.subTest(status_code=status_code):
|
|
142
|
+
mock_response = Mock()
|
|
143
|
+
mock_response.json.side_effect = JSONDecodeError("msg", "doc", 0)
|
|
144
|
+
mock_response.status_code = status_code
|
|
145
|
+
mock_response.text = f"Error {status_code}"
|
|
146
|
+
|
|
147
|
+
with self.assertRaises(InvalidAPIResponseException):
|
|
148
|
+
parse_json_response(mock_response, "test operation")
|
|
149
|
+
|
|
150
|
+
def test_parse_json_special_characters(self):
|
|
151
|
+
"""Test parsing JSON with special characters"""
|
|
152
|
+
mock_response = Mock()
|
|
153
|
+
mock_response.json.return_value = {
|
|
154
|
+
"text": "Hello \"world\"",
|
|
155
|
+
"unicode": "こんにちは",
|
|
156
|
+
"symbols": "!@#$%^&*()",
|
|
157
|
+
"newlines": "line1\nline2\nline3"
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
result = parse_json_response(mock_response, "test operation")
|
|
161
|
+
|
|
162
|
+
self.assertEqual(result["text"], "Hello \"world\"")
|
|
163
|
+
self.assertEqual(result["unicode"], "こんにちは")
|
|
164
|
+
self.assertEqual(result["symbols"], "!@#$%^&*()")
|
|
165
|
+
self.assertEqual(result["newlines"], "line1\nline2\nline3")
|
|
166
|
+
|
|
167
|
+
def test_parse_json_large_numbers(self):
|
|
168
|
+
"""Test parsing JSON with large numbers"""
|
|
169
|
+
mock_response = Mock()
|
|
170
|
+
mock_response.json.return_value = {
|
|
171
|
+
"small": 1,
|
|
172
|
+
"large_int": 9999999999999999,
|
|
173
|
+
"float": 123.456789,
|
|
174
|
+
"scientific": 1.23e-10
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
result = parse_json_response(mock_response, "test operation")
|
|
178
|
+
|
|
179
|
+
self.assertEqual(result["small"], 1)
|
|
180
|
+
self.assertEqual(result["large_int"], 9999999999999999)
|
|
181
|
+
self.assertAlmostEqual(result["float"], 123.456789, places=6)
|
|
182
|
+
|
|
183
|
+
def test_parse_json_boolean_values(self):
|
|
184
|
+
"""Test parsing JSON with boolean values"""
|
|
185
|
+
mock_response = Mock()
|
|
186
|
+
mock_response.json.return_value = {
|
|
187
|
+
"true_value": True,
|
|
188
|
+
"false_value": False,
|
|
189
|
+
"null_value": None
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
result = parse_json_response(mock_response, "test operation")
|
|
193
|
+
|
|
194
|
+
self.assertTrue(result["true_value"])
|
|
195
|
+
self.assertFalse(result["false_value"])
|
|
196
|
+
self.assertIsNone(result["null_value"])
|
|
197
|
+
|
|
198
|
+
def test_parse_json_empty_string_response(self):
|
|
199
|
+
"""Test handling of empty string JSON response"""
|
|
200
|
+
mock_response = Mock()
|
|
201
|
+
mock_response.json.side_effect = JSONDecodeError("Expecting value", "", 0)
|
|
202
|
+
mock_response.status_code = 200
|
|
203
|
+
mock_response.text = ""
|
|
204
|
+
|
|
205
|
+
with self.assertRaises(InvalidAPIResponseException):
|
|
206
|
+
parse_json_response(mock_response, "test operation")
|
|
207
|
+
|
|
208
|
+
def test_parse_json_preserves_order(self):
|
|
209
|
+
"""Test that JSON parsing preserves data structure"""
|
|
210
|
+
ordered_data = {
|
|
211
|
+
"first": 1,
|
|
212
|
+
"second": 2,
|
|
213
|
+
"third": 3,
|
|
214
|
+
"array": ["a", "b", "c"]
|
|
215
|
+
}
|
|
216
|
+
mock_response = Mock()
|
|
217
|
+
mock_response.json.return_value = ordered_data
|
|
218
|
+
|
|
219
|
+
result = parse_json_response(mock_response, "test operation")
|
|
220
|
+
|
|
221
|
+
self.assertEqual(list(result.keys()), ["first", "second", "third", "array"])
|
|
222
|
+
self.assertEqual(result["array"], ["a", "b", "c"])
|
|
223
|
+
|
|
224
|
+
def test_parse_json_with_context_formatting(self):
|
|
225
|
+
"""Test that context formatting works correctly in error messages"""
|
|
226
|
+
mock_response = Mock()
|
|
227
|
+
mock_response.json.side_effect = JSONDecodeError("msg", "doc", 0)
|
|
228
|
+
mock_response.status_code = 500
|
|
229
|
+
mock_response.text = "Error"
|
|
230
|
+
|
|
231
|
+
# Test with string context
|
|
232
|
+
with self.assertRaises(InvalidAPIResponseException) as ctx:
|
|
233
|
+
parse_json_response(mock_response, "operation", name="test")
|
|
234
|
+
self.assertIn("'test'", str(ctx.exception))
|
|
235
|
+
|
|
236
|
+
# Test with numeric context
|
|
237
|
+
with self.assertRaises(InvalidAPIResponseException) as ctx:
|
|
238
|
+
parse_json_response(mock_response, "operation", id=123)
|
|
239
|
+
self.assertIn("'123'", str(ctx.exception))
|
|
240
|
+
|
|
241
|
+
def test_parse_json_real_world_api_response(self):
|
|
242
|
+
"""Test parsing realistic API response structure"""
|
|
243
|
+
api_response = {
|
|
244
|
+
"id": "agent-123",
|
|
245
|
+
"name": "Test Agent",
|
|
246
|
+
"status": "active",
|
|
247
|
+
"created_at": "2024-01-01T00:00:00Z",
|
|
248
|
+
"metadata": {
|
|
249
|
+
"version": "1.0",
|
|
250
|
+
"tags": ["production", "critical"]
|
|
251
|
+
},
|
|
252
|
+
"config": {
|
|
253
|
+
"temperature": 0.7,
|
|
254
|
+
"max_tokens": 1000
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
mock_response = Mock()
|
|
258
|
+
mock_response.json.return_value = api_response
|
|
259
|
+
|
|
260
|
+
result = parse_json_response(mock_response, "get agent", agent_id="agent-123")
|
|
261
|
+
|
|
262
|
+
self.assertEqual(result["id"], "agent-123")
|
|
263
|
+
self.assertEqual(result["name"], "Test Agent")
|
|
264
|
+
self.assertEqual(result["metadata"]["version"], "1.0")
|
|
265
|
+
self.assertEqual(len(result["metadata"]["tags"]), 2)
|
|
266
|
+
self.assertEqual(result["config"]["temperature"], 0.7)
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
class TestParseJsonResponseEdgeCases(unittest.TestCase):
|
|
270
|
+
"""
|
|
271
|
+
Edge case tests for parse_json_response()
|
|
272
|
+
|
|
273
|
+
Run with:
|
|
274
|
+
python -m unittest pygeai.tests.core.utils.test_parsers.TestParseJsonResponseEdgeCases
|
|
275
|
+
"""
|
|
276
|
+
|
|
277
|
+
def test_response_json_method_not_callable(self):
|
|
278
|
+
"""Test behavior when response.json is not callable"""
|
|
279
|
+
mock_response = Mock()
|
|
280
|
+
mock_response.json = "not a method"
|
|
281
|
+
|
|
282
|
+
with self.assertRaises(TypeError):
|
|
283
|
+
parse_json_response(mock_response, "test operation")
|
|
284
|
+
|
|
285
|
+
def test_response_without_json_method(self):
|
|
286
|
+
"""Test behavior when response has no json method"""
|
|
287
|
+
mock_response = Mock(spec=[]) # No methods
|
|
288
|
+
|
|
289
|
+
with self.assertRaises(AttributeError):
|
|
290
|
+
parse_json_response(mock_response, "test operation")
|
|
291
|
+
|
|
292
|
+
def test_json_method_raises_other_exception(self):
|
|
293
|
+
"""Test that non-JSONDecodeError exceptions are not caught"""
|
|
294
|
+
mock_response = Mock()
|
|
295
|
+
mock_response.json.side_effect = ValueError("Some other error")
|
|
296
|
+
|
|
297
|
+
# Should raise ValueError, not catch it
|
|
298
|
+
with self.assertRaises(ValueError):
|
|
299
|
+
parse_json_response(mock_response, "test operation")
|
|
300
|
+
|
|
301
|
+
def test_extremely_nested_json(self):
|
|
302
|
+
"""Test parsing deeply nested JSON structure"""
|
|
303
|
+
# Create deeply nested structure
|
|
304
|
+
nested = {"level": 10}
|
|
305
|
+
for i in range(9, 0, -1):
|
|
306
|
+
nested = {"level": i, "nested": nested}
|
|
307
|
+
|
|
308
|
+
mock_response = Mock()
|
|
309
|
+
mock_response.json.return_value = nested
|
|
310
|
+
|
|
311
|
+
result = parse_json_response(mock_response, "test operation")
|
|
312
|
+
|
|
313
|
+
# Verify we can access deep nesting
|
|
314
|
+
current = result
|
|
315
|
+
for i in range(1, 11):
|
|
316
|
+
self.assertEqual(current["level"], i)
|
|
317
|
+
if i < 10:
|
|
318
|
+
current = current["nested"]
|
|
319
|
+
|
|
320
|
+
def test_json_with_mixed_types_in_array(self):
|
|
321
|
+
"""Test parsing array with mixed types"""
|
|
322
|
+
mock_response = Mock()
|
|
323
|
+
mock_response.json.return_value = {
|
|
324
|
+
"mixed": [1, "string", True, None, {"key": "value"}, [1, 2, 3]]
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
result = parse_json_response(mock_response, "test operation")
|
|
328
|
+
|
|
329
|
+
self.assertEqual(result["mixed"][0], 1)
|
|
330
|
+
self.assertEqual(result["mixed"][1], "string")
|
|
331
|
+
self.assertTrue(result["mixed"][2])
|
|
332
|
+
self.assertIsNone(result["mixed"][3])
|
|
333
|
+
self.assertEqual(result["mixed"][4], {"key": "value"})
|
|
334
|
+
self.assertEqual(result["mixed"][5], [1, 2, 3])
|
|
335
|
+
|
|
336
|
+
def test_context_with_special_characters(self):
|
|
337
|
+
"""Test context parameters with special characters"""
|
|
338
|
+
mock_response = Mock()
|
|
339
|
+
mock_response.json.side_effect = JSONDecodeError("msg", "doc", 0)
|
|
340
|
+
mock_response.status_code = 400
|
|
341
|
+
mock_response.text = "Error"
|
|
342
|
+
|
|
343
|
+
with self.assertRaises(InvalidAPIResponseException) as context:
|
|
344
|
+
parse_json_response(
|
|
345
|
+
mock_response,
|
|
346
|
+
"test operation",
|
|
347
|
+
name="Agent's \"Special\" Name"
|
|
348
|
+
)
|
|
349
|
+
|
|
350
|
+
exception_msg = str(context.exception)
|
|
351
|
+
self.assertIn("Unable to test operation", exception_msg)
|
|
352
|
+
|
|
353
|
+
def test_response_text_with_html(self):
|
|
354
|
+
"""Test error message when response.text contains HTML"""
|
|
355
|
+
mock_response = Mock()
|
|
356
|
+
mock_response.json.side_effect = JSONDecodeError("msg", "doc", 0)
|
|
357
|
+
mock_response.status_code = 500
|
|
358
|
+
mock_response.text = "<html><body>Internal Server Error</body></html>"
|
|
359
|
+
|
|
360
|
+
with self.assertRaises(InvalidAPIResponseException) as context:
|
|
361
|
+
parse_json_response(mock_response, "test operation")
|
|
362
|
+
|
|
363
|
+
exception_msg = str(context.exception)
|
|
364
|
+
self.assertIn("<html>", exception_msg)
|
|
365
|
+
|
|
366
|
+
def test_multiple_calls_same_response(self):
|
|
367
|
+
"""Test that calling parse multiple times works correctly"""
|
|
368
|
+
mock_response = Mock()
|
|
369
|
+
mock_response.json.return_value = {"key": "value"}
|
|
370
|
+
|
|
371
|
+
result1 = parse_json_response(mock_response, "operation 1")
|
|
372
|
+
result2 = parse_json_response(mock_response, "operation 2")
|
|
373
|
+
|
|
374
|
+
self.assertEqual(result1, result2)
|
|
375
|
+
self.assertEqual(mock_response.json.call_count, 2)
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
if __name__ == '__main__':
|
|
379
|
+
unittest.main()
|
|
@@ -164,7 +164,7 @@ pygeai/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
164
164
|
pygeai/auth/clients.py,sha256=8ND_iZS3Ac-BOjbh1ZmIadYlAiTc6_WDgoCkO1dBaD8,6264
|
|
165
165
|
pygeai/auth/endpoints.py,sha256=5gScXVyalZgz1R5KyuZcKPGKFT_FLuSroixp5vPUKbo,696
|
|
166
166
|
pygeai/chat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
167
|
-
pygeai/chat/clients.py,sha256=
|
|
167
|
+
pygeai/chat/clients.py,sha256=QO95Ncx3vwcYAWRtDMbNsX3RSenf1ao1nsRSiUQwq8U,20189
|
|
168
168
|
pygeai/chat/endpoints.py,sha256=r_zvsL5UIqnqhz9I0CG0eQSKV-egwx6EKdaZXj-HndA,343
|
|
169
169
|
pygeai/chat/iris.py,sha256=-9pDHQpWhR_PvbZ6rD8eMPFk46PI9sCdPQ9aAyvSexs,413
|
|
170
170
|
pygeai/chat/managers.py,sha256=65HfuLD68eTmNpKXf_qE7cyrwhvF6VLR2vbz52v4CEk,3095
|
|
@@ -174,7 +174,7 @@ pygeai/chat/ui.py,sha256=-xvjCzBwWlvyq-C0kN2YPczl4Q0alyJamXULOlGjKRA,34595
|
|
|
174
174
|
pygeai/cli/__init__.py,sha256=P7_xZm3j6DdYnVTanQClJjfyW5co5ovNoiizgd0NMLo,95
|
|
175
175
|
pygeai/cli/__main__.py,sha256=2RkQaX48mS2keTpv3-9rxk5dw35PL_deqxcKUUNhp6E,154
|
|
176
176
|
pygeai/cli/error_handler.py,sha256=Lw28yRk0mBvwMpuYrfbYV87g_AHoiidZo9SakoOZva4,5745
|
|
177
|
-
pygeai/cli/geai.py,sha256=
|
|
177
|
+
pygeai/cli/geai.py,sha256=w0vr-EgPgSKQq0QN6LoO6JeM57f-BlIsLXYEHM8UmDE,11112
|
|
178
178
|
pygeai/cli/geai_proxy.py,sha256=vZwI2MlM_2Ejgvk_AW1FpsEGBbYzgi4VtGS6aQC7xzk,13359
|
|
179
179
|
pygeai/cli/install_man.py,sha256=lk1QOk6CWc2azd90OCd8M4wlu4T4EKCagecj6088WNs,3793
|
|
180
180
|
pygeai/cli/parsers.py,sha256=l5YGa-QIQA9c1mxx8ofYAkxVfwuZpr1af5-af7jZTVo,4667
|
|
@@ -183,7 +183,7 @@ pygeai/cli/commands/admin.py,sha256=rPKsqMXn5p1WwKVbvZH9lHW8XsPMcgipvLt3xbx1JCU,
|
|
|
183
183
|
pygeai/cli/commands/analytics.py,sha256=6ww2LS6Go3tRUlwgMGHxKz-Y_fAee8Xg9OOq8BXZyL4,18702
|
|
184
184
|
pygeai/cli/commands/assistant.py,sha256=MCcsNaE3BiYjumqtefwIbLFyDmLrtdf40ITY8K8Y1as,16778
|
|
185
185
|
pygeai/cli/commands/auth.py,sha256=K2bVr3G8v3A59BV8bEr-u1MhimiCEcjBUoVOx8Q2-vE,7552
|
|
186
|
-
pygeai/cli/commands/base.py,sha256=
|
|
186
|
+
pygeai/cli/commands/base.py,sha256=GSfb4nak-JaanC1kUBQPBpsHw1WqVV13b5rQxwhG6dQ,13652
|
|
187
187
|
pygeai/cli/commands/builders.py,sha256=xXk1F4phSQxHN3NiQltl_KEZdCwwJiKLmVqQsft2OC4,1130
|
|
188
188
|
pygeai/cli/commands/chat.py,sha256=v7SGjGRHZ0GvGiPDAGejgV-C3xnWIVZZEapU2OLB-xU,33606
|
|
189
189
|
pygeai/cli/commands/common.py,sha256=xwr4GSgP9SK4fcU7iwwNahk0bDhzqU974Gvu_DmZZYM,16546
|
|
@@ -195,7 +195,7 @@ pygeai/cli/commands/feedback.py,sha256=SnuSlQyw9L51DNK2glhp-RyQy88lVViNLOrl9ri_0
|
|
|
195
195
|
pygeai/cli/commands/files.py,sha256=2YOo1W41iFEQ7c2tgqUl86ASred2UfiFihyTcJjFLYg,6960
|
|
196
196
|
pygeai/cli/commands/gam.py,sha256=TS6h4ocGz9Vn6EH4UJSLCxFTeJms4Zk-5MizS2iOu58,8441
|
|
197
197
|
pygeai/cli/commands/llm.py,sha256=U0lL2BOfZoV6EqEKF-DkJfGgZkacAbBqPIB6L54dxio,3819
|
|
198
|
-
pygeai/cli/commands/migrate.py,sha256=
|
|
198
|
+
pygeai/cli/commands/migrate.py,sha256=eaq91PxghJ7fPnaG1Ay4Kxo0qi5cs3MUxZ0PiNUmeMk,46512
|
|
199
199
|
pygeai/cli/commands/options.py,sha256=oVDJF-SsE80vi-W4d0n2cNo1BeeU_jqDs_TtMPkz-1I,1804
|
|
200
200
|
pygeai/cli/commands/organization.py,sha256=0P09MbpG6g_qMxmbU9LnGgwBNClmvqiaJ0AagVgWoys,25134
|
|
201
201
|
pygeai/cli/commands/rag.py,sha256=z2L3u6ckqvDxQS7VyaE3EoYu6KAWu7IEajOgB098FPk,36329
|
|
@@ -212,9 +212,9 @@ pygeai/cli/commands/lab/options.py,sha256=T13Vi97zochr0cU4yjyvvwWRPENILFDYpvqpU4
|
|
|
212
212
|
pygeai/cli/commands/lab/spec.py,sha256=7uBauh23i9TjXdT8ISQJeIH9IOfuniqvo5cPmMUlIPY,7841
|
|
213
213
|
pygeai/cli/commands/lab/utils.py,sha256=uxhgHvCRrV6WYRxR2qd3nED_hhXcxJ1tAU8MlzoshEg,456
|
|
214
214
|
pygeai/cli/texts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
215
|
-
pygeai/cli/texts/help.py,sha256=
|
|
215
|
+
pygeai/cli/texts/help.py,sha256=gZAqxuS6g_t1QqRjoi9Gm0YuIJBWD5k1EZXeBxIw24Q,25459
|
|
216
216
|
pygeai/core/__init__.py,sha256=bbNktFp7t2dOBIvWto-uGVBW8acaKIe8EKcfuLV-HmA,189
|
|
217
|
-
pygeai/core/handlers.py,sha256=
|
|
217
|
+
pygeai/core/handlers.py,sha256=j9fkUHWkkaCx1uZhdLu-wCXrxVym18B-4NNRtEXwJPA,1350
|
|
218
218
|
pygeai/core/models.py,sha256=XLdoqekExCsLTMhF_4UsuzzvlaemPNZdH11hleSIrW8,27443
|
|
219
219
|
pygeai/core/responses.py,sha256=wxlikhw1UAAB6Mib97xjq2eCFyZPWoosPwn9UhpKi7Y,2825
|
|
220
220
|
pygeai/core/singleton.py,sha256=aZ9muxWwkHuEqytwZjTTE9UTlyl272BCQDFhjYrIS1k,1013
|
|
@@ -270,8 +270,8 @@ pygeai/core/services/llm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
|
|
|
270
270
|
pygeai/core/services/llm/model.py,sha256=dv0vH2uGQDzyXh63A_nr_bmMukr6Q9nO7LuiWgvclnY,9065
|
|
271
271
|
pygeai/core/services/llm/providers.py,sha256=CS1v4qSiibuL51fQlgcARiyPoXxSnCeV5RXwNc1nmgA,293
|
|
272
272
|
pygeai/core/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
273
|
-
pygeai/core/utils/console.py,sha256=
|
|
274
|
-
pygeai/core/utils/parsers.py,sha256=
|
|
273
|
+
pygeai/core/utils/console.py,sha256=wsrKxisnawwqz3w0JkvkgjZqEsrQ1twyDe_WGn1QMzM,5321
|
|
274
|
+
pygeai/core/utils/parsers.py,sha256=WsKWKv6bqSmFeKixE9M-ptf_4UwpjotUK4WWvVH0ZQw,1933
|
|
275
275
|
pygeai/core/utils/validators.py,sha256=LoDrO5z0K8_axMdoMHGZZHlxdIFQWnzC9L7RbEQFITg,328
|
|
276
276
|
pygeai/dbg/__init__.py,sha256=yVJAWK9z9CGKRH5Mw8ZYQ0w5qOw86nXeqtRVqt_zu64,147
|
|
277
277
|
pygeai/dbg/debugger.py,sha256=xJfKVNFSxIoM6SLDBbThcU0wai6ERxzxB-sUP6wRCs8,35685
|
|
@@ -299,7 +299,7 @@ pygeai/lab/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
299
299
|
pygeai/lab/clients.py,sha256=ZpJUnyOYLRMEU1dfbJD4yokTU2m_mnR-lj4JbiO0OFA,1167
|
|
300
300
|
pygeai/lab/constants.py,sha256=ddgDnXP4GD0woi-FUJaJXzaWS3H6zmDN0B-v8utM95Q,170
|
|
301
301
|
pygeai/lab/managers.py,sha256=9ZN03FVEmKHo9khHnBJL_zaCW8X0dEdWSN4__DVbnY8,70706
|
|
302
|
-
pygeai/lab/models.py,sha256=
|
|
302
|
+
pygeai/lab/models.py,sha256=WUdbrYou64IoTiHd41kr61vbjRN7mcxVj4gUO8bg-X8,74904
|
|
303
303
|
pygeai/lab/runners.py,sha256=-uaCPHpFyiKtVOxlEjPjAc9h-onSdGAcYJ5IAZPqlb0,4147
|
|
304
304
|
pygeai/lab/agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
305
305
|
pygeai/lab/agents/clients.py,sha256=cJut_ftGFSX6ZMJlodiE7P7p_OXJre1asC-NlEQcdvs,19091
|
|
@@ -307,7 +307,7 @@ pygeai/lab/agents/endpoints.py,sha256=a3pcvP5ONGEsMyj7sTnpyPjlGPq7mHZY_5qEYK4QxE
|
|
|
307
307
|
pygeai/lab/agents/mappers.py,sha256=3w12HwWj3tnoSbDmQb-sMXjiCm84X_YU4_iH46GWu6s,12563
|
|
308
308
|
pygeai/lab/processes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
309
309
|
pygeai/lab/processes/clients.py,sha256=7CSFCzeymFG1eJUM69wGt2LjSyTG66IxiTCzAUsc_bw,43870
|
|
310
|
-
pygeai/lab/processes/endpoints.py,sha256=
|
|
310
|
+
pygeai/lab/processes/endpoints.py,sha256=5tuLINk7lBe-4SPgCKxCHC6MlMgpnTQ8RAYc-AmVe98,2105
|
|
311
311
|
pygeai/lab/processes/mappers.py,sha256=YOWcVKdcJmLMAq-f3qevzqQ8L_hjb0_jVXBdCHutpzk,15815
|
|
312
312
|
pygeai/lab/spec/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
313
313
|
pygeai/lab/spec/loader.py,sha256=Dq9MhLqFwF4RPdBBaqKPGqt43-PrNlsHpe-NXe4S0qQ,709
|
|
@@ -325,7 +325,7 @@ pygeai/man/man1/__init__.py,sha256=CFvES6cP_sbhgpm-I-QSbPC1f7Bw7cFsMW2-sxm4FtM,5
|
|
|
325
325
|
pygeai/man/man1/geai-proxy.1,sha256=N5jtjzS5dB3JjAkG0Rw8EBzhC6Jgoy6zbS7XDgcE4EA,6735
|
|
326
326
|
pygeai/man/man1/geai.1,sha256=dRJjqXLu4PRr5tELX-TveOrvp-J085rTV0NbqL5I30Q,51162
|
|
327
327
|
pygeai/migration/__init__.py,sha256=sZb6bHOjiOhjHTvU1fYbD8ubSwaitn4jyQrj59Cf8ao,843
|
|
328
|
-
pygeai/migration/strategies.py,sha256=
|
|
328
|
+
pygeai/migration/strategies.py,sha256=QBy_VIdI6JoqzvHN_rn1zJU-BsuprnnEiqKg0P4I90c,22507
|
|
329
329
|
pygeai/migration/tools.py,sha256=QiXjGBZiWeaRMjwlLCaNi3uZNVl_IAEKFtk2ww2EF98,6191
|
|
330
330
|
pygeai/organization/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
331
331
|
pygeai/organization/clients.py,sha256=IEGsVR21yI3MIpAVAHGU3Zifn3l6wQ4iYjKYTsofOA0,22925
|
|
@@ -374,6 +374,7 @@ pygeai/tests/chat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU
|
|
|
374
374
|
pygeai/tests/chat/test_clients.py,sha256=W2mhur_v8cLxR2PuQaZqZM1FJchap9x9ZDNwkfT3p5g,15894
|
|
375
375
|
pygeai/tests/chat/test_iris.py,sha256=o9pxXkk8Sv9YZ4twxbG4-ZvIv6pST8GHa3t1F-NOH3w,1179
|
|
376
376
|
pygeai/tests/chat/test_session.py,sha256=yIxUJJGRXWPjwxvsosIE7AygzKoJ45GIx5DCUYgTRqY,2906
|
|
377
|
+
pygeai/tests/chat/test_streaming_json.py,sha256=e-Wx-X0LWxMZu2hjJHLDQ6HFRmNpNH2Tzl4VlR8gbt8,15946
|
|
377
378
|
pygeai/tests/chat/test_ui.py,sha256=9gp8FwiJ8HkDTvd093Ac1bLMcfhbDbJfUwWAUpj78Ro,8868
|
|
378
379
|
pygeai/tests/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
379
380
|
pygeai/tests/cli/test_credentials_flag.py,sha256=0bqEBGLcUg5frZHOmiB-ZlpYrqqBLTMfBGF8lfH1QFk,12782
|
|
@@ -389,6 +390,7 @@ pygeai/tests/cli/commands/test_evaluation.py,sha256=svwVS8DF7G1fuRMLHXqzseL3c0QR
|
|
|
389
390
|
pygeai/tests/cli/commands/test_feedback.py,sha256=gHJ8Jt8kEemTvlpWLCyZCo73i0iBPlKhONRj4bJfhWU,3192
|
|
390
391
|
pygeai/tests/cli/commands/test_files.py,sha256=cJ0W4f8eg1T2TBZCah1k93nrk7R8ZL6_1HwCOhJOacI,7583
|
|
391
392
|
pygeai/tests/cli/commands/test_gam.py,sha256=oIFj4HJV6z1fQkIU2BmgP1VJ2zJ65UWDM6a3G8AenHM,8318
|
|
393
|
+
pygeai/tests/cli/commands/test_json_parsing.py,sha256=7SmN119ZY5dVNX-hGfQ4ulv-6R0yXg-ursybU9i2oF0,14355
|
|
392
394
|
pygeai/tests/cli/commands/test_llm.py,sha256=Mazqs8eUXjhZ1wWys96QU19XBeE8xNwh3PfCYdQXWbA,5247
|
|
393
395
|
pygeai/tests/cli/commands/test_migrate.py,sha256=k3z7M9fE_5IsWUmsTUDGQz0eNWYo50779jKmc_iVTeo,7834
|
|
394
396
|
pygeai/tests/cli/commands/test_organization.py,sha256=hHmw5sSgL1tWxf5pBuNtnLO-O4CACEv-eV-lQeO3TBs,12728
|
|
@@ -443,6 +445,7 @@ pygeai/tests/core/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
|
|
|
443
445
|
pygeai/tests/core/services/test_rest.py,sha256=CmBTpI6INCAfuxMZGraY4DnCCUk6H2Qn6bb0le6NM8U,10820
|
|
444
446
|
pygeai/tests/core/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
445
447
|
pygeai/tests/core/utils/test_console.py,sha256=z6iegGWCZXtl-dUICpK2__jNcev2cGvXHkTpzCqXwmo,3250
|
|
448
|
+
pygeai/tests/core/utils/test_parsers.py,sha256=0dbbI1JjNC0_SEEBB3j9UURfKDk-sUovdcOP5waIydQ,14438
|
|
446
449
|
pygeai/tests/dbg/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
447
450
|
pygeai/tests/dbg/test_debugger.py,sha256=EN8MDAeUNvB5C5-iqXhZ-yfL1Vldo2jK_v927hRRQ1s,23705
|
|
448
451
|
pygeai/tests/evaluation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -798,9 +801,9 @@ pygeai/vendor/a2a/utils/helpers.py,sha256=6Tbd8SVfXvdNEk6WYmLOjrAxkzFf1aIg8dkFfB
|
|
|
798
801
|
pygeai/vendor/a2a/utils/message.py,sha256=gc_EKO69CJ4HkR76IFgsy-kENJz1dn7CfSgWJWvt-gs,2197
|
|
799
802
|
pygeai/vendor/a2a/utils/task.py,sha256=BYRA_L1HpoUGJAVlyHML0lCM9Awhf2Ovjj7oPFXKbh0,1647
|
|
800
803
|
pygeai/vendor/a2a/utils/telemetry.py,sha256=VvSp1Ztqaobkmq9-3sNhhPEilJS32-JTSfKzegkj6FU,10861
|
|
801
|
-
pygeai-0.7.
|
|
802
|
-
pygeai-0.7.
|
|
803
|
-
pygeai-0.7.
|
|
804
|
-
pygeai-0.7.
|
|
805
|
-
pygeai-0.7.
|
|
806
|
-
pygeai-0.7.
|
|
804
|
+
pygeai-0.7.0b4.dist-info/licenses/LICENSE,sha256=eHfqo7-AWS8cMq0cg03lq7owsLeCmZA-xS5L0kuHnl8,1474
|
|
805
|
+
pygeai-0.7.0b4.dist-info/METADATA,sha256=QcvN2UwJZ0k-9nIREsP1YvyP2NiY3g2MNFOskwxT3Sc,8710
|
|
806
|
+
pygeai-0.7.0b4.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
|
|
807
|
+
pygeai-0.7.0b4.dist-info/entry_points.txt,sha256=OAmwuXVCQBTCE3HeVegVd37hbhCcp9TPahvdrCuMYWw,178
|
|
808
|
+
pygeai-0.7.0b4.dist-info/top_level.txt,sha256=bJFwp2tURmCfB94yXDF7ylvdSJXFDDJsyUOb-7PJgwc,7
|
|
809
|
+
pygeai-0.7.0b4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|