glaip-sdk 0.6.12__py3-none-any.whl → 0.6.14__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.
- glaip_sdk/__init__.py +42 -5
- {glaip_sdk-0.6.12.dist-info → glaip_sdk-0.6.14.dist-info}/METADATA +31 -37
- glaip_sdk-0.6.14.dist-info/RECORD +12 -0
- {glaip_sdk-0.6.12.dist-info → glaip_sdk-0.6.14.dist-info}/WHEEL +2 -1
- glaip_sdk-0.6.14.dist-info/entry_points.txt +2 -0
- glaip_sdk-0.6.14.dist-info/top_level.txt +1 -0
- glaip_sdk/agents/__init__.py +0 -27
- glaip_sdk/agents/base.py +0 -1191
- glaip_sdk/cli/__init__.py +0 -9
- glaip_sdk/cli/account_store.py +0 -540
- glaip_sdk/cli/agent_config.py +0 -78
- glaip_sdk/cli/auth.py +0 -699
- glaip_sdk/cli/commands/__init__.py +0 -5
- glaip_sdk/cli/commands/accounts.py +0 -746
- glaip_sdk/cli/commands/agents.py +0 -1509
- glaip_sdk/cli/commands/common_config.py +0 -101
- glaip_sdk/cli/commands/configure.py +0 -896
- glaip_sdk/cli/commands/mcps.py +0 -1356
- glaip_sdk/cli/commands/models.py +0 -69
- glaip_sdk/cli/commands/tools.py +0 -576
- glaip_sdk/cli/commands/transcripts.py +0 -755
- glaip_sdk/cli/commands/update.py +0 -61
- glaip_sdk/cli/config.py +0 -95
- glaip_sdk/cli/constants.py +0 -38
- glaip_sdk/cli/context.py +0 -150
- glaip_sdk/cli/core/__init__.py +0 -79
- glaip_sdk/cli/core/context.py +0 -124
- glaip_sdk/cli/core/output.py +0 -846
- glaip_sdk/cli/core/prompting.py +0 -649
- glaip_sdk/cli/core/rendering.py +0 -187
- glaip_sdk/cli/display.py +0 -355
- glaip_sdk/cli/hints.py +0 -57
- glaip_sdk/cli/io.py +0 -112
- glaip_sdk/cli/main.py +0 -604
- glaip_sdk/cli/masking.py +0 -136
- glaip_sdk/cli/mcp_validators.py +0 -287
- glaip_sdk/cli/pager.py +0 -266
- glaip_sdk/cli/parsers/__init__.py +0 -7
- glaip_sdk/cli/parsers/json_input.py +0 -177
- glaip_sdk/cli/resolution.py +0 -67
- glaip_sdk/cli/rich_helpers.py +0 -27
- glaip_sdk/cli/slash/__init__.py +0 -15
- glaip_sdk/cli/slash/accounts_controller.py +0 -578
- glaip_sdk/cli/slash/accounts_shared.py +0 -75
- glaip_sdk/cli/slash/agent_session.py +0 -285
- glaip_sdk/cli/slash/prompt.py +0 -256
- glaip_sdk/cli/slash/remote_runs_controller.py +0 -566
- glaip_sdk/cli/slash/session.py +0 -1708
- glaip_sdk/cli/slash/tui/__init__.py +0 -9
- glaip_sdk/cli/slash/tui/accounts_app.py +0 -876
- glaip_sdk/cli/slash/tui/background_tasks.py +0 -72
- glaip_sdk/cli/slash/tui/loading.py +0 -58
- glaip_sdk/cli/slash/tui/remote_runs_app.py +0 -628
- glaip_sdk/cli/transcript/__init__.py +0 -31
- glaip_sdk/cli/transcript/cache.py +0 -536
- glaip_sdk/cli/transcript/capture.py +0 -329
- glaip_sdk/cli/transcript/export.py +0 -38
- glaip_sdk/cli/transcript/history.py +0 -815
- glaip_sdk/cli/transcript/launcher.py +0 -77
- glaip_sdk/cli/transcript/viewer.py +0 -374
- glaip_sdk/cli/update_notifier.py +0 -290
- glaip_sdk/cli/utils.py +0 -263
- glaip_sdk/cli/validators.py +0 -238
- glaip_sdk/client/__init__.py +0 -11
- glaip_sdk/client/_agent_payloads.py +0 -520
- glaip_sdk/client/agent_runs.py +0 -147
- glaip_sdk/client/agents.py +0 -1335
- glaip_sdk/client/base.py +0 -502
- glaip_sdk/client/main.py +0 -249
- glaip_sdk/client/mcps.py +0 -370
- glaip_sdk/client/run_rendering.py +0 -700
- glaip_sdk/client/shared.py +0 -21
- glaip_sdk/client/tools.py +0 -661
- glaip_sdk/client/validators.py +0 -198
- glaip_sdk/config/constants.py +0 -52
- glaip_sdk/mcps/__init__.py +0 -21
- glaip_sdk/mcps/base.py +0 -345
- glaip_sdk/models/__init__.py +0 -90
- glaip_sdk/models/agent.py +0 -47
- glaip_sdk/models/agent_runs.py +0 -116
- glaip_sdk/models/common.py +0 -42
- glaip_sdk/models/mcp.py +0 -33
- glaip_sdk/models/tool.py +0 -33
- glaip_sdk/payload_schemas/__init__.py +0 -7
- glaip_sdk/payload_schemas/agent.py +0 -85
- glaip_sdk/registry/__init__.py +0 -55
- glaip_sdk/registry/agent.py +0 -164
- glaip_sdk/registry/base.py +0 -139
- glaip_sdk/registry/mcp.py +0 -253
- glaip_sdk/registry/tool.py +0 -232
- glaip_sdk/runner/__init__.py +0 -59
- glaip_sdk/runner/base.py +0 -84
- glaip_sdk/runner/deps.py +0 -115
- glaip_sdk/runner/langgraph.py +0 -782
- glaip_sdk/runner/mcp_adapter/__init__.py +0 -13
- glaip_sdk/runner/mcp_adapter/base_mcp_adapter.py +0 -43
- glaip_sdk/runner/mcp_adapter/langchain_mcp_adapter.py +0 -257
- glaip_sdk/runner/mcp_adapter/mcp_config_builder.py +0 -95
- glaip_sdk/runner/tool_adapter/__init__.py +0 -18
- glaip_sdk/runner/tool_adapter/base_tool_adapter.py +0 -44
- glaip_sdk/runner/tool_adapter/langchain_tool_adapter.py +0 -219
- glaip_sdk/tools/__init__.py +0 -22
- glaip_sdk/tools/base.py +0 -435
- glaip_sdk/utils/__init__.py +0 -86
- glaip_sdk/utils/a2a/__init__.py +0 -34
- glaip_sdk/utils/a2a/event_processor.py +0 -188
- glaip_sdk/utils/agent_config.py +0 -194
- glaip_sdk/utils/bundler.py +0 -267
- glaip_sdk/utils/client.py +0 -111
- glaip_sdk/utils/client_utils.py +0 -486
- glaip_sdk/utils/datetime_helpers.py +0 -58
- glaip_sdk/utils/discovery.py +0 -78
- glaip_sdk/utils/display.py +0 -135
- glaip_sdk/utils/export.py +0 -143
- glaip_sdk/utils/general.py +0 -61
- glaip_sdk/utils/import_export.py +0 -168
- glaip_sdk/utils/import_resolver.py +0 -492
- glaip_sdk/utils/instructions.py +0 -101
- glaip_sdk/utils/rendering/__init__.py +0 -115
- glaip_sdk/utils/rendering/formatting.py +0 -264
- glaip_sdk/utils/rendering/layout/__init__.py +0 -64
- glaip_sdk/utils/rendering/layout/panels.py +0 -156
- glaip_sdk/utils/rendering/layout/progress.py +0 -202
- glaip_sdk/utils/rendering/layout/summary.py +0 -74
- glaip_sdk/utils/rendering/layout/transcript.py +0 -606
- glaip_sdk/utils/rendering/models.py +0 -85
- glaip_sdk/utils/rendering/renderer/__init__.py +0 -55
- glaip_sdk/utils/rendering/renderer/base.py +0 -1024
- glaip_sdk/utils/rendering/renderer/config.py +0 -27
- glaip_sdk/utils/rendering/renderer/console.py +0 -55
- glaip_sdk/utils/rendering/renderer/debug.py +0 -178
- glaip_sdk/utils/rendering/renderer/factory.py +0 -138
- glaip_sdk/utils/rendering/renderer/stream.py +0 -202
- glaip_sdk/utils/rendering/renderer/summary_window.py +0 -79
- glaip_sdk/utils/rendering/renderer/thinking.py +0 -273
- glaip_sdk/utils/rendering/renderer/toggle.py +0 -182
- glaip_sdk/utils/rendering/renderer/tool_panels.py +0 -442
- glaip_sdk/utils/rendering/renderer/transcript_mode.py +0 -162
- glaip_sdk/utils/rendering/state.py +0 -204
- glaip_sdk/utils/rendering/step_tree_state.py +0 -100
- glaip_sdk/utils/rendering/steps/__init__.py +0 -34
- glaip_sdk/utils/rendering/steps/event_processor.py +0 -778
- glaip_sdk/utils/rendering/steps/format.py +0 -176
- glaip_sdk/utils/rendering/steps/manager.py +0 -387
- glaip_sdk/utils/rendering/timing.py +0 -36
- glaip_sdk/utils/rendering/viewer/__init__.py +0 -21
- glaip_sdk/utils/rendering/viewer/presenter.py +0 -184
- glaip_sdk/utils/resource_refs.py +0 -195
- glaip_sdk/utils/run_renderer.py +0 -41
- glaip_sdk/utils/runtime_config.py +0 -425
- glaip_sdk/utils/serialization.py +0 -424
- glaip_sdk/utils/sync.py +0 -142
- glaip_sdk/utils/tool_detection.py +0 -33
- glaip_sdk/utils/validation.py +0 -264
- glaip_sdk-0.6.12.dist-info/RECORD +0 -159
- glaip_sdk-0.6.12.dist-info/entry_points.txt +0 -3
|
@@ -1,520 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""Shared helpers for Agent client payload construction and query handling."""
|
|
3
|
-
|
|
4
|
-
from __future__ import annotations
|
|
5
|
-
|
|
6
|
-
from collections.abc import Callable, Mapping, MutableMapping, Sequence
|
|
7
|
-
from copy import deepcopy
|
|
8
|
-
from dataclasses import dataclass, field
|
|
9
|
-
from typing import Any
|
|
10
|
-
|
|
11
|
-
from glaip_sdk.config.constants import (
|
|
12
|
-
DEFAULT_AGENT_FRAMEWORK,
|
|
13
|
-
DEFAULT_AGENT_PROVIDER,
|
|
14
|
-
DEFAULT_AGENT_TYPE,
|
|
15
|
-
DEFAULT_AGENT_VERSION,
|
|
16
|
-
DEFAULT_MODEL,
|
|
17
|
-
)
|
|
18
|
-
from glaip_sdk.payload_schemas.agent import AgentImportOperation, get_import_field_plan
|
|
19
|
-
from glaip_sdk.utils.client_utils import extract_ids
|
|
20
|
-
|
|
21
|
-
_LM_CONFLICT_KEYS = {
|
|
22
|
-
"lm_provider",
|
|
23
|
-
"lm_name",
|
|
24
|
-
"lm_base_url",
|
|
25
|
-
"lm_hyperparameters",
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
def _copy_structure(value: Any) -> Any:
|
|
30
|
-
"""Return a defensive copy for mutable payload structures."""
|
|
31
|
-
if isinstance(value, (dict, list, tuple)):
|
|
32
|
-
return deepcopy(value)
|
|
33
|
-
return value
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
def _sanitize_agent_config(
|
|
37
|
-
agent_config: Mapping[str, Any] | None,
|
|
38
|
-
) -> dict[str, Any] | None:
|
|
39
|
-
"""Remove legacy LM keys that conflict with modern language model fields."""
|
|
40
|
-
if agent_config is None:
|
|
41
|
-
return None
|
|
42
|
-
|
|
43
|
-
sanitized = deepcopy(agent_config)
|
|
44
|
-
for key in _LM_CONFLICT_KEYS:
|
|
45
|
-
sanitized.pop(key, None)
|
|
46
|
-
return sanitized
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
def _merge_execution_timeout(
|
|
50
|
-
agent_config: dict[str, Any] | None,
|
|
51
|
-
timeout: int | None,
|
|
52
|
-
) -> dict[str, Any] | None:
|
|
53
|
-
"""Merge execution timeout into agent_config if provided."""
|
|
54
|
-
if timeout is None:
|
|
55
|
-
return agent_config
|
|
56
|
-
|
|
57
|
-
merged = agent_config or {}
|
|
58
|
-
merged.setdefault("execution_timeout", timeout)
|
|
59
|
-
return merged
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
def merge_payload_fields(
|
|
63
|
-
payload: MutableMapping[str, Any],
|
|
64
|
-
extra_fields: Mapping[str, Any] | None,
|
|
65
|
-
operation: AgentImportOperation,
|
|
66
|
-
) -> None:
|
|
67
|
-
"""Merge additional fields into payload respecting schema hints."""
|
|
68
|
-
if not extra_fields:
|
|
69
|
-
return
|
|
70
|
-
|
|
71
|
-
for key, value in extra_fields.items():
|
|
72
|
-
plan = get_import_field_plan(key, operation)
|
|
73
|
-
if not plan.copy or value is None:
|
|
74
|
-
continue
|
|
75
|
-
|
|
76
|
-
copied_value = _copy_structure(value)
|
|
77
|
-
if plan.sanitize and isinstance(copied_value, dict):
|
|
78
|
-
copied_value = _sanitize_agent_config(copied_value)
|
|
79
|
-
|
|
80
|
-
payload[key] = copied_value
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
def resolve_language_model_fields(
|
|
84
|
-
*,
|
|
85
|
-
model: str | None,
|
|
86
|
-
language_model_id: str | None,
|
|
87
|
-
provider: str | None,
|
|
88
|
-
model_name: str | None,
|
|
89
|
-
default_provider: str = DEFAULT_AGENT_PROVIDER,
|
|
90
|
-
default_model: str = DEFAULT_MODEL,
|
|
91
|
-
) -> dict[str, Any]:
|
|
92
|
-
"""Resolve mutually exclusive language model specification fields."""
|
|
93
|
-
if language_model_id:
|
|
94
|
-
return {"language_model_id": language_model_id}
|
|
95
|
-
|
|
96
|
-
resolved_model = model_name or model or default_model
|
|
97
|
-
resolved_provider = provider if provider is not None else default_provider
|
|
98
|
-
|
|
99
|
-
result: dict[str, Any] = {}
|
|
100
|
-
if resolved_model is not None:
|
|
101
|
-
result["model_name"] = resolved_model
|
|
102
|
-
if resolved_provider:
|
|
103
|
-
result["provider"] = resolved_provider
|
|
104
|
-
return result
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
def _extract_ids_or_empty(items: Sequence[str | Any] | None) -> list[str]:
|
|
108
|
-
"""Extract IDs, returning an empty list when no IDs are present."""
|
|
109
|
-
if items is None:
|
|
110
|
-
return []
|
|
111
|
-
|
|
112
|
-
try:
|
|
113
|
-
iterable = list(items)
|
|
114
|
-
except TypeError:
|
|
115
|
-
return []
|
|
116
|
-
|
|
117
|
-
extracted = extract_ids(iterable)
|
|
118
|
-
return extracted or []
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
def _extract_existing_ids(source: Any, attribute: str) -> list[str]:
|
|
122
|
-
"""Extract IDs from an attribute on the current agent instance."""
|
|
123
|
-
if source is None:
|
|
124
|
-
return []
|
|
125
|
-
value = getattr(source, attribute, None)
|
|
126
|
-
if not value:
|
|
127
|
-
return []
|
|
128
|
-
return _extract_ids_or_empty(value)
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
def _resolve_relation_ids(
|
|
132
|
-
new_items: Sequence[str | Any] | None,
|
|
133
|
-
current_agent: Any,
|
|
134
|
-
attribute: str,
|
|
135
|
-
) -> list[str]:
|
|
136
|
-
"""Resolve relationship IDs favouring explicit values when provided."""
|
|
137
|
-
if new_items is not None:
|
|
138
|
-
return _extract_ids_or_empty(new_items)
|
|
139
|
-
return _extract_existing_ids(current_agent, attribute)
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
def _pick_optional(
|
|
143
|
-
new_value: Any,
|
|
144
|
-
fallback: Any,
|
|
145
|
-
*,
|
|
146
|
-
transform: Callable[[Any], Any] | None = None,
|
|
147
|
-
) -> Any | None:
|
|
148
|
-
"""Return new_value when present, otherwise fallback, applying transform."""
|
|
149
|
-
value = new_value if new_value is not None else fallback
|
|
150
|
-
if value is None:
|
|
151
|
-
return None
|
|
152
|
-
return transform(value) if transform else value
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
def _existing_language_model_fields(current_agent: Any) -> dict[str, Any]:
|
|
156
|
-
"""Derive language model fields from the current agent or defaults."""
|
|
157
|
-
result: dict[str, Any] = {}
|
|
158
|
-
|
|
159
|
-
language_model_id = getattr(current_agent, "language_model_id", None)
|
|
160
|
-
if language_model_id:
|
|
161
|
-
result["language_model_id"] = language_model_id
|
|
162
|
-
return result
|
|
163
|
-
|
|
164
|
-
agent_config = getattr(current_agent, "agent_config", None)
|
|
165
|
-
if isinstance(agent_config, Mapping):
|
|
166
|
-
provider = agent_config.get("lm_provider")
|
|
167
|
-
model_name = agent_config.get("lm_name")
|
|
168
|
-
if provider:
|
|
169
|
-
result["provider"] = provider
|
|
170
|
-
if model_name:
|
|
171
|
-
result["model_name"] = model_name
|
|
172
|
-
|
|
173
|
-
if not result:
|
|
174
|
-
if DEFAULT_AGENT_PROVIDER:
|
|
175
|
-
result["provider"] = DEFAULT_AGENT_PROVIDER
|
|
176
|
-
result["model_name"] = DEFAULT_MODEL
|
|
177
|
-
|
|
178
|
-
return result
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
@dataclass(slots=True)
|
|
182
|
-
class AgentListParams:
|
|
183
|
-
"""Structured query parameters for listing agents."""
|
|
184
|
-
|
|
185
|
-
agent_type: str | None = None
|
|
186
|
-
framework: str | None = None
|
|
187
|
-
name: str | None = None
|
|
188
|
-
version: str | None = None
|
|
189
|
-
limit: int | None = None
|
|
190
|
-
page: int | None = None
|
|
191
|
-
include_deleted: bool | None = None
|
|
192
|
-
created_at_start: str | None = None
|
|
193
|
-
created_at_end: str | None = None
|
|
194
|
-
updated_at_start: str | None = None
|
|
195
|
-
updated_at_end: str | None = None
|
|
196
|
-
sync_langflow_agents: bool | None = None
|
|
197
|
-
metadata: Mapping[str, str] | None = None
|
|
198
|
-
|
|
199
|
-
def to_query_params(self) -> dict[str, Any]:
|
|
200
|
-
"""Convert the dataclass to API-ready query params."""
|
|
201
|
-
params = self._base_filter_params()
|
|
202
|
-
self._apply_pagination_params(params)
|
|
203
|
-
self._apply_timestamp_filters(params)
|
|
204
|
-
self._apply_metadata_filters(params)
|
|
205
|
-
|
|
206
|
-
return params
|
|
207
|
-
|
|
208
|
-
def _base_filter_params(self) -> dict[str, Any]:
|
|
209
|
-
"""Build base filter parameters from non-None fields.
|
|
210
|
-
|
|
211
|
-
Returns:
|
|
212
|
-
Dictionary of filter parameters with non-None values.
|
|
213
|
-
"""
|
|
214
|
-
return {
|
|
215
|
-
key: value
|
|
216
|
-
for key, value in (
|
|
217
|
-
("agent_type", self.agent_type),
|
|
218
|
-
("framework", self.framework),
|
|
219
|
-
("name", self.name),
|
|
220
|
-
("version", self.version),
|
|
221
|
-
)
|
|
222
|
-
if value is not None
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
def _apply_pagination_params(self, params: dict[str, Any]) -> None:
|
|
226
|
-
"""Apply pagination parameters to the params dictionary.
|
|
227
|
-
|
|
228
|
-
Args:
|
|
229
|
-
params: Dictionary to update with pagination parameters.
|
|
230
|
-
"""
|
|
231
|
-
if self.limit is not None:
|
|
232
|
-
if not 1 <= self.limit <= 100:
|
|
233
|
-
raise ValueError("limit must be between 1 and 100 inclusive")
|
|
234
|
-
params["limit"] = self.limit
|
|
235
|
-
|
|
236
|
-
if self.page is not None:
|
|
237
|
-
if self.page < 1:
|
|
238
|
-
raise ValueError("page must be >= 1")
|
|
239
|
-
params["page"] = self.page
|
|
240
|
-
|
|
241
|
-
if self.include_deleted is not None:
|
|
242
|
-
params["include_deleted"] = str(self.include_deleted).lower()
|
|
243
|
-
|
|
244
|
-
if self.sync_langflow_agents is not None:
|
|
245
|
-
params["sync_langflow_agents"] = str(self.sync_langflow_agents).lower()
|
|
246
|
-
|
|
247
|
-
def _apply_timestamp_filters(self, params: dict[str, Any]) -> None:
|
|
248
|
-
"""Apply timestamp filter parameters to the params dictionary.
|
|
249
|
-
|
|
250
|
-
Args:
|
|
251
|
-
params: Dictionary to update with timestamp filter parameters.
|
|
252
|
-
"""
|
|
253
|
-
timestamp_filters = {
|
|
254
|
-
"created_at_start": self.created_at_start,
|
|
255
|
-
"created_at_end": self.created_at_end,
|
|
256
|
-
"updated_at_start": self.updated_at_start,
|
|
257
|
-
"updated_at_end": self.updated_at_end,
|
|
258
|
-
}
|
|
259
|
-
for key, value in timestamp_filters.items():
|
|
260
|
-
if value is not None:
|
|
261
|
-
params[key] = value
|
|
262
|
-
|
|
263
|
-
def _apply_metadata_filters(self, params: dict[str, Any]) -> None:
|
|
264
|
-
"""Apply metadata filter parameters to the params dictionary.
|
|
265
|
-
|
|
266
|
-
Args:
|
|
267
|
-
params: Dictionary to update with metadata filter parameters.
|
|
268
|
-
"""
|
|
269
|
-
if not self.metadata:
|
|
270
|
-
return
|
|
271
|
-
for key, value in self.metadata.items():
|
|
272
|
-
if value is not None:
|
|
273
|
-
params[f"metadata.{key}"] = value
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
@dataclass(slots=True)
|
|
277
|
-
class AgentListResult:
|
|
278
|
-
"""Structured response for list_agents that retains pagination metadata."""
|
|
279
|
-
|
|
280
|
-
items: list[Any] = field(default_factory=list)
|
|
281
|
-
total: int | None = None
|
|
282
|
-
page: int | None = None
|
|
283
|
-
limit: int | None = None
|
|
284
|
-
has_next: bool | None = None
|
|
285
|
-
has_prev: bool | None = None
|
|
286
|
-
message: str | None = None
|
|
287
|
-
|
|
288
|
-
def __len__(self) -> int: # pragma: no cover - simple delegation
|
|
289
|
-
"""Return the number of items in the result list."""
|
|
290
|
-
return len(self.items)
|
|
291
|
-
|
|
292
|
-
def __iter__(self): # pragma: no cover - simple delegation
|
|
293
|
-
"""Return an iterator over the items in the result list."""
|
|
294
|
-
return iter(self.items)
|
|
295
|
-
|
|
296
|
-
def __getitem__(self, index: int) -> Any: # pragma: no cover - simple delegation
|
|
297
|
-
"""Get an item from the result list by index.
|
|
298
|
-
|
|
299
|
-
Args:
|
|
300
|
-
index: Index of the item to retrieve.
|
|
301
|
-
|
|
302
|
-
Returns:
|
|
303
|
-
The item at the specified index.
|
|
304
|
-
"""
|
|
305
|
-
return self.items[index]
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
@dataclass(slots=True)
|
|
309
|
-
class AgentCreateRequest:
|
|
310
|
-
"""Declarative representation of an agent creation payload."""
|
|
311
|
-
|
|
312
|
-
name: str
|
|
313
|
-
instruction: str
|
|
314
|
-
model: str | None = DEFAULT_MODEL
|
|
315
|
-
language_model_id: str | None = None
|
|
316
|
-
provider: str | None = None
|
|
317
|
-
model_name: str | None = None
|
|
318
|
-
agent_type: str = DEFAULT_AGENT_TYPE
|
|
319
|
-
framework: str = DEFAULT_AGENT_FRAMEWORK
|
|
320
|
-
version: str = DEFAULT_AGENT_VERSION
|
|
321
|
-
account_id: str | None = None
|
|
322
|
-
description: str | None = None
|
|
323
|
-
metadata: Mapping[str, Any] | None = None
|
|
324
|
-
tools: Sequence[str | Any] | None = None
|
|
325
|
-
tool_configs: Mapping[str, Any] | None = None
|
|
326
|
-
agents: Sequence[str | Any] | None = None
|
|
327
|
-
mcps: Sequence[str | Any] | None = None
|
|
328
|
-
agent_config: Mapping[str, Any] | None = None
|
|
329
|
-
timeout: int | None = None
|
|
330
|
-
a2a_profile: Mapping[str, Any] | None = None
|
|
331
|
-
extras: Mapping[str, Any] | None = None
|
|
332
|
-
|
|
333
|
-
def to_payload(self) -> dict[str, Any]:
|
|
334
|
-
"""Materialise the request as a dict suitable for API submission."""
|
|
335
|
-
payload: dict[str, Any] = {
|
|
336
|
-
"name": self.name.strip(),
|
|
337
|
-
"instruction": self.instruction.strip(),
|
|
338
|
-
"type": self.agent_type,
|
|
339
|
-
"framework": self.framework,
|
|
340
|
-
"version": self.version,
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
payload.update(
|
|
344
|
-
resolve_language_model_fields(
|
|
345
|
-
model=self.model,
|
|
346
|
-
language_model_id=self.language_model_id,
|
|
347
|
-
provider=self.provider,
|
|
348
|
-
model_name=self.model_name,
|
|
349
|
-
)
|
|
350
|
-
)
|
|
351
|
-
|
|
352
|
-
if self.account_id is not None:
|
|
353
|
-
payload["account_id"] = self.account_id
|
|
354
|
-
if self.description is not None:
|
|
355
|
-
payload["description"] = self.description
|
|
356
|
-
if self.metadata is not None:
|
|
357
|
-
payload["metadata"] = _copy_structure(self.metadata)
|
|
358
|
-
|
|
359
|
-
if self.a2a_profile is not None:
|
|
360
|
-
payload["a2a_profile"] = _copy_structure(self.a2a_profile)
|
|
361
|
-
|
|
362
|
-
tool_ids = extract_ids(list(self.tools) if self.tools is not None else None)
|
|
363
|
-
if tool_ids:
|
|
364
|
-
payload["tools"] = tool_ids
|
|
365
|
-
|
|
366
|
-
agent_ids = extract_ids(list(self.agents) if self.agents is not None else None)
|
|
367
|
-
if agent_ids:
|
|
368
|
-
payload["agents"] = agent_ids
|
|
369
|
-
|
|
370
|
-
mcp_ids = extract_ids(list(self.mcps) if self.mcps is not None else None)
|
|
371
|
-
if mcp_ids:
|
|
372
|
-
payload["mcps"] = mcp_ids
|
|
373
|
-
|
|
374
|
-
if self.tool_configs is not None:
|
|
375
|
-
payload["tool_configs"] = _copy_structure(self.tool_configs)
|
|
376
|
-
|
|
377
|
-
effective_agent_config = _sanitize_agent_config(self.agent_config)
|
|
378
|
-
effective_agent_config = _merge_execution_timeout(effective_agent_config, self.timeout)
|
|
379
|
-
if effective_agent_config:
|
|
380
|
-
payload["agent_config"] = effective_agent_config
|
|
381
|
-
|
|
382
|
-
merge_payload_fields(payload, self.extras, "create")
|
|
383
|
-
return payload
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
@dataclass(slots=True)
|
|
387
|
-
class AgentUpdateRequest:
|
|
388
|
-
"""Declarative representation of an agent update payload."""
|
|
389
|
-
|
|
390
|
-
name: str | None = None
|
|
391
|
-
instruction: str | None = None
|
|
392
|
-
description: str | None = None
|
|
393
|
-
model: str | None = None
|
|
394
|
-
language_model_id: str | None = None
|
|
395
|
-
provider: str | None = None
|
|
396
|
-
model_name: str | None = None
|
|
397
|
-
agent_type: str | None = None
|
|
398
|
-
framework: str | None = None
|
|
399
|
-
version: str | None = None
|
|
400
|
-
account_id: str | None = None
|
|
401
|
-
metadata: Mapping[str, Any] | None = None
|
|
402
|
-
tools: Sequence[str | Any] | None = None
|
|
403
|
-
tool_configs: Mapping[str, Any] | None = None
|
|
404
|
-
agents: Sequence[str | Any] | None = None
|
|
405
|
-
mcps: Sequence[str | Any] | None = None
|
|
406
|
-
agent_config: Mapping[str, Any] | None = None
|
|
407
|
-
a2a_profile: Mapping[str, Any] | None = None
|
|
408
|
-
extras: Mapping[str, Any] | None = None
|
|
409
|
-
|
|
410
|
-
def to_payload(self, current_agent: Any) -> dict[str, Any]:
|
|
411
|
-
"""Materialise the request using current agent data as fallbacks."""
|
|
412
|
-
payload = _build_base_update_payload(self, current_agent)
|
|
413
|
-
payload.update(_resolve_update_language_model_fields(self, current_agent))
|
|
414
|
-
payload.update(_collect_optional_update_fields(self, current_agent))
|
|
415
|
-
payload.update(_collect_relationship_fields(self, current_agent))
|
|
416
|
-
|
|
417
|
-
agent_config_value = _resolve_agent_config_update(self, current_agent)
|
|
418
|
-
if agent_config_value is not None:
|
|
419
|
-
payload["agent_config"] = agent_config_value
|
|
420
|
-
|
|
421
|
-
merge_payload_fields(payload, self.extras, "update")
|
|
422
|
-
return payload
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
__all__ = [
|
|
426
|
-
"AgentCreateRequest",
|
|
427
|
-
"AgentListParams",
|
|
428
|
-
"AgentListResult",
|
|
429
|
-
"AgentUpdateRequest",
|
|
430
|
-
"merge_payload_fields",
|
|
431
|
-
"resolve_language_model_fields",
|
|
432
|
-
]
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
def _build_base_update_payload(request: AgentUpdateRequest, current_agent: Any) -> dict[str, Any]:
|
|
436
|
-
"""Populate immutable agent update fields using request data or existing agent defaults."""
|
|
437
|
-
# Support both "agent_type" (runtime class) and "type" (API response) attributes
|
|
438
|
-
current_type = getattr(current_agent, "agent_type", None) or getattr(current_agent, "type", None)
|
|
439
|
-
return {
|
|
440
|
-
"name": (request.name.strip() if request.name is not None else getattr(current_agent, "name", None)),
|
|
441
|
-
"instruction": (
|
|
442
|
-
request.instruction.strip()
|
|
443
|
-
if request.instruction is not None
|
|
444
|
-
else getattr(current_agent, "instruction", None)
|
|
445
|
-
),
|
|
446
|
-
"type": request.agent_type or current_type or DEFAULT_AGENT_TYPE,
|
|
447
|
-
"framework": request.framework or getattr(current_agent, "framework", None) or DEFAULT_AGENT_FRAMEWORK,
|
|
448
|
-
"version": request.version or getattr(current_agent, "version", None) or DEFAULT_AGENT_VERSION,
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
def _resolve_update_language_model_fields(request: AgentUpdateRequest, current_agent: Any) -> dict[str, Any]:
|
|
453
|
-
"""Resolve the language-model portion of an update request with sensible fallbacks."""
|
|
454
|
-
fields = resolve_language_model_fields(
|
|
455
|
-
model=request.model,
|
|
456
|
-
language_model_id=request.language_model_id,
|
|
457
|
-
provider=request.provider,
|
|
458
|
-
model_name=request.model_name,
|
|
459
|
-
)
|
|
460
|
-
if not fields:
|
|
461
|
-
fields = _existing_language_model_fields(current_agent)
|
|
462
|
-
return fields
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
def _collect_optional_update_fields(request: AgentUpdateRequest, current_agent: Any) -> dict[str, Any]:
|
|
466
|
-
"""Collect optional agent fields, preserving current values when updates are absent."""
|
|
467
|
-
result: dict[str, Any] = {}
|
|
468
|
-
|
|
469
|
-
for field_name, value in (
|
|
470
|
-
("account_id", request.account_id),
|
|
471
|
-
("description", request.description),
|
|
472
|
-
):
|
|
473
|
-
resolved_value = _pick_optional(value, getattr(current_agent, field_name, None))
|
|
474
|
-
if resolved_value is not None:
|
|
475
|
-
result[field_name] = resolved_value
|
|
476
|
-
|
|
477
|
-
metadata_value = _pick_optional(
|
|
478
|
-
request.metadata,
|
|
479
|
-
getattr(current_agent, "metadata", None),
|
|
480
|
-
transform=_copy_structure,
|
|
481
|
-
)
|
|
482
|
-
if metadata_value is not None:
|
|
483
|
-
result["metadata"] = metadata_value
|
|
484
|
-
|
|
485
|
-
profile_value = _pick_optional(
|
|
486
|
-
request.a2a_profile,
|
|
487
|
-
getattr(current_agent, "a2a_profile", None),
|
|
488
|
-
transform=_copy_structure,
|
|
489
|
-
)
|
|
490
|
-
if profile_value is not None:
|
|
491
|
-
result["a2a_profile"] = profile_value
|
|
492
|
-
|
|
493
|
-
tool_configs_value = _pick_optional(
|
|
494
|
-
request.tool_configs,
|
|
495
|
-
getattr(current_agent, "tool_configs", None),
|
|
496
|
-
transform=_copy_structure,
|
|
497
|
-
)
|
|
498
|
-
if tool_configs_value is not None:
|
|
499
|
-
result["tool_configs"] = tool_configs_value
|
|
500
|
-
|
|
501
|
-
return result
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
def _collect_relationship_fields(request: AgentUpdateRequest, current_agent: Any) -> dict[str, Any]:
|
|
505
|
-
"""Return relationship identifiers (tools/agents/mcps) for an update request."""
|
|
506
|
-
return {
|
|
507
|
-
"tools": _resolve_relation_ids(request.tools, current_agent, "tools"),
|
|
508
|
-
"agents": _resolve_relation_ids(request.agents, current_agent, "agents"),
|
|
509
|
-
"mcps": _resolve_relation_ids(request.mcps, current_agent, "mcps"),
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
def _resolve_agent_config_update(request: AgentUpdateRequest, current_agent: Any) -> dict[str, Any] | None:
|
|
514
|
-
"""Determine the agent_config payload to send, if any."""
|
|
515
|
-
effective_agent_config = _sanitize_agent_config(request.agent_config)
|
|
516
|
-
if effective_agent_config is not None:
|
|
517
|
-
return effective_agent_config
|
|
518
|
-
if getattr(current_agent, "agent_config", None):
|
|
519
|
-
return _sanitize_agent_config(current_agent.agent_config)
|
|
520
|
-
return None
|
glaip_sdk/client/agent_runs.py
DELETED
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""Agent runs client for AIP SDK.
|
|
3
|
-
|
|
4
|
-
Authors:
|
|
5
|
-
Raymond Christopher (raymond.christopher@gdplabs.id)
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
from typing import Any
|
|
9
|
-
|
|
10
|
-
import httpx
|
|
11
|
-
|
|
12
|
-
from glaip_sdk.client.base import BaseClient
|
|
13
|
-
from glaip_sdk.exceptions import TimeoutError, ValidationError
|
|
14
|
-
from glaip_sdk.models.agent_runs import RunSummary, RunsPage, RunWithOutput
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class AgentRunsClient(BaseClient):
|
|
18
|
-
"""Client for agent run operations."""
|
|
19
|
-
|
|
20
|
-
def list_runs(
|
|
21
|
-
self,
|
|
22
|
-
agent_id: str,
|
|
23
|
-
*,
|
|
24
|
-
limit: int = 20,
|
|
25
|
-
page: int = 1,
|
|
26
|
-
) -> RunsPage:
|
|
27
|
-
"""List agent runs with pagination.
|
|
28
|
-
|
|
29
|
-
Args:
|
|
30
|
-
agent_id: UUID of the agent
|
|
31
|
-
limit: Number of runs per page (1-100, default 20)
|
|
32
|
-
page: Page number (1-based, default 1)
|
|
33
|
-
|
|
34
|
-
Returns:
|
|
35
|
-
RunsPage containing paginated run summaries
|
|
36
|
-
|
|
37
|
-
Raises:
|
|
38
|
-
ValidationError: If pagination parameters are invalid
|
|
39
|
-
NotFoundError: If agent is not found
|
|
40
|
-
AuthenticationError: If authentication fails
|
|
41
|
-
TimeoutError: If request times out (30s default)
|
|
42
|
-
"""
|
|
43
|
-
self._validate_pagination_params(limit, page)
|
|
44
|
-
envelope = self._fetch_runs_envelope(agent_id, limit, page)
|
|
45
|
-
normalized_data = self._normalize_runs_payload(envelope.get("data"))
|
|
46
|
-
runs = [RunSummary(**item) for item in normalized_data]
|
|
47
|
-
return self._build_runs_page(envelope, runs, limit, page)
|
|
48
|
-
|
|
49
|
-
def _fetch_runs_envelope(self, agent_id: str, limit: int, page: int) -> dict[str, Any]:
|
|
50
|
-
params = {"limit": limit, "page": page}
|
|
51
|
-
try:
|
|
52
|
-
envelope = self._request_with_envelope(
|
|
53
|
-
"GET",
|
|
54
|
-
f"/agents/{agent_id}/runs",
|
|
55
|
-
params=params,
|
|
56
|
-
)
|
|
57
|
-
except httpx.TimeoutException as e:
|
|
58
|
-
raise TimeoutError(f"Request timed out after {self._timeout}s while fetching agent runs") from e
|
|
59
|
-
|
|
60
|
-
if isinstance(envelope, dict):
|
|
61
|
-
return envelope
|
|
62
|
-
return {"data": envelope}
|
|
63
|
-
|
|
64
|
-
@staticmethod
|
|
65
|
-
def _validate_pagination_params(limit: int, page: int) -> None:
|
|
66
|
-
if limit < 1 or limit > 100:
|
|
67
|
-
raise ValidationError("limit must be between 1 and 100")
|
|
68
|
-
if page < 1:
|
|
69
|
-
raise ValidationError("page must be >= 1")
|
|
70
|
-
|
|
71
|
-
@staticmethod
|
|
72
|
-
def _normalize_runs_payload(data_payload: Any) -> list[Any]:
|
|
73
|
-
if not data_payload:
|
|
74
|
-
return []
|
|
75
|
-
normalized_data: list[Any] = []
|
|
76
|
-
for item in data_payload:
|
|
77
|
-
normalized_data.append(AgentRunsClient._normalize_run_item(item))
|
|
78
|
-
return normalized_data
|
|
79
|
-
|
|
80
|
-
@staticmethod
|
|
81
|
-
def _normalize_run_item(item: Any) -> Any:
|
|
82
|
-
if isinstance(item, dict):
|
|
83
|
-
if item.get("config") is None:
|
|
84
|
-
item["config"] = {}
|
|
85
|
-
schedule_id = item.get("schedule_id")
|
|
86
|
-
if schedule_id == "None" or schedule_id == "":
|
|
87
|
-
item["schedule_id"] = None
|
|
88
|
-
return item
|
|
89
|
-
|
|
90
|
-
@staticmethod
|
|
91
|
-
def _build_runs_page(
|
|
92
|
-
envelope: dict[str, Any],
|
|
93
|
-
runs: list[RunSummary],
|
|
94
|
-
limit: int,
|
|
95
|
-
page: int,
|
|
96
|
-
) -> RunsPage:
|
|
97
|
-
return RunsPage(
|
|
98
|
-
data=runs,
|
|
99
|
-
total=envelope.get("total", 0),
|
|
100
|
-
page=envelope.get("page", page),
|
|
101
|
-
limit=envelope.get("limit", limit),
|
|
102
|
-
has_next=envelope.get("has_next", False),
|
|
103
|
-
has_prev=envelope.get("has_prev", False),
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
def get_run(
|
|
107
|
-
self,
|
|
108
|
-
agent_id: str,
|
|
109
|
-
run_id: str,
|
|
110
|
-
) -> RunWithOutput:
|
|
111
|
-
"""Get detailed run information including SSE event stream.
|
|
112
|
-
|
|
113
|
-
Args:
|
|
114
|
-
agent_id: UUID of the agent
|
|
115
|
-
run_id: UUID of the run
|
|
116
|
-
|
|
117
|
-
Returns:
|
|
118
|
-
RunWithOutput containing complete run details and event stream
|
|
119
|
-
|
|
120
|
-
Raises:
|
|
121
|
-
NotFoundError: If run or agent is not found
|
|
122
|
-
AuthenticationError: If authentication fails
|
|
123
|
-
TimeoutError: If request times out (30s default)
|
|
124
|
-
"""
|
|
125
|
-
try:
|
|
126
|
-
envelope = self._request_with_envelope(
|
|
127
|
-
"GET",
|
|
128
|
-
f"/agents/{agent_id}/runs/{run_id}",
|
|
129
|
-
)
|
|
130
|
-
except httpx.TimeoutException as e:
|
|
131
|
-
raise TimeoutError(f"Request timed out after {self._timeout}s while fetching run detail") from e
|
|
132
|
-
|
|
133
|
-
if not isinstance(envelope, dict):
|
|
134
|
-
envelope = {"data": envelope}
|
|
135
|
-
|
|
136
|
-
data = envelope.get("data") or {}
|
|
137
|
-
# Normalize config, output, and schedule_id fields
|
|
138
|
-
if data.get("config") is None:
|
|
139
|
-
data["config"] = {}
|
|
140
|
-
if data.get("output") is None:
|
|
141
|
-
data["output"] = []
|
|
142
|
-
# Normalize schedule_id: convert string "None" to None
|
|
143
|
-
schedule_id = data.get("schedule_id")
|
|
144
|
-
if schedule_id == "None" or schedule_id == "":
|
|
145
|
-
data["schedule_id"] = None
|
|
146
|
-
|
|
147
|
-
return RunWithOutput(**data)
|