glaip-sdk 0.0.20__py3-none-any.whl → 0.7.7__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 (216) hide show
  1. glaip_sdk/__init__.py +44 -4
  2. glaip_sdk/_version.py +10 -3
  3. glaip_sdk/agents/__init__.py +27 -0
  4. glaip_sdk/agents/base.py +1250 -0
  5. glaip_sdk/branding.py +15 -6
  6. glaip_sdk/cli/account_store.py +540 -0
  7. glaip_sdk/cli/agent_config.py +2 -6
  8. glaip_sdk/cli/auth.py +271 -45
  9. glaip_sdk/cli/commands/__init__.py +2 -2
  10. glaip_sdk/cli/commands/accounts.py +746 -0
  11. glaip_sdk/cli/commands/agents/__init__.py +119 -0
  12. glaip_sdk/cli/commands/agents/_common.py +561 -0
  13. glaip_sdk/cli/commands/agents/create.py +151 -0
  14. glaip_sdk/cli/commands/agents/delete.py +64 -0
  15. glaip_sdk/cli/commands/agents/get.py +89 -0
  16. glaip_sdk/cli/commands/agents/list.py +129 -0
  17. glaip_sdk/cli/commands/agents/run.py +264 -0
  18. glaip_sdk/cli/commands/agents/sync_langflow.py +72 -0
  19. glaip_sdk/cli/commands/agents/update.py +112 -0
  20. glaip_sdk/cli/commands/common_config.py +104 -0
  21. glaip_sdk/cli/commands/configure.py +734 -143
  22. glaip_sdk/cli/commands/mcps/__init__.py +94 -0
  23. glaip_sdk/cli/commands/mcps/_common.py +459 -0
  24. glaip_sdk/cli/commands/mcps/connect.py +82 -0
  25. glaip_sdk/cli/commands/mcps/create.py +152 -0
  26. glaip_sdk/cli/commands/mcps/delete.py +73 -0
  27. glaip_sdk/cli/commands/mcps/get.py +212 -0
  28. glaip_sdk/cli/commands/mcps/list.py +69 -0
  29. glaip_sdk/cli/commands/mcps/tools.py +235 -0
  30. glaip_sdk/cli/commands/mcps/update.py +190 -0
  31. glaip_sdk/cli/commands/models.py +14 -12
  32. glaip_sdk/cli/commands/shared/__init__.py +21 -0
  33. glaip_sdk/cli/commands/shared/formatters.py +91 -0
  34. glaip_sdk/cli/commands/tools/__init__.py +69 -0
  35. glaip_sdk/cli/commands/tools/_common.py +80 -0
  36. glaip_sdk/cli/commands/tools/create.py +228 -0
  37. glaip_sdk/cli/commands/tools/delete.py +61 -0
  38. glaip_sdk/cli/commands/tools/get.py +103 -0
  39. glaip_sdk/cli/commands/tools/list.py +69 -0
  40. glaip_sdk/cli/commands/tools/script.py +49 -0
  41. glaip_sdk/cli/commands/tools/update.py +102 -0
  42. glaip_sdk/cli/commands/transcripts/__init__.py +90 -0
  43. glaip_sdk/cli/commands/transcripts/_common.py +9 -0
  44. glaip_sdk/cli/commands/transcripts/clear.py +5 -0
  45. glaip_sdk/cli/commands/transcripts/detail.py +5 -0
  46. glaip_sdk/cli/commands/transcripts_original.py +756 -0
  47. glaip_sdk/cli/commands/update.py +164 -23
  48. glaip_sdk/cli/config.py +49 -7
  49. glaip_sdk/cli/constants.py +38 -0
  50. glaip_sdk/cli/context.py +8 -0
  51. glaip_sdk/cli/core/__init__.py +79 -0
  52. glaip_sdk/cli/core/context.py +124 -0
  53. glaip_sdk/cli/core/output.py +851 -0
  54. glaip_sdk/cli/core/prompting.py +649 -0
  55. glaip_sdk/cli/core/rendering.py +187 -0
  56. glaip_sdk/cli/display.py +45 -32
  57. glaip_sdk/cli/entrypoint.py +20 -0
  58. glaip_sdk/cli/hints.py +57 -0
  59. glaip_sdk/cli/io.py +14 -17
  60. glaip_sdk/cli/main.py +344 -167
  61. glaip_sdk/cli/masking.py +21 -33
  62. glaip_sdk/cli/mcp_validators.py +5 -15
  63. glaip_sdk/cli/pager.py +15 -22
  64. glaip_sdk/cli/parsers/__init__.py +1 -3
  65. glaip_sdk/cli/parsers/json_input.py +11 -22
  66. glaip_sdk/cli/resolution.py +5 -10
  67. glaip_sdk/cli/rich_helpers.py +1 -3
  68. glaip_sdk/cli/slash/__init__.py +0 -9
  69. glaip_sdk/cli/slash/accounts_controller.py +580 -0
  70. glaip_sdk/cli/slash/accounts_shared.py +75 -0
  71. glaip_sdk/cli/slash/agent_session.py +65 -29
  72. glaip_sdk/cli/slash/prompt.py +24 -10
  73. glaip_sdk/cli/slash/remote_runs_controller.py +566 -0
  74. glaip_sdk/cli/slash/session.py +827 -232
  75. glaip_sdk/cli/slash/tui/__init__.py +34 -0
  76. glaip_sdk/cli/slash/tui/accounts.tcss +88 -0
  77. glaip_sdk/cli/slash/tui/accounts_app.py +933 -0
  78. glaip_sdk/cli/slash/tui/background_tasks.py +72 -0
  79. glaip_sdk/cli/slash/tui/clipboard.py +147 -0
  80. glaip_sdk/cli/slash/tui/context.py +59 -0
  81. glaip_sdk/cli/slash/tui/keybind_registry.py +235 -0
  82. glaip_sdk/cli/slash/tui/loading.py +58 -0
  83. glaip_sdk/cli/slash/tui/remote_runs_app.py +628 -0
  84. glaip_sdk/cli/slash/tui/terminal.py +402 -0
  85. glaip_sdk/cli/slash/tui/theme/__init__.py +15 -0
  86. glaip_sdk/cli/slash/tui/theme/catalog.py +79 -0
  87. glaip_sdk/cli/slash/tui/theme/manager.py +86 -0
  88. glaip_sdk/cli/slash/tui/theme/tokens.py +55 -0
  89. glaip_sdk/cli/slash/tui/toast.py +123 -0
  90. glaip_sdk/cli/transcript/__init__.py +12 -52
  91. glaip_sdk/cli/transcript/cache.py +258 -60
  92. glaip_sdk/cli/transcript/capture.py +72 -21
  93. glaip_sdk/cli/transcript/history.py +815 -0
  94. glaip_sdk/cli/transcript/launcher.py +1 -3
  95. glaip_sdk/cli/transcript/viewer.py +79 -329
  96. glaip_sdk/cli/update_notifier.py +385 -24
  97. glaip_sdk/cli/validators.py +16 -18
  98. glaip_sdk/client/__init__.py +3 -1
  99. glaip_sdk/client/_schedule_payloads.py +89 -0
  100. glaip_sdk/client/agent_runs.py +147 -0
  101. glaip_sdk/client/agents.py +370 -100
  102. glaip_sdk/client/base.py +78 -35
  103. glaip_sdk/client/hitl.py +136 -0
  104. glaip_sdk/client/main.py +25 -10
  105. glaip_sdk/client/mcps.py +166 -27
  106. glaip_sdk/client/payloads/agent/__init__.py +23 -0
  107. glaip_sdk/client/{_agent_payloads.py → payloads/agent/requests.py} +65 -74
  108. glaip_sdk/client/payloads/agent/responses.py +43 -0
  109. glaip_sdk/client/run_rendering.py +583 -79
  110. glaip_sdk/client/schedules.py +439 -0
  111. glaip_sdk/client/shared.py +21 -0
  112. glaip_sdk/client/tools.py +214 -56
  113. glaip_sdk/client/validators.py +20 -48
  114. glaip_sdk/config/constants.py +11 -0
  115. glaip_sdk/exceptions.py +1 -3
  116. glaip_sdk/hitl/__init__.py +48 -0
  117. glaip_sdk/hitl/base.py +64 -0
  118. glaip_sdk/hitl/callback.py +43 -0
  119. glaip_sdk/hitl/local.py +121 -0
  120. glaip_sdk/hitl/remote.py +523 -0
  121. glaip_sdk/icons.py +9 -3
  122. glaip_sdk/mcps/__init__.py +21 -0
  123. glaip_sdk/mcps/base.py +345 -0
  124. glaip_sdk/models/__init__.py +107 -0
  125. glaip_sdk/models/agent.py +47 -0
  126. glaip_sdk/models/agent_runs.py +117 -0
  127. glaip_sdk/models/common.py +42 -0
  128. glaip_sdk/models/mcp.py +33 -0
  129. glaip_sdk/models/schedule.py +224 -0
  130. glaip_sdk/models/tool.py +33 -0
  131. glaip_sdk/payload_schemas/__init__.py +1 -13
  132. glaip_sdk/payload_schemas/agent.py +1 -3
  133. glaip_sdk/registry/__init__.py +55 -0
  134. glaip_sdk/registry/agent.py +164 -0
  135. glaip_sdk/registry/base.py +139 -0
  136. glaip_sdk/registry/mcp.py +253 -0
  137. glaip_sdk/registry/tool.py +445 -0
  138. glaip_sdk/rich_components.py +58 -2
  139. glaip_sdk/runner/__init__.py +76 -0
  140. glaip_sdk/runner/base.py +84 -0
  141. glaip_sdk/runner/deps.py +112 -0
  142. glaip_sdk/runner/langgraph.py +872 -0
  143. glaip_sdk/runner/logging_config.py +77 -0
  144. glaip_sdk/runner/mcp_adapter/__init__.py +13 -0
  145. glaip_sdk/runner/mcp_adapter/base_mcp_adapter.py +43 -0
  146. glaip_sdk/runner/mcp_adapter/langchain_mcp_adapter.py +257 -0
  147. glaip_sdk/runner/mcp_adapter/mcp_config_builder.py +95 -0
  148. glaip_sdk/runner/tool_adapter/__init__.py +18 -0
  149. glaip_sdk/runner/tool_adapter/base_tool_adapter.py +44 -0
  150. glaip_sdk/runner/tool_adapter/langchain_tool_adapter.py +242 -0
  151. glaip_sdk/schedules/__init__.py +22 -0
  152. glaip_sdk/schedules/base.py +291 -0
  153. glaip_sdk/tools/__init__.py +22 -0
  154. glaip_sdk/tools/base.py +468 -0
  155. glaip_sdk/utils/__init__.py +59 -12
  156. glaip_sdk/utils/a2a/__init__.py +34 -0
  157. glaip_sdk/utils/a2a/event_processor.py +188 -0
  158. glaip_sdk/utils/agent_config.py +4 -14
  159. glaip_sdk/utils/bundler.py +403 -0
  160. glaip_sdk/utils/client.py +111 -0
  161. glaip_sdk/utils/client_utils.py +46 -28
  162. glaip_sdk/utils/datetime_helpers.py +58 -0
  163. glaip_sdk/utils/discovery.py +78 -0
  164. glaip_sdk/utils/display.py +25 -21
  165. glaip_sdk/utils/export.py +143 -0
  166. glaip_sdk/utils/general.py +1 -36
  167. glaip_sdk/utils/import_export.py +15 -16
  168. glaip_sdk/utils/import_resolver.py +524 -0
  169. glaip_sdk/utils/instructions.py +101 -0
  170. glaip_sdk/utils/rendering/__init__.py +115 -1
  171. glaip_sdk/utils/rendering/formatting.py +38 -23
  172. glaip_sdk/utils/rendering/layout/__init__.py +64 -0
  173. glaip_sdk/utils/rendering/{renderer → layout}/panels.py +10 -3
  174. glaip_sdk/utils/rendering/{renderer → layout}/progress.py +73 -12
  175. glaip_sdk/utils/rendering/layout/summary.py +74 -0
  176. glaip_sdk/utils/rendering/layout/transcript.py +606 -0
  177. glaip_sdk/utils/rendering/models.py +18 -8
  178. glaip_sdk/utils/rendering/renderer/__init__.py +9 -51
  179. glaip_sdk/utils/rendering/renderer/base.py +534 -882
  180. glaip_sdk/utils/rendering/renderer/config.py +4 -10
  181. glaip_sdk/utils/rendering/renderer/debug.py +30 -34
  182. glaip_sdk/utils/rendering/renderer/factory.py +138 -0
  183. glaip_sdk/utils/rendering/renderer/stream.py +13 -54
  184. glaip_sdk/utils/rendering/renderer/summary_window.py +79 -0
  185. glaip_sdk/utils/rendering/renderer/thinking.py +273 -0
  186. glaip_sdk/utils/rendering/renderer/toggle.py +182 -0
  187. glaip_sdk/utils/rendering/renderer/tool_panels.py +442 -0
  188. glaip_sdk/utils/rendering/renderer/transcript_mode.py +162 -0
  189. glaip_sdk/utils/rendering/state.py +204 -0
  190. glaip_sdk/utils/rendering/step_tree_state.py +100 -0
  191. glaip_sdk/utils/rendering/steps/__init__.py +34 -0
  192. glaip_sdk/utils/rendering/steps/event_processor.py +778 -0
  193. glaip_sdk/utils/rendering/steps/format.py +176 -0
  194. glaip_sdk/utils/rendering/{steps.py → steps/manager.py} +122 -26
  195. glaip_sdk/utils/rendering/timing.py +36 -0
  196. glaip_sdk/utils/rendering/viewer/__init__.py +21 -0
  197. glaip_sdk/utils/rendering/viewer/presenter.py +184 -0
  198. glaip_sdk/utils/resource_refs.py +29 -26
  199. glaip_sdk/utils/runtime_config.py +425 -0
  200. glaip_sdk/utils/serialization.py +32 -46
  201. glaip_sdk/utils/sync.py +162 -0
  202. glaip_sdk/utils/tool_detection.py +301 -0
  203. glaip_sdk/utils/tool_storage_provider.py +140 -0
  204. glaip_sdk/utils/validation.py +20 -28
  205. {glaip_sdk-0.0.20.dist-info → glaip_sdk-0.7.7.dist-info}/METADATA +78 -23
  206. glaip_sdk-0.7.7.dist-info/RECORD +213 -0
  207. {glaip_sdk-0.0.20.dist-info → glaip_sdk-0.7.7.dist-info}/WHEEL +2 -1
  208. glaip_sdk-0.7.7.dist-info/entry_points.txt +2 -0
  209. glaip_sdk-0.7.7.dist-info/top_level.txt +1 -0
  210. glaip_sdk/cli/commands/agents.py +0 -1412
  211. glaip_sdk/cli/commands/mcps.py +0 -1225
  212. glaip_sdk/cli/commands/tools.py +0 -597
  213. glaip_sdk/cli/utils.py +0 -1330
  214. glaip_sdk/models.py +0 -259
  215. glaip_sdk-0.0.20.dist-info/RECORD +0 -80
  216. glaip_sdk-0.0.20.dist-info/entry_points.txt +0 -3
