glaip-sdk 0.6.1__py3-none-any.whl → 0.6.2__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/agents/base.py +71 -23
- glaip_sdk/client/agents.py +36 -2
- glaip_sdk/utils/runtime_config.py +306 -0
- {glaip_sdk-0.6.1.dist-info → glaip_sdk-0.6.2.dist-info}/METADATA +1 -1
- {glaip_sdk-0.6.1.dist-info → glaip_sdk-0.6.2.dist-info}/RECORD +7 -6
- {glaip_sdk-0.6.1.dist-info → glaip_sdk-0.6.2.dist-info}/WHEEL +0 -0
- {glaip_sdk-0.6.1.dist-info → glaip_sdk-0.6.2.dist-info}/entry_points.txt +0 -0
glaip_sdk/agents/base.py
CHANGED
|
@@ -51,6 +51,7 @@ from typing import TYPE_CHECKING, Any
|
|
|
51
51
|
|
|
52
52
|
from glaip_sdk.registry import get_agent_registry, get_mcp_registry, get_tool_registry
|
|
53
53
|
from glaip_sdk.utils.discovery import find_agent
|
|
54
|
+
from glaip_sdk.utils.runtime_config import normalize_runtime_config_keys
|
|
54
55
|
|
|
55
56
|
if TYPE_CHECKING:
|
|
56
57
|
from glaip_sdk.models import AgentResponse
|
|
@@ -795,21 +796,23 @@ class Agent:
|
|
|
795
796
|
self._client = client
|
|
796
797
|
return self
|
|
797
798
|
|
|
798
|
-
def
|
|
799
|
+
def _prepare_run_kwargs(
|
|
799
800
|
self,
|
|
800
801
|
message: str,
|
|
801
|
-
verbose: bool
|
|
802
|
+
verbose: bool,
|
|
803
|
+
runtime_config: dict[str, Any] | None,
|
|
802
804
|
**kwargs: Any,
|
|
803
|
-
) -> str:
|
|
804
|
-
"""
|
|
805
|
+
) -> tuple[Any, dict[str, Any]]:
|
|
806
|
+
"""Prepare common arguments for run/arun methods.
|
|
805
807
|
|
|
806
808
|
Args:
|
|
807
809
|
message: The message to send to the agent.
|
|
808
810
|
verbose: If True, print streaming output to console.
|
|
811
|
+
runtime_config: Optional runtime configuration.
|
|
809
812
|
**kwargs: Additional arguments to pass to the run API.
|
|
810
813
|
|
|
811
814
|
Returns:
|
|
812
|
-
|
|
815
|
+
Tuple of (agent_client, call_kwargs).
|
|
813
816
|
|
|
814
817
|
Raises:
|
|
815
818
|
ValueError: If the agent hasn't been deployed yet.
|
|
@@ -820,24 +823,77 @@ class Agent:
|
|
|
820
823
|
if not self._client:
|
|
821
824
|
raise RuntimeError(_CLIENT_NOT_AVAILABLE_MSG)
|
|
822
825
|
|
|
823
|
-
# _client can be either main Client or AgentClient
|
|
824
826
|
agent_client = getattr(self._client, "agents", self._client)
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
827
|
+
|
|
828
|
+
call_kwargs: dict[str, Any] = {
|
|
829
|
+
"agent_id": self.id,
|
|
830
|
+
"message": message,
|
|
831
|
+
"verbose": verbose,
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
if runtime_config is not None:
|
|
835
|
+
call_kwargs["runtime_config"] = normalize_runtime_config_keys(
|
|
836
|
+
runtime_config,
|
|
837
|
+
tool_registry=get_tool_registry(),
|
|
838
|
+
mcp_registry=get_mcp_registry(),
|
|
839
|
+
agent_registry=get_agent_registry(),
|
|
840
|
+
)
|
|
841
|
+
|
|
842
|
+
call_kwargs.update(kwargs)
|
|
843
|
+
return agent_client, call_kwargs
|
|
844
|
+
|
|
845
|
+
def run(
|
|
846
|
+
self,
|
|
847
|
+
message: str,
|
|
848
|
+
verbose: bool = False,
|
|
849
|
+
runtime_config: dict[str, Any] | None = None,
|
|
850
|
+
**kwargs: Any,
|
|
851
|
+
) -> str:
|
|
852
|
+
"""Run the agent synchronously with a message.
|
|
853
|
+
|
|
854
|
+
Args:
|
|
855
|
+
message: The message to send to the agent.
|
|
856
|
+
verbose: If True, print streaming output to console.
|
|
857
|
+
runtime_config: Optional runtime configuration for tools, MCPs, and agents.
|
|
858
|
+
Keys can be SDK objects, UUIDs, or names. Example:
|
|
859
|
+
{
|
|
860
|
+
"tool_configs": {"tool-id": {"param": "value"}},
|
|
861
|
+
"mcp_configs": {"mcp-id": {"setting": "on"}},
|
|
862
|
+
"agent_config": {"planning": True},
|
|
863
|
+
}
|
|
864
|
+
**kwargs: Additional arguments to pass to the run API.
|
|
865
|
+
|
|
866
|
+
Returns:
|
|
867
|
+
The agent's response as a string.
|
|
868
|
+
|
|
869
|
+
Raises:
|
|
870
|
+
ValueError: If the agent hasn't been deployed yet.
|
|
871
|
+
RuntimeError: If client is not available.
|
|
872
|
+
"""
|
|
873
|
+
agent_client, call_kwargs = self._prepare_run_kwargs(
|
|
874
|
+
message, verbose, runtime_config or kwargs.get("runtime_config"), **kwargs
|
|
830
875
|
)
|
|
876
|
+
return agent_client.run_agent(**call_kwargs)
|
|
831
877
|
|
|
832
878
|
async def arun(
|
|
833
879
|
self,
|
|
834
880
|
message: str,
|
|
881
|
+
verbose: bool = False,
|
|
882
|
+
runtime_config: dict[str, Any] | None = None,
|
|
835
883
|
**kwargs: Any,
|
|
836
884
|
) -> AsyncGenerator[dict, None]:
|
|
837
885
|
"""Run the agent asynchronously with streaming output.
|
|
838
886
|
|
|
839
887
|
Args:
|
|
840
888
|
message: The message to send to the agent.
|
|
889
|
+
verbose: If True, print streaming output to console.
|
|
890
|
+
runtime_config: Optional runtime configuration for tools, MCPs, and agents.
|
|
891
|
+
Keys can be SDK objects, UUIDs, or names. Example:
|
|
892
|
+
{
|
|
893
|
+
"tool_configs": {"tool-id": {"param": "value"}},
|
|
894
|
+
"mcp_configs": {"mcp-id": {"setting": "on"}},
|
|
895
|
+
"agent_config": {"planning": True},
|
|
896
|
+
}
|
|
841
897
|
**kwargs: Additional arguments to pass to the run API.
|
|
842
898
|
|
|
843
899
|
Yields:
|
|
@@ -847,18 +903,10 @@ class Agent:
|
|
|
847
903
|
ValueError: If the agent hasn't been deployed yet.
|
|
848
904
|
RuntimeError: If client is not available.
|
|
849
905
|
"""
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
# _client can be either main Client or AgentClient
|
|
856
|
-
agent_client = getattr(self._client, "agents", self._client)
|
|
857
|
-
async for chunk in agent_client.arun_agent(
|
|
858
|
-
agent_id=self.id,
|
|
859
|
-
message=message,
|
|
860
|
-
**kwargs,
|
|
861
|
-
):
|
|
906
|
+
agent_client, call_kwargs = self._prepare_run_kwargs(
|
|
907
|
+
message, verbose, runtime_config or kwargs.get("runtime_config"), **kwargs
|
|
908
|
+
)
|
|
909
|
+
async for chunk in agent_client.arun_agent(**call_kwargs):
|
|
862
910
|
yield chunk
|
|
863
911
|
|
|
864
912
|
def update(self, **kwargs: Any) -> Agent:
|
glaip_sdk/client/agents.py
CHANGED
|
@@ -441,7 +441,7 @@ class AgentClient(BaseClient):
|
|
|
441
441
|
started_monotonic: float | None,
|
|
442
442
|
finished_monotonic: float | None,
|
|
443
443
|
) -> str:
|
|
444
|
-
"""Finalize the renderer and return the final text.
|
|
444
|
+
"""Finalize the renderer and return the final response text.
|
|
445
445
|
|
|
446
446
|
Args:
|
|
447
447
|
renderer: Renderer to finalize.
|
|
@@ -1095,9 +1095,32 @@ class AgentClient(BaseClient):
|
|
|
1095
1095
|
tty: bool = False,
|
|
1096
1096
|
*,
|
|
1097
1097
|
renderer: RichStreamRenderer | str | None = "auto",
|
|
1098
|
+
runtime_config: dict[str, Any] | None = None,
|
|
1098
1099
|
**kwargs,
|
|
1099
1100
|
) -> str:
|
|
1100
|
-
"""Run an agent with a message, streaming via a renderer.
|
|
1101
|
+
"""Run an agent with a message, streaming via a renderer.
|
|
1102
|
+
|
|
1103
|
+
Args:
|
|
1104
|
+
agent_id: The ID of the agent to run.
|
|
1105
|
+
message: The message to send to the agent.
|
|
1106
|
+
files: Optional list of files to include with the request.
|
|
1107
|
+
tty: Whether to enable TTY mode.
|
|
1108
|
+
renderer: Renderer for streaming output.
|
|
1109
|
+
runtime_config: Optional runtime configuration for tools, MCPs, and agents.
|
|
1110
|
+
Keys should be platform IDs. Example:
|
|
1111
|
+
{
|
|
1112
|
+
"tool_configs": {"tool-id": {"param": "value"}},
|
|
1113
|
+
"mcp_configs": {"mcp-id": {"setting": "on"}},
|
|
1114
|
+
"agent_config": {"planning": True},
|
|
1115
|
+
}
|
|
1116
|
+
**kwargs: Additional arguments to pass to the run API.
|
|
1117
|
+
|
|
1118
|
+
Returns:
|
|
1119
|
+
The agent's response as a string.
|
|
1120
|
+
"""
|
|
1121
|
+
# Include runtime_config in kwargs only when caller hasn't already provided it
|
|
1122
|
+
if runtime_config is not None and "runtime_config" not in kwargs:
|
|
1123
|
+
kwargs["runtime_config"] = runtime_config
|
|
1101
1124
|
(
|
|
1102
1125
|
payload,
|
|
1103
1126
|
data_payload,
|
|
@@ -1242,6 +1265,7 @@ class AgentClient(BaseClient):
|
|
|
1242
1265
|
files: list[str | BinaryIO] | None = None,
|
|
1243
1266
|
*,
|
|
1244
1267
|
request_timeout: float | None = None,
|
|
1268
|
+
runtime_config: dict[str, Any] | None = None,
|
|
1245
1269
|
**kwargs,
|
|
1246
1270
|
) -> AsyncGenerator[dict, None]:
|
|
1247
1271
|
"""Async run an agent with a message, yielding streaming JSON chunks.
|
|
@@ -1251,6 +1275,13 @@ class AgentClient(BaseClient):
|
|
|
1251
1275
|
message: Message to send to the agent
|
|
1252
1276
|
files: Optional list of files to include
|
|
1253
1277
|
request_timeout: Optional request timeout in seconds (defaults to client timeout)
|
|
1278
|
+
runtime_config: Optional runtime configuration for tools, MCPs, and agents.
|
|
1279
|
+
Keys should be platform IDs. Example:
|
|
1280
|
+
{
|
|
1281
|
+
"tool_configs": {"tool-id": {"param": "value"}},
|
|
1282
|
+
"mcp_configs": {"mcp-id": {"setting": "on"}},
|
|
1283
|
+
"agent_config": {"planning": True},
|
|
1284
|
+
}
|
|
1254
1285
|
**kwargs: Additional arguments (chat_history, pii_mapping, etc.)
|
|
1255
1286
|
|
|
1256
1287
|
Yields:
|
|
@@ -1261,6 +1292,9 @@ class AgentClient(BaseClient):
|
|
|
1261
1292
|
httpx.TimeoutException: When general timeout occurs
|
|
1262
1293
|
Exception: For other unexpected errors
|
|
1263
1294
|
"""
|
|
1295
|
+
# Include runtime_config in kwargs only when caller hasn't already provided it
|
|
1296
|
+
if runtime_config is not None and "runtime_config" not in kwargs:
|
|
1297
|
+
kwargs["runtime_config"] = runtime_config
|
|
1264
1298
|
# Derive timeout values for request/control flow
|
|
1265
1299
|
legacy_timeout = kwargs.get("timeout")
|
|
1266
1300
|
http_timeout_override = request_timeout if request_timeout is not None else legacy_timeout
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
"""Runtime configuration helpers for agent execution.
|
|
2
|
+
|
|
3
|
+
Provides utilities for normalizing runtime_config keys from various input types
|
|
4
|
+
(SDK objects, UUIDs, names) to stable platform IDs.
|
|
5
|
+
|
|
6
|
+
Authors:
|
|
7
|
+
Christian Trisno Sen Long Chen (christian.t.s.l.chen@gdplabs.id)
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from typing import TYPE_CHECKING
|
|
13
|
+
|
|
14
|
+
from glaip_sdk.utils.resource_refs import is_uuid
|
|
15
|
+
from gllm_core.utils import LoggerManager
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from glaip_sdk.agents import Agent
|
|
19
|
+
from glaip_sdk.mcps import MCP
|
|
20
|
+
from glaip_sdk.registry import AgentRegistry, MCPRegistry, ToolRegistry
|
|
21
|
+
from glaip_sdk.tools import Tool
|
|
22
|
+
|
|
23
|
+
# Type alias for config key inputs (only used in type hints)
|
|
24
|
+
ConfigKeyInput = str | Agent | Tool | MCP | type[Agent] | type[Tool] | type[MCP]
|
|
25
|
+
|
|
26
|
+
# Type alias for registry types
|
|
27
|
+
Registry = ToolRegistry | MCPRegistry | AgentRegistry
|
|
28
|
+
|
|
29
|
+
# Type alias for runtime config dict shape after normalization
|
|
30
|
+
# Top-level keys include:
|
|
31
|
+
# - "tool_configs", "mcp_configs", "agent_config"
|
|
32
|
+
# - Agent IDs for agent-specific overrides
|
|
33
|
+
# Values are nested dictionaries whose contents depend on the section.
|
|
34
|
+
RuntimeConfigDict = dict[str, dict[str, object]]
|
|
35
|
+
|
|
36
|
+
logger = LoggerManager().get_logger(__name__)
|
|
37
|
+
|
|
38
|
+
# Config fields that need key normalization (maps field name to registry type)
|
|
39
|
+
_NORMALIZABLE_FIELDS = {
|
|
40
|
+
"tool_configs": "tool",
|
|
41
|
+
"mcp_configs": "mcp",
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
# Config fields that are preserved as-is (no normalization needed)
|
|
45
|
+
_PASSTHROUGH_FIELDS = {"agent_config"}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _extract_id_from_key(key: ConfigKeyInput) -> str | None:
|
|
49
|
+
"""Extract ID directly from key if available.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
key: The config key to extract ID from.
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
The ID string if available, None otherwise.
|
|
56
|
+
"""
|
|
57
|
+
if isinstance(key, str) and is_uuid(key):
|
|
58
|
+
return key
|
|
59
|
+
if hasattr(key, "id") and key.id is not None:
|
|
60
|
+
return key.id
|
|
61
|
+
return None
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _resolve_via_registry(key: ConfigKeyInput, registry: Registry | None) -> str | None:
|
|
65
|
+
"""Attempt to resolve key via registry.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
key: The config key to resolve.
|
|
69
|
+
registry: Registry to use for resolution.
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
The resolved ID string if successful, None otherwise.
|
|
73
|
+
"""
|
|
74
|
+
if registry is None:
|
|
75
|
+
return None
|
|
76
|
+
|
|
77
|
+
try:
|
|
78
|
+
return registry.resolve(key).id
|
|
79
|
+
except (KeyError, ValueError, AttributeError) as exc:
|
|
80
|
+
logger.debug("Failed to resolve key via registry: %r", key, exc_info=exc)
|
|
81
|
+
return None
|
|
82
|
+
except Exception as exc: # pragma: no cover - unexpected failures
|
|
83
|
+
logger.warning(
|
|
84
|
+
"Unexpected error resolving key via registry for %r: %s",
|
|
85
|
+
key,
|
|
86
|
+
exc,
|
|
87
|
+
exc_info=True,
|
|
88
|
+
)
|
|
89
|
+
return None
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def _resolve_config_key(
|
|
93
|
+
key: ConfigKeyInput,
|
|
94
|
+
registry: Registry | None,
|
|
95
|
+
*,
|
|
96
|
+
missing_registry_message: str,
|
|
97
|
+
unresolved_message: str,
|
|
98
|
+
) -> str:
|
|
99
|
+
"""Resolve a config key using a registry when needed.
|
|
100
|
+
|
|
101
|
+
For non-ID keys this always requires a registry; callers customize the
|
|
102
|
+
error messages for missing registries vs unresolved keys.
|
|
103
|
+
"""
|
|
104
|
+
# Allow direct UUID / object.id without needing a registry
|
|
105
|
+
if (extracted_id := _extract_id_from_key(key)) is not None:
|
|
106
|
+
return extracted_id
|
|
107
|
+
|
|
108
|
+
# For non-ID keys we always require a registry
|
|
109
|
+
if registry is None:
|
|
110
|
+
raise ValueError(missing_registry_message.format(key=key))
|
|
111
|
+
|
|
112
|
+
if (resolved_id := _resolve_via_registry(key, registry)) is not None:
|
|
113
|
+
return resolved_id
|
|
114
|
+
|
|
115
|
+
raise ValueError(unresolved_message.format(key=key))
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def _normalize_section_keys(
|
|
119
|
+
config_section: dict[ConfigKeyInput, dict[str, object]],
|
|
120
|
+
registry: Registry | None,
|
|
121
|
+
) -> dict[str, dict[str, object]]:
|
|
122
|
+
"""Normalize keys in a single config section (e.g. tool_configs).
|
|
123
|
+
|
|
124
|
+
Converts ConfigKeyInput keys (SDK objects, names, classes) to stable IDs
|
|
125
|
+
using the provided registry.
|
|
126
|
+
|
|
127
|
+
Example:
|
|
128
|
+
Input: {ToolClass: {"param": "value"}, "tool-name": {"x": 1}}
|
|
129
|
+
Output: {"uuid-1": {"param": "value"}, "uuid-2": {"x": 1}}
|
|
130
|
+
|
|
131
|
+
Args:
|
|
132
|
+
config_section: The config section dict to normalize.
|
|
133
|
+
registry: Registry to use for resolving keys.
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
Normalized config section with all keys converted to IDs.
|
|
137
|
+
"""
|
|
138
|
+
normalized: dict[str, dict[str, object]] = {}
|
|
139
|
+
for key, value in config_section.items():
|
|
140
|
+
resolved_id = _resolve_config_key(
|
|
141
|
+
key,
|
|
142
|
+
registry,
|
|
143
|
+
missing_registry_message="Unable to resolve runtime_config key via registry: {key!r}",
|
|
144
|
+
unresolved_message="Unable to resolve runtime_config key via registry: {key!r}",
|
|
145
|
+
)
|
|
146
|
+
normalized[resolved_id] = value
|
|
147
|
+
return normalized
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def _is_agent_specific_key(key: object) -> bool:
|
|
151
|
+
"""Check if a key represents an agent-specific override.
|
|
152
|
+
|
|
153
|
+
Agent-specific keys are:
|
|
154
|
+
- Agent instances (from glaip_sdk.agents.Agent)
|
|
155
|
+
- UUID strings (agent IDs)
|
|
156
|
+
- Non-reserved string names (resolved via agent_registry)
|
|
157
|
+
|
|
158
|
+
NOT agent-specific:
|
|
159
|
+
- Known config field names (tool_configs, mcp_configs, agent_config)
|
|
160
|
+
- Tool or MCP objects (these are only valid inside *_configs sections)
|
|
161
|
+
|
|
162
|
+
Args:
|
|
163
|
+
key: The key to check.
|
|
164
|
+
|
|
165
|
+
Returns:
|
|
166
|
+
True if the key could be an agent-specific override.
|
|
167
|
+
"""
|
|
168
|
+
from glaip_sdk.agents import Agent # noqa: PLC0415
|
|
169
|
+
|
|
170
|
+
# Agent instance
|
|
171
|
+
if isinstance(key, Agent):
|
|
172
|
+
return True
|
|
173
|
+
|
|
174
|
+
# Non-string keys that are not Agent instances are not agent-specific
|
|
175
|
+
if not isinstance(key, str):
|
|
176
|
+
return False
|
|
177
|
+
|
|
178
|
+
# Known config field names are not agent-specific
|
|
179
|
+
if key in _NORMALIZABLE_FIELDS or key in _PASSTHROUGH_FIELDS:
|
|
180
|
+
return False
|
|
181
|
+
|
|
182
|
+
# Any other string key is treated as an agent reference (ID or name)
|
|
183
|
+
return True
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
def _normalize_standard_config(
|
|
187
|
+
config: dict[str, object],
|
|
188
|
+
tool_registry: ToolRegistry | None,
|
|
189
|
+
mcp_registry: MCPRegistry | None,
|
|
190
|
+
context: str = "",
|
|
191
|
+
) -> dict[str, object]:
|
|
192
|
+
"""Normalize a standard config dict with tool_configs, mcp_configs, agent_config sections.
|
|
193
|
+
|
|
194
|
+
Used for both global runtime_config and agent-specific nested configs.
|
|
195
|
+
Delegates key normalization to _normalize_section_keys for each section.
|
|
196
|
+
|
|
197
|
+
Example:
|
|
198
|
+
Input: {"tool_configs": {ToolClass: {...}}, "agent_config": {...}}
|
|
199
|
+
Output: {"tool_configs": {"tool-uuid": {...}}, "agent_config": {...}}
|
|
200
|
+
|
|
201
|
+
Args:
|
|
202
|
+
config: The config dict to normalize.
|
|
203
|
+
tool_registry: Registry for resolving tool keys.
|
|
204
|
+
mcp_registry: Registry for resolving MCP keys.
|
|
205
|
+
context: Context string for warning messages.
|
|
206
|
+
|
|
207
|
+
Returns:
|
|
208
|
+
Normalized config dict.
|
|
209
|
+
"""
|
|
210
|
+
registries: dict[str, Registry | None] = {
|
|
211
|
+
"tool": tool_registry,
|
|
212
|
+
"mcp": mcp_registry,
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
result: dict[str, object] = {}
|
|
216
|
+
|
|
217
|
+
for field, value in config.items():
|
|
218
|
+
if field in _NORMALIZABLE_FIELDS and isinstance(value, dict):
|
|
219
|
+
registry_type = _NORMALIZABLE_FIELDS[field]
|
|
220
|
+
result[field] = _normalize_section_keys(value, registries.get(registry_type))
|
|
221
|
+
elif field in _PASSTHROUGH_FIELDS:
|
|
222
|
+
result[field] = value
|
|
223
|
+
else:
|
|
224
|
+
logger.warning("Unknown field '%s' in %s, ignoring", field, context or "config")
|
|
225
|
+
|
|
226
|
+
return result
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def normalize_runtime_config_keys(
|
|
230
|
+
runtime_config: RuntimeConfigDict | None,
|
|
231
|
+
tool_registry: ToolRegistry | None,
|
|
232
|
+
mcp_registry: MCPRegistry | None,
|
|
233
|
+
agent_registry: AgentRegistry | None,
|
|
234
|
+
) -> RuntimeConfigDict | None:
|
|
235
|
+
"""Normalize runtime_config keys from various input types to stable IDs.
|
|
236
|
+
|
|
237
|
+
Handles both global configs and agent-specific overrides:
|
|
238
|
+
- Global: tool_configs, mcp_configs, agent_config
|
|
239
|
+
- Agent-specific: keyed by Agent object, agent UUID, or agent name string
|
|
240
|
+
|
|
241
|
+
Example:
|
|
242
|
+
Input:
|
|
243
|
+
{
|
|
244
|
+
"tool_configs": {ToolClass: {"param": "val"}},
|
|
245
|
+
"agent_config": {"planning": True},
|
|
246
|
+
AgentClass: {"mcp_configs": {MCPClass: {...}}}
|
|
247
|
+
}
|
|
248
|
+
Output:
|
|
249
|
+
{
|
|
250
|
+
"tool_configs": {"tool-uuid": {"param": "val"}},
|
|
251
|
+
"agent_config": {"planning": True},
|
|
252
|
+
"agent-uuid": {"mcp_configs": {"mcp-uuid": {...}}}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
Converts keys from:
|
|
256
|
+
- SDK objects → their .id attribute
|
|
257
|
+
- UUID strings → passed through
|
|
258
|
+
- Names → resolved via appropriate registry
|
|
259
|
+
|
|
260
|
+
Args:
|
|
261
|
+
runtime_config: The runtime configuration dict to normalize.
|
|
262
|
+
tool_registry: Registry for resolving tool keys.
|
|
263
|
+
mcp_registry: Registry for resolving MCP keys.
|
|
264
|
+
agent_registry: Registry for resolving agent keys.
|
|
265
|
+
|
|
266
|
+
Returns:
|
|
267
|
+
Normalized runtime_config with all keys converted to IDs, or None if input is None.
|
|
268
|
+
"""
|
|
269
|
+
if runtime_config is None:
|
|
270
|
+
return None
|
|
271
|
+
|
|
272
|
+
if not runtime_config:
|
|
273
|
+
return {}
|
|
274
|
+
|
|
275
|
+
registries: dict[str, Registry | None] = {
|
|
276
|
+
"tool": tool_registry,
|
|
277
|
+
"mcp": mcp_registry,
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
result: dict[str, object] = {}
|
|
281
|
+
|
|
282
|
+
for field, value in runtime_config.items():
|
|
283
|
+
if field in _NORMALIZABLE_FIELDS and isinstance(value, dict):
|
|
284
|
+
registry_type = _NORMALIZABLE_FIELDS[field]
|
|
285
|
+
result[field] = _normalize_section_keys(value, registries.get(registry_type))
|
|
286
|
+
elif field in _PASSTHROUGH_FIELDS:
|
|
287
|
+
result[field] = value
|
|
288
|
+
elif _is_agent_specific_key(field) and isinstance(value, dict):
|
|
289
|
+
agent_id = _resolve_config_key(
|
|
290
|
+
field,
|
|
291
|
+
agent_registry,
|
|
292
|
+
missing_registry_message=(
|
|
293
|
+
"Agent-specific runtime_config provided but no agent_registry is available to resolve key: {key!r}"
|
|
294
|
+
),
|
|
295
|
+
unresolved_message="Unable to resolve agent-specific runtime_config key: {key!r}",
|
|
296
|
+
)
|
|
297
|
+
result[agent_id] = _normalize_standard_config(
|
|
298
|
+
value,
|
|
299
|
+
tool_registry,
|
|
300
|
+
mcp_registry,
|
|
301
|
+
context=f"agent '{agent_id}'",
|
|
302
|
+
)
|
|
303
|
+
else:
|
|
304
|
+
logger.warning("Unknown field '%s' in runtime_config, ignoring", field)
|
|
305
|
+
|
|
306
|
+
return result
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
glaip_sdk/__init__.py,sha256=0PAFfodqAEdggIiV1Es_JryDokZrhYLFFIXosqdguJU,420
|
|
2
2
|
glaip_sdk/_version.py,sha256=5CHGCxx_36fgmMWuEx6jJ2CzzM-i9eBFyQWFwBi23XE,2259
|
|
3
3
|
glaip_sdk/agents/__init__.py,sha256=VfYov56edbWuySXFEbWJ_jLXgwnFzPk1KB-9-mfsUCc,776
|
|
4
|
-
glaip_sdk/agents/base.py,sha256=
|
|
4
|
+
glaip_sdk/agents/base.py,sha256=asXkYyOiaeqqzsOk_FoFXbECBozyy7rfxgr9h0iliKc,36060
|
|
5
5
|
glaip_sdk/branding.py,sha256=tLqYCIHMkUf8p2smpuAGNptwaKUN38G4mlh0A0DOl_w,7823
|
|
6
6
|
glaip_sdk/cli/__init__.py,sha256=xCCfuF1Yc7mpCDcfhHZTX0vizvtrDSLeT8MJ3V7m5A0,156
|
|
7
7
|
glaip_sdk/cli/account_store.py,sha256=NXuAVPaJS_32Aw1VTaZCNwIID-gADw4F_UMieoWmg3g,17336
|
|
@@ -57,7 +57,7 @@ glaip_sdk/cli/validators.py,sha256=d-kq4y7HWMo6Gc7wLXWUsCt8JwFvJX_roZqRm1Nko1I,5
|
|
|
57
57
|
glaip_sdk/client/__init__.py,sha256=F-eE_dRSzA0cc1it06oi0tZetZBHmSUjWSHGhJMLCls,263
|
|
58
58
|
glaip_sdk/client/_agent_payloads.py,sha256=cH7CvNRn0JvudwKLr072E7W2QGWO9r-4xDxWMvXoPKE,17865
|
|
59
59
|
glaip_sdk/client/agent_runs.py,sha256=tZSFEZZ3Yx0uYRgnwkLe-X0TlmgKJQ-ivzb6SrVnxY8,4862
|
|
60
|
-
glaip_sdk/client/agents.py,sha256=
|
|
60
|
+
glaip_sdk/client/agents.py,sha256=33Wr5BYLN6uSN_Vwdine-9KKT030nDnsEArytN9g0lc,47580
|
|
61
61
|
glaip_sdk/client/base.py,sha256=BhNaC2TJJ2jVWRTYmfxD3WjYgAyIuWNz9YURdNXXjJo,18245
|
|
62
62
|
glaip_sdk/client/main.py,sha256=RTREAOgGouYm4lFKkpNBQ9dmxalnBsIpSSaQLWVFSmU,9054
|
|
63
63
|
glaip_sdk/client/mcps.py,sha256=gFRuLOGeh6ieIhR4PeD6yNVT6NhvUMTqPq9iuu1vkAY,13019
|
|
@@ -130,10 +130,11 @@ glaip_sdk/utils/rendering/viewer/__init__.py,sha256=XrxmE2cMAozqrzo1jtDFm8HqNtvD
|
|
|
130
130
|
glaip_sdk/utils/rendering/viewer/presenter.py,sha256=mlLMTjnyeyPVtsyrAbz1BJu9lFGQSlS-voZ-_Cuugv0,5725
|
|
131
131
|
glaip_sdk/utils/resource_refs.py,sha256=vF34kyAtFBLnaKnQVrsr2st1JiSxVbIZ4yq0DelJvCI,5966
|
|
132
132
|
glaip_sdk/utils/run_renderer.py,sha256=d_VMI6LbvHPUUeRmGqh5wK_lHqDEIAcym2iqpbtDad0,1365
|
|
133
|
+
glaip_sdk/utils/runtime_config.py,sha256=Y6frWR_PjD3CV2Jl3AqKxhhsJCkrxSuX27jw0-2aX2M,10124
|
|
133
134
|
glaip_sdk/utils/serialization.py,sha256=z-qpvWLSBrGK3wbUclcA1UIKLXJedTnMSwPdq-FF4lo,13308
|
|
134
135
|
glaip_sdk/utils/sync.py,sha256=3VKqs1UfNGWSobgRXohBKP7mMMzdUW3SU0bJQ1uxOgw,4872
|
|
135
136
|
glaip_sdk/utils/validation.py,sha256=Vt8oSnn7OM6ns5vjOl5FwGIMWBPb0yI6RD5XL_L5_4M,6826
|
|
136
|
-
glaip_sdk-0.6.
|
|
137
|
-
glaip_sdk-0.6.
|
|
138
|
-
glaip_sdk-0.6.
|
|
139
|
-
glaip_sdk-0.6.
|
|
137
|
+
glaip_sdk-0.6.2.dist-info/METADATA,sha256=i9j_B_1f1ONjg6yRh_pcA8ZRqkhl9ZJ-V1JecnRTUOw,7128
|
|
138
|
+
glaip_sdk-0.6.2.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
139
|
+
glaip_sdk-0.6.2.dist-info/entry_points.txt,sha256=EGs8NO8J1fdFMWA3CsF7sKBEvtHb_fujdCoNPhfMouE,47
|
|
140
|
+
glaip_sdk-0.6.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|