pygeai 0.6.0b7__py3-none-any.whl → 0.6.0b11__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) hide show
  1. pygeai/_docs/source/conf.py +78 -6
  2. pygeai/_docs/source/content/api_reference/embeddings.rst +31 -1
  3. pygeai/_docs/source/content/api_reference/evaluation.rst +590 -0
  4. pygeai/_docs/source/content/api_reference/feedback.rst +237 -0
  5. pygeai/_docs/source/content/api_reference/files.rst +592 -0
  6. pygeai/_docs/source/content/api_reference/gam.rst +401 -0
  7. pygeai/_docs/source/content/api_reference/proxy.rst +318 -0
  8. pygeai/_docs/source/content/api_reference/secrets.rst +495 -0
  9. pygeai/_docs/source/content/api_reference/usage_limits.rst +390 -0
  10. pygeai/_docs/source/content/api_reference.rst +7 -0
  11. pygeai/_docs/source/content/debugger.rst +376 -83
  12. pygeai/_docs/source/content/migration.rst +528 -0
  13. pygeai/_docs/source/content/modules.rst +1 -1
  14. pygeai/_docs/source/pygeai.cli.rst +8 -0
  15. pygeai/_docs/source/pygeai.tests.cli.rst +16 -0
  16. pygeai/_docs/source/pygeai.tests.core.embeddings.rst +16 -0
  17. pygeai/_docs/source/pygeai.tests.snippets.chat.rst +40 -0
  18. pygeai/_docs/source/pygeai.tests.snippets.dbg.rst +45 -0
  19. pygeai/_docs/source/pygeai.tests.snippets.embeddings.rst +40 -0
  20. pygeai/_docs/source/pygeai.tests.snippets.evaluation.dataset.rst +197 -0
  21. pygeai/_docs/source/pygeai.tests.snippets.evaluation.plan.rst +133 -0
  22. pygeai/_docs/source/pygeai.tests.snippets.evaluation.result.rst +37 -0
  23. pygeai/_docs/source/pygeai.tests.snippets.evaluation.rst +10 -0
  24. pygeai/_docs/source/pygeai.tests.snippets.rst +1 -0
  25. pygeai/admin/clients.py +5 -0
  26. pygeai/assistant/clients.py +7 -0
  27. pygeai/assistant/data_analyst/clients.py +2 -0
  28. pygeai/assistant/rag/clients.py +11 -0
  29. pygeai/chat/clients.py +236 -25
  30. pygeai/chat/endpoints.py +3 -1
  31. pygeai/cli/commands/chat.py +322 -1
  32. pygeai/cli/commands/embeddings.py +56 -8
  33. pygeai/cli/commands/migrate.py +994 -434
  34. pygeai/cli/error_handler.py +116 -0
  35. pygeai/cli/geai.py +28 -10
  36. pygeai/cli/parsers.py +8 -2
  37. pygeai/core/base/clients.py +3 -1
  38. pygeai/core/common/exceptions.py +11 -10
  39. pygeai/core/embeddings/__init__.py +19 -0
  40. pygeai/core/embeddings/clients.py +17 -2
  41. pygeai/core/embeddings/mappers.py +16 -2
  42. pygeai/core/embeddings/responses.py +9 -2
  43. pygeai/core/feedback/clients.py +1 -0
  44. pygeai/core/files/clients.py +5 -7
  45. pygeai/core/files/managers.py +42 -0
  46. pygeai/core/llm/clients.py +4 -0
  47. pygeai/core/plugins/clients.py +1 -0
  48. pygeai/core/rerank/clients.py +1 -0
  49. pygeai/core/secrets/clients.py +6 -0
  50. pygeai/core/services/rest.py +1 -1
  51. pygeai/dbg/__init__.py +3 -0
  52. pygeai/dbg/debugger.py +565 -70
  53. pygeai/evaluation/clients.py +1 -1
  54. pygeai/evaluation/dataset/clients.py +45 -44
  55. pygeai/evaluation/plan/clients.py +27 -26
  56. pygeai/evaluation/result/clients.py +37 -5
  57. pygeai/gam/clients.py +4 -0
  58. pygeai/health/clients.py +1 -0
  59. pygeai/lab/agents/clients.py +8 -1
  60. pygeai/lab/models.py +3 -3
  61. pygeai/lab/processes/clients.py +21 -0
  62. pygeai/lab/strategies/clients.py +4 -0
  63. pygeai/lab/tools/clients.py +1 -0
  64. pygeai/migration/__init__.py +31 -0
  65. pygeai/migration/strategies.py +404 -155
  66. pygeai/migration/tools.py +170 -3
  67. pygeai/organization/clients.py +13 -0
  68. pygeai/organization/limits/clients.py +15 -0
  69. pygeai/proxy/clients.py +3 -1
  70. pygeai/tests/admin/test_clients.py +16 -11
  71. pygeai/tests/assistants/rag/test_clients.py +35 -23
  72. pygeai/tests/assistants/test_clients.py +22 -15
  73. pygeai/tests/auth/test_clients.py +14 -6
  74. pygeai/tests/chat/test_clients.py +211 -1
  75. pygeai/tests/cli/commands/test_embeddings.py +32 -9
  76. pygeai/tests/cli/commands/test_evaluation.py +7 -0
  77. pygeai/tests/cli/commands/test_migrate.py +112 -243
  78. pygeai/tests/cli/test_error_handler.py +225 -0
  79. pygeai/tests/cli/test_geai_driver.py +154 -0
  80. pygeai/tests/cli/test_parsers.py +5 -5
  81. pygeai/tests/core/embeddings/test_clients.py +144 -0
  82. pygeai/tests/core/embeddings/test_managers.py +171 -0
  83. pygeai/tests/core/embeddings/test_mappers.py +142 -0
  84. pygeai/tests/core/feedback/test_clients.py +2 -0
  85. pygeai/tests/core/files/test_clients.py +1 -0
  86. pygeai/tests/core/llm/test_clients.py +14 -9
  87. pygeai/tests/core/plugins/test_clients.py +5 -3
  88. pygeai/tests/core/rerank/test_clients.py +1 -0
  89. pygeai/tests/core/secrets/test_clients.py +19 -13
  90. pygeai/tests/dbg/test_debugger.py +453 -75
  91. pygeai/tests/evaluation/dataset/test_clients.py +3 -1
  92. pygeai/tests/evaluation/plan/test_clients.py +4 -2
  93. pygeai/tests/evaluation/result/test_clients.py +7 -5
  94. pygeai/tests/gam/test_clients.py +1 -1
  95. pygeai/tests/health/test_clients.py +1 -0
  96. pygeai/tests/lab/agents/test_clients.py +9 -0
  97. pygeai/tests/lab/processes/test_clients.py +36 -0
  98. pygeai/tests/lab/processes/test_mappers.py +3 -0
  99. pygeai/tests/lab/strategies/test_clients.py +14 -9
  100. pygeai/tests/migration/test_strategies.py +45 -218
  101. pygeai/tests/migration/test_tools.py +133 -9
  102. pygeai/tests/organization/limits/test_clients.py +17 -0
  103. pygeai/tests/organization/test_clients.py +22 -0
  104. pygeai/tests/proxy/test_clients.py +2 -0
  105. pygeai/tests/proxy/test_integration.py +1 -0
  106. pygeai/tests/snippets/chat/chat_completion_with_reasoning_effort.py +18 -0
  107. pygeai/tests/snippets/chat/get_response.py +15 -0
  108. pygeai/tests/snippets/chat/get_response_streaming.py +20 -0
  109. pygeai/tests/snippets/chat/get_response_with_files.py +16 -0
  110. pygeai/tests/snippets/chat/get_response_with_tools.py +36 -0
  111. pygeai/tests/snippets/dbg/__init__.py +0 -0
  112. pygeai/tests/snippets/dbg/basic_debugging.py +32 -0
  113. pygeai/tests/snippets/dbg/breakpoint_management.py +48 -0
  114. pygeai/tests/snippets/dbg/stack_navigation.py +45 -0
  115. pygeai/tests/snippets/dbg/stepping_example.py +40 -0
  116. pygeai/tests/snippets/embeddings/cache_example.py +31 -0
  117. pygeai/tests/snippets/embeddings/cohere_example.py +41 -0
  118. pygeai/tests/snippets/embeddings/openai_base64_example.py +27 -0
  119. pygeai/tests/snippets/embeddings/openai_example.py +30 -0
  120. pygeai/tests/snippets/embeddings/similarity_example.py +42 -0
  121. pygeai/tests/snippets/evaluation/dataset/__init__.py +0 -0
  122. pygeai/tests/snippets/evaluation/dataset/complete_workflow_example.py +195 -0
  123. pygeai/tests/snippets/evaluation/dataset/create_dataset.py +26 -0
  124. pygeai/tests/snippets/evaluation/dataset/create_dataset_from_file.py +11 -0
  125. pygeai/tests/snippets/evaluation/dataset/create_dataset_row.py +17 -0
  126. pygeai/tests/snippets/evaluation/dataset/create_expected_source.py +18 -0
  127. pygeai/tests/snippets/evaluation/dataset/create_filter_variable.py +19 -0
  128. pygeai/tests/snippets/evaluation/dataset/delete_dataset.py +9 -0
  129. pygeai/tests/snippets/evaluation/dataset/delete_dataset_row.py +10 -0
  130. pygeai/tests/snippets/evaluation/dataset/delete_expected_source.py +15 -0
  131. pygeai/tests/snippets/evaluation/dataset/delete_filter_variable.py +15 -0
  132. pygeai/tests/snippets/evaluation/dataset/get_dataset.py +9 -0
  133. pygeai/tests/snippets/evaluation/dataset/get_dataset_row.py +10 -0
  134. pygeai/tests/snippets/evaluation/dataset/get_expected_source.py +15 -0
  135. pygeai/tests/snippets/evaluation/dataset/get_filter_variable.py +15 -0
  136. pygeai/tests/snippets/evaluation/dataset/list_dataset_rows.py +9 -0
  137. pygeai/tests/snippets/evaluation/dataset/list_datasets.py +6 -0
  138. pygeai/tests/snippets/evaluation/dataset/list_expected_sources.py +10 -0
  139. pygeai/tests/snippets/evaluation/dataset/list_filter_variables.py +10 -0
  140. pygeai/tests/snippets/evaluation/dataset/update_dataset.py +15 -0
  141. pygeai/tests/snippets/evaluation/dataset/update_dataset_row.py +20 -0
  142. pygeai/tests/snippets/evaluation/dataset/update_expected_source.py +18 -0
  143. pygeai/tests/snippets/evaluation/dataset/update_filter_variable.py +19 -0
  144. pygeai/tests/snippets/evaluation/dataset/upload_dataset_rows_file.py +10 -0
  145. pygeai/tests/snippets/evaluation/plan/__init__.py +0 -0
  146. pygeai/tests/snippets/evaluation/plan/add_plan_system_metric.py +13 -0
  147. pygeai/tests/snippets/evaluation/plan/complete_workflow_example.py +136 -0
  148. pygeai/tests/snippets/evaluation/plan/create_evaluation_plan.py +24 -0
  149. pygeai/tests/snippets/evaluation/plan/create_rag_evaluation_plan.py +22 -0
  150. pygeai/tests/snippets/evaluation/plan/delete_evaluation_plan.py +9 -0
  151. pygeai/tests/snippets/evaluation/plan/delete_plan_system_metric.py +13 -0
  152. pygeai/tests/snippets/evaluation/plan/execute_evaluation_plan.py +11 -0
  153. pygeai/tests/snippets/evaluation/plan/get_evaluation_plan.py +9 -0
  154. pygeai/tests/snippets/evaluation/plan/get_plan_system_metric.py +13 -0
  155. pygeai/tests/snippets/evaluation/plan/get_system_metric.py +9 -0
  156. pygeai/tests/snippets/evaluation/plan/list_evaluation_plans.py +7 -0
  157. pygeai/tests/snippets/evaluation/plan/list_plan_system_metrics.py +9 -0
  158. pygeai/tests/snippets/evaluation/plan/list_system_metrics.py +7 -0
  159. pygeai/tests/snippets/evaluation/plan/update_evaluation_plan.py +22 -0
  160. pygeai/tests/snippets/evaluation/plan/update_plan_system_metric.py +14 -0
  161. pygeai/tests/snippets/evaluation/result/__init__.py +0 -0
  162. pygeai/tests/snippets/evaluation/result/complete_workflow_example.py +150 -0
  163. pygeai/tests/snippets/evaluation/result/get_evaluation_result.py +26 -0
  164. pygeai/tests/snippets/evaluation/result/list_evaluation_results.py +17 -0
  165. pygeai/tests/snippets/migrate/__init__.py +45 -0
  166. pygeai/tests/snippets/migrate/agent_migration.py +110 -0
  167. pygeai/tests/snippets/migrate/assistant_migration.py +64 -0
  168. pygeai/tests/snippets/migrate/orchestrator_examples.py +179 -0
  169. pygeai/tests/snippets/migrate/process_migration.py +64 -0
  170. pygeai/tests/snippets/migrate/project_migration.py +42 -0
  171. pygeai/tests/snippets/migrate/tool_migration.py +64 -0
  172. pygeai/tests/snippets/organization/create_project.py +2 -2
  173. {pygeai-0.6.0b7.dist-info → pygeai-0.6.0b11.dist-info}/METADATA +1 -1
  174. {pygeai-0.6.0b7.dist-info → pygeai-0.6.0b11.dist-info}/RECORD +178 -96
  175. {pygeai-0.6.0b7.dist-info → pygeai-0.6.0b11.dist-info}/WHEEL +0 -0
  176. {pygeai-0.6.0b7.dist-info → pygeai-0.6.0b11.dist-info}/entry_points.txt +0 -0
  177. {pygeai-0.6.0b7.dist-info → pygeai-0.6.0b11.dist-info}/licenses/LICENSE +0 -0
  178. {pygeai-0.6.0b7.dist-info → pygeai-0.6.0b11.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,401 @@
1
+ GAM OAuth Integration
2
+ =====================
3
+
4
+ The GAM (GeneXus Access Manager) module provides OAuth 2.0 authentication functionality for integrating with GeneXus applications. It enables user authentication, token management, and access to user information.
5
+
6
+ This section covers:
7
+
8
+ * Generating OAuth signin URLs
9
+ * Obtaining access tokens
10
+ * Refreshing tokens
11
+ * Retrieving user information
12
+
13
+ For each operation, you have implementation options using the Low-Level Service Layer.
14
+
15
+ Overview
16
+ --------
17
+
18
+ OAuth 2.0 Flow with GAM:
19
+
20
+ 1. **Generate Signin URL**: Create URL for user authentication
21
+ 2. **User Authorization**: User authenticates via browser
22
+ 3. **Get Access Token**: Exchange credentials/code for access token
23
+ 4. **Access Resources**: Use token to access protected resources
24
+ 5. **Refresh Token**: Obtain new access token when expired
25
+
26
+ Generate Signin URL
27
+ -------------------
28
+
29
+ Creates an OAuth 2.0 authorization URL for browser-based authentication flows.
30
+
31
+ Low-Level Service Layer
32
+ ^^^^^^^^^^^^^^^^^^^^^^^^
33
+
34
+ .. code-block:: python
35
+
36
+ from pygeai.gam.clients import GAMClient
37
+ import secrets
38
+
39
+ client = GAMClient()
40
+
41
+ # Generate random state for CSRF protection
42
+ state = secrets.token_urlsafe(32)
43
+
44
+ signin_url = client.generate_signing_url(
45
+ client_id="your-app-client-id",
46
+ redirect_uri="https://yourapp.com/callback",
47
+ scope="gam_user_data",
48
+ state=state
49
+ )
50
+
51
+ print(f"Redirect user to: {signin_url}")
52
+ # Store state for validation when user returns
53
+
54
+ **Parameters:**
55
+
56
+ * ``client_id``: (Required) Your application's client ID
57
+ * ``redirect_uri``: (Required) Callback URL registered in your app
58
+ * ``scope``: OAuth scope (default: "gam_user_data")
59
+ * ``state``: (Required) Random string for CSRF protection
60
+ * ``response_type``: Response type (default: "code")
61
+
62
+ **Returns:**
63
+ String containing the complete authorization URL.
64
+
65
+ **Scopes:**
66
+
67
+ * ``gam_user_data``: Basic user information
68
+ * ``gam_user_roles``: User roles and permissions
69
+ * Combine with ``+``: ``"gam_user_data+gam_user_roles"``
70
+
71
+
72
+ Get Access Token
73
+ ----------------
74
+
75
+ Obtains an access token using the Resource Owner Password Credentials grant.
76
+
77
+ Low-Level Service Layer
78
+ ^^^^^^^^^^^^^^^^^^^^^^^^
79
+
80
+ .. code-block:: python
81
+
82
+ from pygeai.gam.clients import GAMClient
83
+
84
+ client = GAMClient()
85
+
86
+ token_response = client.get_access_token(
87
+ client_id="your-app-client-id",
88
+ client_secret="your-app-client-secret",
89
+ username="user@example.com",
90
+ password="user-password",
91
+ scope="gam_user_data+gam_user_roles"
92
+ )
93
+
94
+ access_token = token_response['access_token']
95
+ refresh_token = token_response['refresh_token']
96
+ expires_in = token_response['expires_in']
97
+
98
+ print(f"Access token: {access_token}")
99
+ print(f"Expires in: {expires_in} seconds")
100
+
101
+ **Parameters:**
102
+
103
+ * ``client_id``: (Required) Application client ID
104
+ * ``client_secret``: (Required) Application client secret
105
+ * ``username``: (Required) User's username/email
106
+ * ``password``: (Required) User's password
107
+ * ``grant_type``: Grant type (default: "password")
108
+ * ``scope``: OAuth scope (default: "gam_user_data")
109
+ * ``authentication_type_name``: Auth type (default: "local")
110
+ * ``repository``: Repository ID for multitenant setups
111
+ * ``initial_properties``: Custom user properties array
112
+ * ``request_token_type``: Token type: "OAuth" or "Web" (default: "OAuth")
113
+
114
+ **Returns:**
115
+ Dictionary containing:
116
+
117
+ * ``access_token``: The access token
118
+ * ``token_type``: Token type (usually "Bearer")
119
+ * ``expires_in``: Token lifetime in seconds
120
+ * ``refresh_token``: Token for refreshing access
121
+ * ``scope``: Granted scopes
122
+ * ``user_guid``: User's unique identifier
123
+
124
+
125
+ Refresh Access Token
126
+ ---------------------
127
+
128
+ Obtains a new access token using a refresh token.
129
+
130
+ Low-Level Service Layer
131
+ ^^^^^^^^^^^^^^^^^^^^^^^^
132
+
133
+ .. code-block:: python
134
+
135
+ from pygeai.gam.clients import GAMClient
136
+
137
+ client = GAMClient()
138
+
139
+ new_token = client.refresh_access_token(
140
+ client_id="your-app-client-id",
141
+ client_secret="your-app-client-secret",
142
+ refresh_token="existing-refresh-token"
143
+ )
144
+
145
+ access_token = new_token['access_token']
146
+ print(f"New access token: {access_token}")
147
+
148
+ **Parameters:**
149
+
150
+ * ``client_id``: (Required) Application client ID
151
+ * ``client_secret``: (Required) Application client secret
152
+ * ``refresh_token``: (Required) Refresh token from previous response
153
+ * ``grant_type``: Must be "refresh_token" (default)
154
+
155
+ **Returns:**
156
+ Dictionary with new access token and refresh token.
157
+
158
+
159
+ Get User Information
160
+ --------------------
161
+
162
+ Retrieves authenticated user's information.
163
+
164
+ Low-Level Service Layer
165
+ ^^^^^^^^^^^^^^^^^^^^^^^^
166
+
167
+ .. code-block:: python
168
+
169
+ from pygeai.gam.clients import GAMClient
170
+
171
+ client = GAMClient()
172
+
173
+ user_info = client.get_user_info(
174
+ access_token="user-access-token"
175
+ )
176
+
177
+ print(f"User GUID: {user_info['guid']}")
178
+ print(f"Username: {user_info['username']}")
179
+ print(f"Email: {user_info['email']}")
180
+
181
+ **Parameters:**
182
+
183
+ * ``access_token``: (Required) Valid access token
184
+
185
+ **Returns:**
186
+ Dictionary containing user details based on granted scopes.
187
+
188
+
189
+ Complete OAuth Flow Example
190
+ ----------------------------
191
+
192
+ .. code-block:: python
193
+
194
+ from pygeai.gam.clients import GAMClient
195
+ import time
196
+
197
+ client = GAMClient()
198
+
199
+ # Step 1: Obtain access token
200
+ token_response = client.get_access_token(
201
+ client_id="app-client-id",
202
+ client_secret="app-secret",
203
+ username="user@example.com",
204
+ password="password",
205
+ scope="gam_user_data+gam_user_roles"
206
+ )
207
+
208
+ access_token = token_response['access_token']
209
+ refresh_token = token_response['refresh_token']
210
+ expires_in = token_response['expires_in']
211
+
212
+ print(f"Obtained access token (expires in {expires_in}s)")
213
+
214
+ # Step 2: Get user information
215
+ user_info = client.get_user_info(access_token=access_token)
216
+
217
+ print(f"\nUser Information:")
218
+ print(f" GUID: {user_info['guid']}")
219
+ print(f" Username: {user_info['username']}")
220
+ print(f" Email: {user_info.get('email', 'N/A')}")
221
+
222
+ # Step 3: Simulate token expiration and refresh
223
+ print(f"\nWaiting for token to expire...")
224
+ time.sleep(expires_in + 1)
225
+
226
+ # Step 4: Refresh the access token
227
+ new_token = client.refresh_access_token(
228
+ client_id="app-client-id",
229
+ client_secret="app-secret",
230
+ refresh_token=refresh_token
231
+ )
232
+
233
+ access_token = new_token['access_token']
234
+ print(f"Refreshed access token")
235
+
236
+
237
+ Best Practices
238
+ --------------
239
+
240
+ Token Security
241
+ ~~~~~~~~~~~~~~
242
+
243
+ * Store tokens securely (encrypted storage, environment variables)
244
+ * Never log or expose tokens in code
245
+ * Use HTTPS for all OAuth communications
246
+ * Implement token rotation
247
+ * Clear tokens from memory after use
248
+
249
+ State Parameter
250
+ ~~~~~~~~~~~~~~~
251
+
252
+ * Generate cryptographically random state values
253
+ * Store state in session for validation
254
+ * Validate state when user returns from authentication
255
+ * Prevents CSRF attacks
256
+
257
+ Token Lifecycle
258
+ ~~~~~~~~~~~~~~~
259
+
260
+ * Monitor token expiration
261
+ * Refresh tokens proactively before expiration
262
+ * Implement token refresh logic in error handlers
263
+ * Handle refresh token expiration gracefully
264
+
265
+ Scopes
266
+ ~~~~~~
267
+
268
+ * Request minimal required scopes
269
+ * Document why each scope is needed
270
+ * Handle scope changes gracefully
271
+ * Validate granted vs requested scopes
272
+
273
+
274
+ Security Considerations
275
+ -----------------------
276
+
277
+ CSRF Protection
278
+ ~~~~~~~~~~~~~~~
279
+
280
+ Always use and validate the ``state`` parameter:
281
+
282
+ .. code-block:: python
283
+
284
+ import secrets
285
+
286
+ # Generate state
287
+ state = secrets.token_urlsafe(32)
288
+ # Store in session: session['oauth_state'] = state
289
+
290
+ signin_url = client.generate_signing_url(
291
+ client_id="...",
292
+ redirect_uri="...",
293
+ state=state
294
+ )
295
+
296
+ # On callback, validate:
297
+ # if request.args.get('state') != session.get('oauth_state'):
298
+ # raise SecurityError("Invalid state parameter")
299
+
300
+ Password Grant Considerations
301
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
302
+
303
+ * Use password grant only for trusted applications
304
+ * Prefer authorization code flow for web applications
305
+ * Implement rate limiting on token requests
306
+ * Use strong password policies
307
+ * Consider multi-factor authentication
308
+
309
+ Token Storage
310
+ ~~~~~~~~~~~~~
311
+
312
+ * Never store tokens in:
313
+
314
+ * Client-side JavaScript
315
+ * URL parameters
316
+ * Logs
317
+ * Version control
318
+
319
+ * Secure storage options:
320
+
321
+ * Server-side session storage
322
+ * Encrypted database fields
323
+ * Secure key management systems
324
+
325
+
326
+ Error Handling
327
+ --------------
328
+
329
+ .. code-block:: python
330
+
331
+ from pygeai.gam.clients import GAMClient
332
+ from pygeai.core.common.exceptions import MissingRequirementException, APIError
333
+
334
+ client = GAMClient()
335
+
336
+ # Handle missing parameters
337
+ try:
338
+ url = client.generate_signing_url(
339
+ client_id="id",
340
+ # Missing redirect_uri and state
341
+ )
342
+ except MissingRequirementException as e:
343
+ print(f"Missing required parameters: {e}")
344
+
345
+ # Handle invalid credentials
346
+ try:
347
+ token = client.get_access_token(
348
+ client_id="app-id",
349
+ client_secret="secret",
350
+ username="user",
351
+ password="wrong-password"
352
+ )
353
+ except APIError as e:
354
+ print(f"Authentication failed: {e}")
355
+
356
+ # Handle expired refresh token
357
+ try:
358
+ new_token = client.refresh_access_token(
359
+ client_id="app-id",
360
+ client_secret="secret",
361
+ refresh_token="expired-token"
362
+ )
363
+ except APIError as e:
364
+ print("Refresh token expired, user must re-authenticate")
365
+
366
+
367
+ Integration with GEAI
368
+ ---------------------
369
+
370
+ Using GAM tokens with GEAI services:
371
+
372
+ .. code-block:: python
373
+
374
+ from pygeai.gam.clients import GAMClient
375
+ from pygeai.assistant.managers import AssistantManager
376
+
377
+ # Authenticate via GAM
378
+ gam_client = GAMClient()
379
+ token_response = gam_client.get_access_token(
380
+ client_id="app-id",
381
+ client_secret="secret",
382
+ username="user@example.com",
383
+ password="password"
384
+ )
385
+
386
+ access_token = token_response['access_token']
387
+
388
+ # Use token with GEAI services
389
+ # (Specific integration depends on service configuration)
390
+ # Some services may accept GAM tokens for authentication
391
+
392
+
393
+ Notes
394
+ -----
395
+
396
+ * GAM OAuth follows the OAuth 2.0 specification
397
+ * Password grant is suitable for trusted applications only
398
+ * Refresh tokens have longer lifetimes than access tokens
399
+ * Token response may vary based on ``request_token_type``
400
+ * Multitenant deployments require ``repository`` parameter
401
+ * Custom user properties can be set via ``initial_properties``
@@ -0,0 +1,318 @@
1
+ Proxy
2
+ =====
3
+
4
+ The Proxy module enables tool proxying functionality, allowing external tools and services to be registered and made available to AI assistants. This creates a bridge between GEAI assistants and external APIs or custom functions.
5
+
6
+ This section covers:
7
+
8
+ * Registering tool proxies
9
+ * Submitting jobs to proxies
10
+ * Monitoring job execution
11
+ * Retrieving results
12
+
13
+ For each operation, you use the Low-Level Service Layer.
14
+
15
+ Overview
16
+ --------
17
+
18
+ The proxy system enables:
19
+
20
+ * **Tool Registration**: Register external tools with the system
21
+ * **Job Submission**: Submit work to registered tools
22
+ * **Async Execution**: Tools process jobs asynchronously
23
+ * **Result Retrieval**: Poll for and retrieve job results
24
+ * **Server Deployment**: Run proxy servers to handle tool execution
25
+
26
+ Architecture:
27
+
28
+ 1. Register tools with proxy
29
+ 2. Assistant requests tool execution
30
+ 3. Job submitted to proxy
31
+ 4. Proxy routes to appropriate tool/server
32
+ 5. Results returned to assistant
33
+
34
+ Tool Proxy Registration
35
+ -----------------------
36
+
37
+ Register a Proxy
38
+ ~~~~~~~~~~~~~~~~
39
+
40
+ .. code-block:: python
41
+
42
+ from pygeai.proxy.clients import ToolProxyData, ProxiedTool
43
+ import uuid
44
+
45
+ # Define a tool
46
+ tool = ProxiedTool(
47
+ name="weather_lookup",
48
+ description="Get current weather for a location",
49
+ server_name="weather-server",
50
+ input_schema={
51
+ "type": "object",
52
+ "properties": {
53
+ "location": {
54
+ "type": "string",
55
+ "description": "City name"
56
+ }
57
+ },
58
+ "required": ["location"]
59
+ }
60
+ )
61
+
62
+ # Create proxy registration
63
+ proxy_data = ToolProxyData(
64
+ id=uuid.uuid4(),
65
+ name="Weather Tools",
66
+ description="Weather information tools",
67
+ affinity=uuid.uuid4(),
68
+ tools=[tool]
69
+ )
70
+
71
+ # Register (implementation depends on proxy client setup)
72
+ # proxy_client.register(proxy_data)
73
+
74
+ **Components:**
75
+
76
+ * ``ToolProxyData``: Proxy registration information
77
+ * ``ProxiedTool``: Individual tool definition
78
+ * ``input_schema``: JSON Schema for tool parameters
79
+
80
+ Job Management
81
+ --------------
82
+
83
+ Submit Job
84
+ ~~~~~~~~~~
85
+
86
+ .. code-block:: python
87
+
88
+ from pygeai.proxy.clients import ToolProxyJob
89
+
90
+ # Job submission (conceptual - actual implementation may vary)
91
+ job = {
92
+ "proxy_id": "proxy-uuid",
93
+ "tool_name": "weather_lookup",
94
+ "input": {
95
+ "location": "San Francisco"
96
+ }
97
+ }
98
+
99
+ # Submit job to proxy
100
+ # result = proxy_client.submit_job(job)
101
+
102
+
103
+ Check Job Status
104
+ ~~~~~~~~~~~~~~~~
105
+
106
+ .. code-block:: python
107
+
108
+ from pygeai.proxy.clients import ToolProxyJob
109
+
110
+ # Poll for job completion
111
+ job = ToolProxyJob(
112
+ id=uuid.UUID("job-uuid"),
113
+ proxy_id=uuid.UUID("proxy-uuid"),
114
+ proxy_status="active",
115
+ job_status="pending"
116
+ )
117
+
118
+ # Check status
119
+ # status = proxy_client.get_job_status(job.id)
120
+
121
+
122
+ Get Job Result
123
+ ~~~~~~~~~~~~~~
124
+
125
+ .. code-block:: python
126
+
127
+ from pygeai.proxy.clients import ToolProxyJobResult
128
+
129
+ # Retrieve completed job result
130
+ result = ToolProxyJobResult(
131
+ success=True,
132
+ job=job # ToolProxyJob instance
133
+ )
134
+
135
+ if result.success:
136
+ output = result.job.output
137
+ print(f"Result: {output}")
138
+
139
+
140
+ Proxy Server
141
+ ------------
142
+
143
+ The proxy module includes server functionality to handle tool execution:
144
+
145
+ .. code-block:: python
146
+
147
+ from pygeai.proxy.servers import ProxyServer
148
+ from pygeai.proxy.config import ProxyConfig
149
+
150
+ # Configure proxy server
151
+ config = ProxyConfig(
152
+ host="localhost",
153
+ port=8080,
154
+ # Additional configuration...
155
+ )
156
+
157
+ # Start server
158
+ server = ProxyServer(config)
159
+ server.start()
160
+
161
+ **Note:** Server deployment typically runs as a separate service.
162
+
163
+
164
+ Complete Example
165
+ ----------------
166
+
167
+ .. code-block:: python
168
+
169
+ from pygeai.proxy.clients import ToolProxyData, ProxiedTool
170
+ from pygeai.proxy.tool import ProxiedTool
171
+ import uuid
172
+
173
+ # Define tools
174
+ calculator_tool = ProxiedTool(
175
+ name="calculate",
176
+ description="Perform mathematical calculations",
177
+ server_name="calc-server",
178
+ input_schema={
179
+ "type": "object",
180
+ "properties": {
181
+ "expression": {"type": "string"},
182
+ "operation": {"type": "string", "enum": ["add", "subtract", "multiply", "divide"]}
183
+ }
184
+ }
185
+ )
186
+
187
+ database_tool = ProxiedTool(
188
+ name="query_db",
189
+ description="Query customer database",
190
+ server_name="db-server",
191
+ input_schema={
192
+ "type": "object",
193
+ "properties": {
194
+ "query": {"type": "string"},
195
+ "limit": {"type": "integer"}
196
+ }
197
+ }
198
+ )
199
+
200
+ # Create proxy with multiple tools
201
+ proxy = ToolProxyData(
202
+ id=uuid.uuid4(),
203
+ name="Business Tools",
204
+ description="Tools for business operations",
205
+ tools=[calculator_tool, database_tool]
206
+ )
207
+
208
+ print(f"Proxy configuration: {proxy.to_dict()}")
209
+
210
+
211
+ Tool Definition Schema
212
+ ----------------------
213
+
214
+ Required Fields
215
+ ~~~~~~~~~~~~~~~
216
+
217
+ * ``name``: Unique tool identifier
218
+ * ``description``: Human-readable description
219
+ * ``server_name``: Server handling this tool
220
+ * ``input_schema``: JSON Schema for parameters
221
+
222
+ Input Schema Format
223
+ ~~~~~~~~~~~~~~~~~~~
224
+
225
+ .. code-block:: python
226
+
227
+ input_schema = {
228
+ "type": "object",
229
+ "properties": {
230
+ "param1": {
231
+ "type": "string",
232
+ "description": "First parameter",
233
+ "enum": ["option1", "option2"] # Optional
234
+ },
235
+ "param2": {
236
+ "type": "integer",
237
+ "description": "Second parameter",
238
+ "minimum": 0, # Optional constraints
239
+ "maximum": 100
240
+ }
241
+ },
242
+ "required": ["param1"]
243
+ }
244
+
245
+
246
+ Best Practices
247
+ --------------
248
+
249
+ Tool Design
250
+ ~~~~~~~~~~~
251
+
252
+ * Use clear, descriptive tool names
253
+ * Provide detailed descriptions
254
+ * Define complete input schemas
255
+ * Include parameter descriptions
256
+ * Specify required vs optional parameters
257
+ * Add validation constraints
258
+
259
+ Security
260
+ ~~~~~~~~
261
+
262
+ * Validate all input parameters
263
+ * Sanitize user inputs
264
+ * Implement authentication
265
+ * Use HTTPS for communication
266
+ * Rate limit tool usage
267
+ * Log all tool executions
268
+
269
+ Error Handling
270
+ ~~~~~~~~~~~~~~
271
+
272
+ * Return clear error messages
273
+ * Include error codes
274
+ * Handle timeouts gracefully
275
+ * Implement retry logic
276
+ * Log failures for debugging
277
+
278
+ Performance
279
+ ~~~~~~~~~~~
280
+
281
+ * Optimize tool execution time
282
+ * Implement caching where appropriate
283
+ * Use async processing
284
+ * Monitor resource usage
285
+ * Scale servers based on load
286
+
287
+
288
+ Integration with Assistants
289
+ ----------------------------
290
+
291
+ Tools registered via proxy can be made available to assistants:
292
+
293
+ .. code-block:: python
294
+
295
+ # Register proxy with tools
296
+ # ...
297
+
298
+ # Configure assistant to use proxied tools
299
+ # (Specific integration depends on assistant configuration)
300
+
301
+ # Assistant can now call:
302
+ # "Get the weather in Tokyo"
303
+ # -> Routes to weather_lookup tool
304
+ # -> Returns weather data
305
+
306
+
307
+ Notes
308
+ -----
309
+
310
+ * Proxies enable extensibility of assistant capabilities
311
+ * Tools execute asynchronously
312
+ * Affinity groups related tools
313
+ * Public vs private tool visibility options
314
+ * Server handles actual tool execution
315
+ * Input schemas use JSON Schema specification
316
+ * Tool responses should be JSON-serializable
317
+
318
+ For detailed proxy architecture, see ``docs/geai-proxy/README.md``.