@@ -1,11 +1,15 @@
1
- #!/usr/bin/env python3
2
- """Shared helpers for Agent client payload construction and query handling."""
1
+ """Agent request payload types and helpers.
3
2
 
3
+ Authors:
4
+ Raymond Christopher (raymond.christopher@gdplabs.id)
5
+ """
6
+
7
+ # pylint: disable=duplicate-code
4
8
  from __future__ import annotations
5
9
 
6
10
  from collections.abc import Callable, Mapping, MutableMapping, Sequence
7
11
  from copy import deepcopy
8
- from dataclasses import dataclass, field
12
+ from dataclasses import dataclass
9
13
  from typing import Any
10
14
 
11
15
  from glaip_sdk.config.constants import (
@@ -15,10 +19,7 @@ from glaip_sdk.config.constants import (
15
19
  DEFAULT_AGENT_VERSION,
16
20
  DEFAULT_MODEL,
17
21
  )
18
- from glaip_sdk.payload_schemas.agent import (
19
- AgentImportOperation,
20
- get_import_field_plan,
21
- )
22
+ from glaip_sdk.payload_schemas.agent import AgentImportOperation, get_import_field_plan
22
23
  from glaip_sdk.utils.client_utils import extract_ids
23
24
 
24
25
  _LM_CONFLICT_KEYS = {
@@ -209,6 +210,11 @@ class AgentListParams:
209
210
  return params
210
211
 
211
212
  def _base_filter_params(self) -> dict[str, Any]:
213
+ """Build base filter parameters from non-None fields.
214
+
215
+ Returns:
216
+ Dictionary of filter parameters with non-None values.
217
+ """
212
218
  return {
213
219
  key: value
214
220
  for key, value in (
@@ -221,6 +227,11 @@ class AgentListParams:
221
227
  }
222
228
 
223
229
  def _apply_pagination_params(self, params: dict[str, Any]) -> None:
230
+ """Apply pagination parameters to the params dictionary.
231
+
232
+ Args:
233
+ params: Dictionary to update with pagination parameters.
234
+ """
224
235
  if self.limit is not None:
225
236
  if not 1 <= self.limit <= 100:
226
237
  raise ValueError("limit must be between 1 and 100 inclusive")
@@ -238,6 +249,11 @@ class AgentListParams:
238
249
  params["sync_langflow_agents"] = str(self.sync_langflow_agents).lower()
239
250
 
240
251
  def _apply_timestamp_filters(self, params: dict[str, Any]) -> None:
252
+ """Apply timestamp filter parameters to the params dictionary.
253
+
254
+ Args:
255
+ params: Dictionary to update with timestamp filter parameters.
256
+ """
241
257
  timestamp_filters = {
242
258
  "created_at_start": self.created_at_start,
243
259
  "created_at_end": self.created_at_end,
@@ -249,6 +265,11 @@ class AgentListParams:
249
265
  params[key] = value
250
266
 
251
267
  def _apply_metadata_filters(self, params: dict[str, Any]) -> None:
268
+ """Apply metadata filter parameters to the params dictionary.
269
+
270
+ Args:
271
+ params: Dictionary to update with metadata filter parameters.
272
+ """
252
273
  if not self.metadata:
253
274
  return
254
275
  for key, value in self.metadata.items():
@@ -256,28 +277,6 @@ class AgentListParams:
256
277
  params[f"metadata.{key}"] = value
257
278
 
258
279
 
259
- @dataclass(slots=True)
260
- class AgentListResult:
261
- """Structured response for list_agents that retains pagination metadata."""
262
-
263
- items: list[Any] = field(default_factory=list)
264
- total: int | None = None
265
- page: int | None = None
266
- limit: int | None = None
267
- has_next: bool | None = None
268
- has_prev: bool | None = None
269
- message: str | None = None
270
-
271
- def __len__(self) -> int: # pragma: no cover - simple delegation
272
- return len(self.items)
273
-
274
- def __iter__(self): # pragma: no cover - simple delegation
275
- return iter(self.items)
276
-
277
- def __getitem__(self, index: int) -> Any: # pragma: no cover - simple delegation
278
- return self.items[index]
279
-
280
-
281
280
  @dataclass(slots=True)
282
281
  class AgentCreateRequest:
283
282
  """Declarative representation of an agent creation payload."""
@@ -348,9 +347,7 @@ class AgentCreateRequest:
348
347
  payload["tool_configs"] = _copy_structure(self.tool_configs)
349
348
 
350
349
  effective_agent_config = _sanitize_agent_config(self.agent_config)
351
- effective_agent_config = _merge_execution_timeout(
352
- effective_agent_config, self.timeout
353
- )
350
+ effective_agent_config = _merge_execution_timeout(effective_agent_config, self.timeout)
354
351
  if effective_agent_config:
355
352
  payload["agent_config"] = effective_agent_config
356
353
 
@@ -397,55 +394,51 @@ class AgentUpdateRequest:
397
394
  return payload
398
395
 
399
396
 
400
- __all__ = [
401
- "AgentCreateRequest",
402
- "AgentListParams",
403
- "AgentListResult",
404
- "AgentUpdateRequest",
405
- "merge_payload_fields",
406
- "resolve_language_model_fields",
407
- ]
408
-
409
-
410
- def _build_base_update_payload(
411
- request: AgentUpdateRequest, current_agent: Any
412
- ) -> dict[str, Any]:
397
+ def _build_base_update_payload(request: AgentUpdateRequest, current_agent: Any) -> dict[str, Any]:
398
+ """Populate immutable agent update fields using request data or existing agent defaults."""
399
+ # Support both "agent_type" (runtime class) and "type" (API response) attributes
400
+ current_type = getattr(current_agent, "agent_type", None) or getattr(current_agent, "type", None)
413
401
  return {
414
- "name": request.name.strip()
415
- if request.name is not None
416
- else getattr(current_agent, "name", None),
417
- "instruction": request.instruction.strip()
418
- if request.instruction is not None
419
- else getattr(current_agent, "instruction", None),
420
- "type": request.agent_type
421
- or getattr(current_agent, "type", None)
422
- or DEFAULT_AGENT_TYPE,
423
- "framework": request.framework
424
- or getattr(current_agent, "framework", None)
425
- or DEFAULT_AGENT_FRAMEWORK,
426
- "version": request.version
427
- or getattr(current_agent, "version", None)
428
- or DEFAULT_AGENT_VERSION,
402
+ "name": (request.name.strip() if request.name is not None else getattr(current_agent, "name", None)),
403
+ "instruction": (
404
+ request.instruction.strip()
405
+ if request.instruction is not None
406
+ else getattr(current_agent, "instruction", None)
407
+ ),
408
+ "type": request.agent_type or current_type or DEFAULT_AGENT_TYPE,
409
+ "framework": request.framework or getattr(current_agent, "framework", None) or DEFAULT_AGENT_FRAMEWORK,
410
+ "version": request.version or getattr(current_agent, "version", None) or DEFAULT_AGENT_VERSION,
429
411
  }
430
412
 
431
413
 
432
- def _resolve_update_language_model_fields(
433
- request: AgentUpdateRequest, current_agent: Any
434
- ) -> dict[str, Any]:
414
+ def _resolve_update_language_model_fields(request: AgentUpdateRequest, current_agent: Any) -> dict[str, Any]:
415
+ """Resolve the language-model portion of an update request with sensible fallbacks."""
416
+ # Check if any LM inputs were provided
417
+ has_lm_inputs = any(
418
+ [
419
+ request.model is not None,
420
+ request.language_model_id is not None,
421
+ request.provider is not None,
422
+ request.model_name is not None,
423
+ ]
424
+ )
425
+
426
+ if not has_lm_inputs:
427
+ # No LM inputs provided - preserve existing fields
428
+ return _existing_language_model_fields(current_agent)
429
+
430
+ # LM inputs provided - resolve them (may return defaults if only partial info)
435
431
  fields = resolve_language_model_fields(
436
432
  model=request.model,
437
433
  language_model_id=request.language_model_id,
438
434
  provider=request.provider,
439
435
  model_name=request.model_name,
440
436
  )
441
- if not fields:
442
- fields = _existing_language_model_fields(current_agent)
443
437
  return fields
444
438
 
445
439
 
446
- def _collect_optional_update_fields(
447
- request: AgentUpdateRequest, current_agent: Any
448
- ) -> dict[str, Any]:
440
+ def _collect_optional_update_fields(request: AgentUpdateRequest, current_agent: Any) -> dict[str, Any]:
441
+ """Collect optional agent fields, preserving current values when updates are absent."""
449
442
  result: dict[str, Any] = {}
450
443
 
451
444
  for field_name, value in (
@@ -483,9 +476,8 @@ def _collect_optional_update_fields(
483
476
  return result
484
477
 
485
478
 
486
- def _collect_relationship_fields(
487
- request: AgentUpdateRequest, current_agent: Any
488
- ) -> dict[str, Any]:
479
+ def _collect_relationship_fields(request: AgentUpdateRequest, current_agent: Any) -> dict[str, Any]:
480
+ """Return relationship identifiers (tools/agents/mcps) for an update request."""
489
481
  return {
490
482
  "tools": _resolve_relation_ids(request.tools, current_agent, "tools"),
491
483
  "agents": _resolve_relation_ids(request.agents, current_agent, "agents"),
@@ -493,9 +485,8 @@ def _collect_relationship_fields(
493
485
  }
494
486
 
495
487
 
496
- def _resolve_agent_config_update(
497
- request: AgentUpdateRequest, current_agent: Any
498
- ) -> dict[str, Any] | None:
488
+ def _resolve_agent_config_update(request: AgentUpdateRequest, current_agent: Any) -> dict[str, Any] | None:
489
+ """Determine the agent_config payload to send, if any."""
499
490
  effective_agent_config = _sanitize_agent_config(request.agent_config)
500
491
  if effective_agent_config is not None:
501
492
  return effective_agent_config
@@ -0,0 +1,43 @@
1
+ """Agent response payload types.
2
+
3
+ Authors:
4
+ Raymond Christopher (raymond.christopher@gdplabs.id)
5
+ """
6
+
7
+ # pylint: disable=duplicate-code
8
+ from __future__ import annotations
9
+
10
+ from dataclasses import dataclass, field
11
+ from typing import Any
12
+
13
+
14
+ @dataclass(slots=True)
15
+ class AgentListResult:
16
+ """Structured response for list_agents that retains pagination metadata."""
17
+
18
+ items: list[Any] = field(default_factory=list)
19
+ total: int | None = None
20
+ page: int | None = None
21
+ limit: int | None = None
22
+ has_next: bool | None = None
23
+ has_prev: bool | None = None
24
+ message: str | None = None
25
+
26
+ def __len__(self) -> int: # pragma: no cover - simple delegation
27
+ """Return the number of items in the result list."""
28
+ return len(self.items)
29
+
30
+ def __iter__(self): # pragma: no cover - simple delegation
31
+ """Return an iterator over the items in the result list."""
32
+ return iter(self.items)
33
+
34
+ def __getitem__(self, index: int) -> Any: # pragma: no cover - simple delegation
35
+ """Get an item from the result list by index.
36
+
37
+ Args:
38
+ index: Index of the item to retrieve.
39
+
40
+ Returns:
41
+ The item at the specified index.
42
+ """
43
+ return self.items[index]