glaip-sdk 0.6.5b6__py3-none-any.whl → 0.7.12__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/agents/base.py +217 -42
- glaip_sdk/branding.py +113 -2
- glaip_sdk/cli/account_store.py +15 -0
- glaip_sdk/cli/auth.py +14 -8
- glaip_sdk/cli/commands/accounts.py +1 -1
- glaip_sdk/cli/commands/agents/__init__.py +119 -0
- glaip_sdk/cli/commands/agents/_common.py +561 -0
- glaip_sdk/cli/commands/agents/create.py +151 -0
- glaip_sdk/cli/commands/agents/delete.py +64 -0
- glaip_sdk/cli/commands/agents/get.py +89 -0
- glaip_sdk/cli/commands/agents/list.py +129 -0
- glaip_sdk/cli/commands/agents/run.py +264 -0
- glaip_sdk/cli/commands/agents/sync_langflow.py +72 -0
- glaip_sdk/cli/commands/agents/update.py +112 -0
- glaip_sdk/cli/commands/common_config.py +15 -12
- glaip_sdk/cli/commands/configure.py +2 -3
- glaip_sdk/cli/commands/mcps/__init__.py +94 -0
- glaip_sdk/cli/commands/mcps/_common.py +459 -0
- glaip_sdk/cli/commands/mcps/connect.py +82 -0
- glaip_sdk/cli/commands/mcps/create.py +152 -0
- glaip_sdk/cli/commands/mcps/delete.py +73 -0
- glaip_sdk/cli/commands/mcps/get.py +212 -0
- glaip_sdk/cli/commands/mcps/list.py +69 -0
- glaip_sdk/cli/commands/mcps/tools.py +235 -0
- glaip_sdk/cli/commands/mcps/update.py +190 -0
- glaip_sdk/cli/commands/models.py +2 -4
- glaip_sdk/cli/commands/shared/__init__.py +21 -0
- glaip_sdk/cli/commands/shared/formatters.py +91 -0
- glaip_sdk/cli/commands/tools/__init__.py +69 -0
- glaip_sdk/cli/commands/tools/_common.py +80 -0
- glaip_sdk/cli/commands/tools/create.py +228 -0
- glaip_sdk/cli/commands/tools/delete.py +61 -0
- glaip_sdk/cli/commands/tools/get.py +103 -0
- glaip_sdk/cli/commands/tools/list.py +69 -0
- glaip_sdk/cli/commands/tools/script.py +49 -0
- glaip_sdk/cli/commands/tools/update.py +102 -0
- glaip_sdk/cli/commands/transcripts/__init__.py +90 -0
- glaip_sdk/cli/commands/transcripts/_common.py +9 -0
- glaip_sdk/cli/commands/transcripts/clear.py +5 -0
- glaip_sdk/cli/commands/transcripts/detail.py +5 -0
- glaip_sdk/cli/commands/{transcripts.py → transcripts_original.py} +2 -1
- glaip_sdk/cli/commands/update.py +163 -17
- glaip_sdk/cli/config.py +1 -0
- glaip_sdk/cli/core/output.py +12 -7
- glaip_sdk/cli/entrypoint.py +20 -0
- glaip_sdk/cli/main.py +127 -39
- glaip_sdk/cli/pager.py +3 -3
- glaip_sdk/cli/resolution.py +2 -1
- glaip_sdk/cli/slash/accounts_controller.py +112 -32
- glaip_sdk/cli/slash/agent_session.py +5 -2
- glaip_sdk/cli/slash/prompt.py +11 -0
- glaip_sdk/cli/slash/remote_runs_controller.py +3 -1
- glaip_sdk/cli/slash/session.py +369 -23
- glaip_sdk/cli/slash/tui/__init__.py +26 -1
- glaip_sdk/cli/slash/tui/accounts.tcss +79 -5
- glaip_sdk/cli/slash/tui/accounts_app.py +1027 -88
- glaip_sdk/cli/slash/tui/clipboard.py +195 -0
- glaip_sdk/cli/slash/tui/context.py +87 -0
- glaip_sdk/cli/slash/tui/keybind_registry.py +235 -0
- glaip_sdk/cli/slash/tui/layouts/__init__.py +14 -0
- glaip_sdk/cli/slash/tui/layouts/harlequin.py +160 -0
- glaip_sdk/cli/slash/tui/remote_runs_app.py +119 -12
- glaip_sdk/cli/slash/tui/terminal.py +407 -0
- glaip_sdk/cli/slash/tui/theme/__init__.py +15 -0
- glaip_sdk/cli/slash/tui/theme/catalog.py +79 -0
- glaip_sdk/cli/slash/tui/theme/manager.py +112 -0
- glaip_sdk/cli/slash/tui/theme/tokens.py +55 -0
- glaip_sdk/cli/slash/tui/toast.py +374 -0
- glaip_sdk/cli/transcript/history.py +1 -1
- glaip_sdk/cli/transcript/viewer.py +5 -3
- glaip_sdk/cli/tui_settings.py +125 -0
- glaip_sdk/cli/update_notifier.py +215 -7
- glaip_sdk/cli/validators.py +1 -1
- glaip_sdk/client/__init__.py +2 -1
- glaip_sdk/client/_schedule_payloads.py +89 -0
- glaip_sdk/client/agents.py +50 -8
- glaip_sdk/client/hitl.py +136 -0
- glaip_sdk/client/main.py +7 -1
- glaip_sdk/client/mcps.py +44 -13
- glaip_sdk/client/payloads/agent/__init__.py +23 -0
- glaip_sdk/client/{_agent_payloads.py → payloads/agent/requests.py} +22 -47
- glaip_sdk/client/payloads/agent/responses.py +43 -0
- glaip_sdk/client/run_rendering.py +414 -3
- glaip_sdk/client/schedules.py +439 -0
- glaip_sdk/client/tools.py +57 -26
- glaip_sdk/guardrails/__init__.py +80 -0
- glaip_sdk/guardrails/serializer.py +89 -0
- glaip_sdk/hitl/__init__.py +48 -0
- glaip_sdk/hitl/base.py +64 -0
- glaip_sdk/hitl/callback.py +43 -0
- glaip_sdk/hitl/local.py +121 -0
- glaip_sdk/hitl/remote.py +523 -0
- glaip_sdk/models/__init__.py +17 -0
- glaip_sdk/models/agent_runs.py +2 -1
- glaip_sdk/models/schedule.py +224 -0
- glaip_sdk/payload_schemas/agent.py +1 -0
- glaip_sdk/payload_schemas/guardrails.py +34 -0
- glaip_sdk/registry/tool.py +273 -59
- glaip_sdk/runner/__init__.py +20 -3
- glaip_sdk/runner/deps.py +5 -8
- glaip_sdk/runner/langgraph.py +318 -42
- glaip_sdk/runner/logging_config.py +77 -0
- glaip_sdk/runner/mcp_adapter/langchain_mcp_adapter.py +104 -5
- glaip_sdk/runner/tool_adapter/langchain_tool_adapter.py +72 -7
- glaip_sdk/schedules/__init__.py +22 -0
- glaip_sdk/schedules/base.py +291 -0
- glaip_sdk/tools/base.py +67 -14
- glaip_sdk/utils/__init__.py +1 -0
- glaip_sdk/utils/bundler.py +138 -2
- glaip_sdk/utils/import_resolver.py +43 -11
- glaip_sdk/utils/rendering/renderer/base.py +58 -0
- glaip_sdk/utils/runtime_config.py +15 -12
- glaip_sdk/utils/sync.py +31 -11
- glaip_sdk/utils/tool_detection.py +274 -6
- glaip_sdk/utils/tool_storage_provider.py +140 -0
- {glaip_sdk-0.6.5b6.dist-info → glaip_sdk-0.7.12.dist-info}/METADATA +49 -37
- glaip_sdk-0.7.12.dist-info/RECORD +219 -0
- {glaip_sdk-0.6.5b6.dist-info → glaip_sdk-0.7.12.dist-info}/WHEEL +2 -1
- glaip_sdk-0.7.12.dist-info/entry_points.txt +2 -0
- glaip_sdk-0.7.12.dist-info/top_level.txt +1 -0
- glaip_sdk/cli/commands/agents.py +0 -1509
- glaip_sdk/cli/commands/mcps.py +0 -1356
- glaip_sdk/cli/commands/tools.py +0 -576
- glaip_sdk/cli/utils.py +0 -263
- glaip_sdk-0.6.5b6.dist-info/RECORD +0 -159
- glaip_sdk-0.6.5b6.dist-info/entry_points.txt +0 -3
glaip_sdk/client/hitl.py
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""HITL REST client for manual approval operations.
|
|
3
|
+
|
|
4
|
+
Authors:
|
|
5
|
+
GLAIP SDK Team
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
from glaip_sdk.client.base import BaseClient
|
|
11
|
+
from glaip_sdk.hitl.base import HITLDecision
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class HITLClient(BaseClient):
|
|
15
|
+
"""Client for HITL REST endpoints.
|
|
16
|
+
|
|
17
|
+
Use for manual approval workflows separate from agent runs.
|
|
18
|
+
|
|
19
|
+
Example:
|
|
20
|
+
>>> # List pending approvals
|
|
21
|
+
>>> pending = client.hitl.list_pending()
|
|
22
|
+
>>>
|
|
23
|
+
>>> # Approve a request
|
|
24
|
+
>>> client.hitl.approve(
|
|
25
|
+
... request_id="bc4d0a77-7800-470e-a91c-7fd663a66b4d",
|
|
26
|
+
... operator_input="Verified and approved",
|
|
27
|
+
... )
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
def approve(
|
|
31
|
+
self,
|
|
32
|
+
request_id: str,
|
|
33
|
+
operator_input: str | None = None,
|
|
34
|
+
run_id: str | None = None,
|
|
35
|
+
) -> dict[str, Any]:
|
|
36
|
+
"""Approve a HITL request.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
request_id: HITL request ID from SSE stream
|
|
40
|
+
operator_input: Optional notes/reason for approval
|
|
41
|
+
run_id: Optional client-side run correlation ID
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
Response dict: {"status": "ok", "message": "..."}
|
|
45
|
+
"""
|
|
46
|
+
return self._post_decision(
|
|
47
|
+
request_id,
|
|
48
|
+
HITLDecision.APPROVED,
|
|
49
|
+
operator_input,
|
|
50
|
+
run_id,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
def reject(
|
|
54
|
+
self,
|
|
55
|
+
request_id: str,
|
|
56
|
+
operator_input: str | None = None,
|
|
57
|
+
run_id: str | None = None,
|
|
58
|
+
) -> dict[str, Any]:
|
|
59
|
+
"""Reject a HITL request.
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
request_id: HITL request ID
|
|
63
|
+
operator_input: Optional reason for rejection
|
|
64
|
+
run_id: Optional run correlation ID
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
Response dict
|
|
68
|
+
"""
|
|
69
|
+
return self._post_decision(
|
|
70
|
+
request_id,
|
|
71
|
+
HITLDecision.REJECTED,
|
|
72
|
+
operator_input,
|
|
73
|
+
run_id,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
def skip(
|
|
77
|
+
self,
|
|
78
|
+
request_id: str,
|
|
79
|
+
operator_input: str | None = None,
|
|
80
|
+
run_id: str | None = None,
|
|
81
|
+
) -> dict[str, Any]:
|
|
82
|
+
"""Skip a HITL request.
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
request_id: HITL request ID
|
|
86
|
+
operator_input: Optional notes
|
|
87
|
+
run_id: Optional run correlation ID
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
Response dict
|
|
91
|
+
"""
|
|
92
|
+
return self._post_decision(
|
|
93
|
+
request_id,
|
|
94
|
+
HITLDecision.SKIPPED,
|
|
95
|
+
operator_input,
|
|
96
|
+
run_id,
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
def _post_decision(
|
|
100
|
+
self,
|
|
101
|
+
request_id: str,
|
|
102
|
+
decision: HITLDecision,
|
|
103
|
+
operator_input: str | None,
|
|
104
|
+
run_id: str | None,
|
|
105
|
+
) -> dict[str, Any]:
|
|
106
|
+
"""Post HITL decision to backend."""
|
|
107
|
+
payload = {
|
|
108
|
+
"request_id": request_id,
|
|
109
|
+
"decision": decision.value,
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if operator_input:
|
|
113
|
+
payload["operator_input"] = operator_input
|
|
114
|
+
if run_id:
|
|
115
|
+
payload["run_id"] = run_id
|
|
116
|
+
|
|
117
|
+
return self._request("POST", "/agents/hitl/decision", json=payload)
|
|
118
|
+
|
|
119
|
+
def list_pending(self) -> list[dict[str, Any]]:
|
|
120
|
+
"""List all pending HITL requests.
|
|
121
|
+
|
|
122
|
+
Returns:
|
|
123
|
+
List of pending request dicts with metadata:
|
|
124
|
+
[
|
|
125
|
+
{
|
|
126
|
+
"request_id": "...",
|
|
127
|
+
"tool": "...",
|
|
128
|
+
"arguments": {...},
|
|
129
|
+
"created_at": "...",
|
|
130
|
+
"agent_id": "...",
|
|
131
|
+
"hitl_metadata": {...},
|
|
132
|
+
},
|
|
133
|
+
...
|
|
134
|
+
]
|
|
135
|
+
"""
|
|
136
|
+
return self._request("GET", "/agents/hitl/pending")
|
glaip_sdk/client/main.py
CHANGED
|
@@ -12,13 +12,15 @@ from typing import TYPE_CHECKING, Any
|
|
|
12
12
|
|
|
13
13
|
from glaip_sdk.client.agents import AgentClient
|
|
14
14
|
from glaip_sdk.client.base import BaseClient
|
|
15
|
+
from glaip_sdk.client.hitl import HITLClient
|
|
15
16
|
from glaip_sdk.client.mcps import MCPClient
|
|
17
|
+
from glaip_sdk.client.schedules import ScheduleClient
|
|
16
18
|
from glaip_sdk.client.shared import build_shared_config
|
|
17
19
|
from glaip_sdk.client.tools import ToolClient
|
|
18
20
|
|
|
19
21
|
if TYPE_CHECKING: # pragma: no cover
|
|
20
22
|
from glaip_sdk.agents import Agent
|
|
21
|
-
from glaip_sdk.client.
|
|
23
|
+
from glaip_sdk.client.payloads.agent import AgentListResult
|
|
22
24
|
from glaip_sdk.mcps import MCP
|
|
23
25
|
from glaip_sdk.tools import Tool
|
|
24
26
|
|
|
@@ -38,6 +40,8 @@ class Client(BaseClient):
|
|
|
38
40
|
self.agents = AgentClient(**shared_config)
|
|
39
41
|
self.tools = ToolClient(**shared_config)
|
|
40
42
|
self.mcps = MCPClient(**shared_config)
|
|
43
|
+
self.schedules = ScheduleClient(**shared_config)
|
|
44
|
+
self.hitl = HITLClient(**shared_config)
|
|
41
45
|
|
|
42
46
|
# ---- Core API Methods (Public Interface) ----
|
|
43
47
|
|
|
@@ -236,6 +240,8 @@ class Client(BaseClient):
|
|
|
236
240
|
self.tools.http_client = self.http_client
|
|
237
241
|
if hasattr(self, "mcps"):
|
|
238
242
|
self.mcps.http_client = self.http_client
|
|
243
|
+
if hasattr(self, "schedules"):
|
|
244
|
+
self.schedules.http_client = self.http_client
|
|
239
245
|
except Exception:
|
|
240
246
|
pass
|
|
241
247
|
|
glaip_sdk/client/mcps.py
CHANGED
|
@@ -85,26 +85,56 @@ class MCPClient(BaseClient):
|
|
|
85
85
|
response = MCPResponse(**full_mcp_data)
|
|
86
86
|
return MCP.from_response(response, client=self)
|
|
87
87
|
|
|
88
|
-
def update_mcp(self, mcp_id: str, **kwargs) -> MCP:
|
|
88
|
+
def update_mcp(self, mcp_id: str | MCP, **kwargs) -> MCP:
|
|
89
89
|
"""Update an existing MCP.
|
|
90
90
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
91
|
+
Notes:
|
|
92
|
+
- Payload construction is centralized via ``_build_update_payload`` so required
|
|
93
|
+
defaults (e.g., ``type``) and value normalization stay consistent across SDK and CLI.
|
|
94
|
+
- For backward compatibility, still chooses PATCH vs PUT based on which fields the
|
|
95
|
+
caller provided, but uses the SDK payload builder for the final payload.
|
|
95
96
|
"""
|
|
96
|
-
#
|
|
97
|
+
# Backward-compatible: allow passing an MCP instance to avoid an extra fetch.
|
|
98
|
+
if isinstance(mcp_id, MCP):
|
|
99
|
+
current_mcp = mcp_id
|
|
100
|
+
if not current_mcp.id:
|
|
101
|
+
raise ValueError("MCP instance has no id; cannot update.")
|
|
102
|
+
mcp_id_value = str(current_mcp.id)
|
|
103
|
+
else:
|
|
104
|
+
current_mcp = None
|
|
105
|
+
mcp_id_value = mcp_id
|
|
106
|
+
|
|
97
107
|
required_fields = {"name", "config", "transport"}
|
|
98
108
|
provided_fields = set(kwargs.keys())
|
|
109
|
+
method = "PUT" if required_fields.issubset(provided_fields) else "PATCH"
|
|
110
|
+
|
|
111
|
+
if not kwargs:
|
|
112
|
+
data = self._request(method, f"{MCPS_ENDPOINT}{mcp_id_value}", json={})
|
|
113
|
+
response = MCPResponse(**data)
|
|
114
|
+
return MCP.from_response(response, client=self)
|
|
115
|
+
|
|
116
|
+
if current_mcp is None:
|
|
117
|
+
current_mcp = self.get_mcp_by_id(mcp_id_value)
|
|
118
|
+
|
|
119
|
+
payload_kwargs = kwargs.copy()
|
|
120
|
+
name = payload_kwargs.pop("name", None)
|
|
121
|
+
description = payload_kwargs.pop("description", None)
|
|
122
|
+
full_payload = self._build_update_payload(
|
|
123
|
+
current_mcp=current_mcp,
|
|
124
|
+
name=name,
|
|
125
|
+
description=description,
|
|
126
|
+
**payload_kwargs,
|
|
127
|
+
)
|
|
99
128
|
|
|
100
|
-
if
|
|
101
|
-
|
|
102
|
-
method = "PUT"
|
|
129
|
+
if method == "PUT":
|
|
130
|
+
json_payload = full_payload
|
|
103
131
|
else:
|
|
104
|
-
|
|
105
|
-
|
|
132
|
+
json_payload = {key: full_payload[key] for key in provided_fields if key in full_payload}
|
|
133
|
+
json_payload["type"] = full_payload["type"]
|
|
134
|
+
if "config" in provided_fields and "transport" not in provided_fields and "transport" in full_payload:
|
|
135
|
+
json_payload["transport"] = full_payload["transport"]
|
|
106
136
|
|
|
107
|
-
data = self._request(method, f"{MCPS_ENDPOINT}{
|
|
137
|
+
data = self._request(method, f"{MCPS_ENDPOINT}{mcp_id_value}", json=json_payload)
|
|
108
138
|
response = MCPResponse(**data)
|
|
109
139
|
return MCP.from_response(response, client=self)
|
|
110
140
|
|
|
@@ -188,7 +218,8 @@ class MCPClient(BaseClient):
|
|
|
188
218
|
**kwargs,
|
|
189
219
|
) -> MCP:
|
|
190
220
|
"""Find by name and update, or create if not found."""
|
|
191
|
-
|
|
221
|
+
all_mcps = self.list_mcps()
|
|
222
|
+
existing = [mcp for mcp in all_mcps if mcp.name.lower() == name.lower()]
|
|
192
223
|
|
|
193
224
|
if len(existing) == 1:
|
|
194
225
|
logger.info("Updating existing MCP: %s", name)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""Agent payload types for requests and responses.
|
|
2
|
+
|
|
3
|
+
Authors:
|
|
4
|
+
Raymond Christopher (raymond.christopher@gdplabs.id)
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from glaip_sdk.client.payloads.agent.requests import (
|
|
8
|
+
AgentCreateRequest,
|
|
9
|
+
AgentListParams,
|
|
10
|
+
AgentUpdateRequest,
|
|
11
|
+
merge_payload_fields,
|
|
12
|
+
resolve_language_model_fields,
|
|
13
|
+
)
|
|
14
|
+
from glaip_sdk.client.payloads.agent.responses import AgentListResult
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"AgentCreateRequest",
|
|
18
|
+
"AgentListParams",
|
|
19
|
+
"AgentListResult",
|
|
20
|
+
"AgentUpdateRequest",
|
|
21
|
+
"merge_payload_fields",
|
|
22
|
+
"resolve_language_model_fields",
|
|
23
|
+
]
|
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
|
|
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
|
|
12
|
+
from dataclasses import dataclass
|
|
9
13
|
from typing import Any
|
|
10
14
|
|
|
11
15
|
from glaip_sdk.config.constants import (
|
|
@@ -273,38 +277,6 @@ class AgentListParams:
|
|
|
273
277
|
params[f"metadata.{key}"] = value
|
|
274
278
|
|
|
275
279
|
|
|
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
280
|
@dataclass(slots=True)
|
|
309
281
|
class AgentCreateRequest:
|
|
310
282
|
"""Declarative representation of an agent creation payload."""
|
|
@@ -422,16 +394,6 @@ class AgentUpdateRequest:
|
|
|
422
394
|
return payload
|
|
423
395
|
|
|
424
396
|
|
|
425
|
-
__all__ = [
|
|
426
|
-
"AgentCreateRequest",
|
|
427
|
-
"AgentListParams",
|
|
428
|
-
"AgentListResult",
|
|
429
|
-
"AgentUpdateRequest",
|
|
430
|
-
"merge_payload_fields",
|
|
431
|
-
"resolve_language_model_fields",
|
|
432
|
-
]
|
|
433
|
-
|
|
434
|
-
|
|
435
397
|
def _build_base_update_payload(request: AgentUpdateRequest, current_agent: Any) -> dict[str, Any]:
|
|
436
398
|
"""Populate immutable agent update fields using request data or existing agent defaults."""
|
|
437
399
|
# Support both "agent_type" (runtime class) and "type" (API response) attributes
|
|
@@ -451,14 +413,27 @@ def _build_base_update_payload(request: AgentUpdateRequest, current_agent: Any)
|
|
|
451
413
|
|
|
452
414
|
def _resolve_update_language_model_fields(request: AgentUpdateRequest, current_agent: Any) -> dict[str, Any]:
|
|
453
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)
|
|
454
431
|
fields = resolve_language_model_fields(
|
|
455
432
|
model=request.model,
|
|
456
433
|
language_model_id=request.language_model_id,
|
|
457
434
|
provider=request.provider,
|
|
458
435
|
model_name=request.model_name,
|
|
459
436
|
)
|
|
460
|
-
if not fields:
|
|
461
|
-
fields = _existing_language_model_fields(current_agent)
|
|
462
437
|
return fields
|
|
463
438
|
|
|
464
439
|
|
|
@@ -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]
|