glaip-sdk 0.6.19__py3-none-any.whl → 0.7.27__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 +283 -30
- glaip_sdk/agents/component.py +233 -0
- 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 +116 -0
- glaip_sdk/cli/commands/agents/_common.py +562 -0
- glaip_sdk/cli/commands/agents/create.py +155 -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 +1 -1
- glaip_sdk/cli/commands/configure.py +1 -2
- 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/entrypoint.py +20 -0
- glaip_sdk/cli/main.py +112 -35
- glaip_sdk/cli/pager.py +3 -3
- glaip_sdk/cli/resolution.py +2 -1
- glaip_sdk/cli/slash/accounts_controller.py +3 -1
- glaip_sdk/cli/slash/agent_session.py +1 -1
- glaip_sdk/cli/slash/remote_runs_controller.py +3 -1
- glaip_sdk/cli/slash/session.py +343 -20
- glaip_sdk/cli/slash/tui/__init__.py +29 -1
- glaip_sdk/cli/slash/tui/accounts.tcss +97 -6
- glaip_sdk/cli/slash/tui/accounts_app.py +1117 -126
- glaip_sdk/cli/slash/tui/clipboard.py +316 -0
- glaip_sdk/cli/slash/tui/context.py +92 -0
- glaip_sdk/cli/slash/tui/indicators.py +341 -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 +184 -0
- glaip_sdk/cli/slash/tui/loading.py +43 -21
- glaip_sdk/cli/slash/tui/remote_runs_app.py +178 -20
- 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 +388 -0
- glaip_sdk/cli/transcript/history.py +1 -1
- glaip_sdk/cli/transcript/viewer.py +1 -1
- 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 +293 -17
- glaip_sdk/client/base.py +25 -0
- glaip_sdk/client/hitl.py +136 -0
- glaip_sdk/client/main.py +7 -5
- 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} +28 -48
- glaip_sdk/client/payloads/agent/responses.py +43 -0
- glaip_sdk/client/run_rendering.py +109 -30
- glaip_sdk/client/schedules.py +439 -0
- glaip_sdk/client/tools.py +52 -23
- glaip_sdk/config/constants.py +22 -2
- glaip_sdk/guardrails/__init__.py +80 -0
- glaip_sdk/guardrails/serializer.py +91 -0
- glaip_sdk/hitl/__init__.py +35 -2
- glaip_sdk/hitl/base.py +64 -0
- glaip_sdk/hitl/callback.py +43 -0
- glaip_sdk/hitl/local.py +1 -31
- glaip_sdk/hitl/remote.py +523 -0
- glaip_sdk/models/__init__.py +47 -1
- glaip_sdk/models/_provider_mappings.py +101 -0
- glaip_sdk/models/_validation.py +97 -0
- glaip_sdk/models/agent.py +2 -1
- glaip_sdk/models/agent_runs.py +2 -1
- glaip_sdk/models/constants.py +141 -0
- glaip_sdk/models/model.py +170 -0
- 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/ptc.py +145 -0
- glaip_sdk/registry/tool.py +270 -57
- glaip_sdk/runner/__init__.py +20 -3
- glaip_sdk/runner/deps.py +4 -1
- glaip_sdk/runner/langgraph.py +251 -27
- glaip_sdk/runner/logging_config.py +77 -0
- glaip_sdk/runner/mcp_adapter/mcp_config_builder.py +30 -9
- glaip_sdk/runner/ptc_adapter.py +98 -0
- glaip_sdk/runner/tool_adapter/langchain_tool_adapter.py +25 -2
- 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/agent_config.py +8 -2
- glaip_sdk/utils/bundler.py +138 -2
- glaip_sdk/utils/import_resolver.py +427 -49
- glaip_sdk/utils/runtime_config.py +3 -2
- glaip_sdk/utils/sync.py +31 -11
- glaip_sdk/utils/tool_detection.py +274 -6
- {glaip_sdk-0.6.19.dist-info → glaip_sdk-0.7.27.dist-info}/METADATA +22 -8
- glaip_sdk-0.7.27.dist-info/RECORD +227 -0
- {glaip_sdk-0.6.19.dist-info → glaip_sdk-0.7.27.dist-info}/WHEEL +1 -1
- glaip_sdk-0.7.27.dist-info/entry_points.txt +2 -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.19.dist-info/RECORD +0 -163
- glaip_sdk-0.6.19.dist-info/entry_points.txt +0 -2
- {glaip_sdk-0.6.19.dist-info → glaip_sdk-0.7.27.dist-info}/top_level.txt +0 -0
glaip_sdk/utils/bundler.py
CHANGED
|
@@ -14,6 +14,7 @@ import inspect
|
|
|
14
14
|
from pathlib import Path
|
|
15
15
|
|
|
16
16
|
from glaip_sdk.utils.import_resolver import ImportResolver
|
|
17
|
+
from glaip_sdk.utils.tool_detection import is_tool_plugin_decorator
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
class ToolBundler:
|
|
@@ -50,9 +51,14 @@ class ToolBundler:
|
|
|
50
51
|
self.tool_dir = self.tool_file.parent
|
|
51
52
|
self._import_resolver = ImportResolver(self.tool_dir)
|
|
52
53
|
|
|
53
|
-
def bundle(self) -> str:
|
|
54
|
+
def bundle(self, add_tool_plugin_decorator: bool = True) -> str:
|
|
54
55
|
"""Bundle tool source code with inlined local imports.
|
|
55
56
|
|
|
57
|
+
Args:
|
|
58
|
+
add_tool_plugin_decorator: If True, add @tool_plugin decorator to BaseTool classes.
|
|
59
|
+
Set to False for newer servers (0.1.85+) where decorator is optional.
|
|
60
|
+
Defaults to True for backward compatibility with older servers.
|
|
61
|
+
|
|
56
62
|
Returns:
|
|
57
63
|
Bundled source code with all local dependencies inlined.
|
|
58
64
|
"""
|
|
@@ -62,6 +68,16 @@ class ToolBundler:
|
|
|
62
68
|
tree = ast.parse(full_source)
|
|
63
69
|
local_imports, external_imports = self._import_resolver.categorize_imports(tree)
|
|
64
70
|
|
|
71
|
+
# NOTE: The @tool_plugin decorator is REQUIRED by older servers (< 0.1.85) for remote execution.
|
|
72
|
+
# Newer servers (0.1.85+) make the decorator optional.
|
|
73
|
+
# The server validates uploaded tool code and will reject tools without the decorator
|
|
74
|
+
# with error: "No classes found with @tool_plugin decorator".
|
|
75
|
+
# See: docs/resources/reference/schemas/tools.md - "Plugin Requirements"
|
|
76
|
+
# TESTED: Commenting out this decorator addition causes HTTP 400 ValidationError from older servers.
|
|
77
|
+
# We try without decorator first (for new servers), then retry with decorator if validation fails.
|
|
78
|
+
if add_tool_plugin_decorator:
|
|
79
|
+
self._add_tool_plugin_decorator(tree)
|
|
80
|
+
|
|
65
81
|
# Extract main code nodes (excluding imports, docstrings, glaip_sdk.Tool subclasses)
|
|
66
82
|
main_code_nodes = self._extract_main_code_nodes(tree)
|
|
67
83
|
|
|
@@ -71,6 +87,13 @@ class ToolBundler:
|
|
|
71
87
|
# Merge all external imports
|
|
72
88
|
all_external_imports = external_imports + inlined_external_imports
|
|
73
89
|
|
|
90
|
+
# NOTE: The gllm_plugin.tools import is REQUIRED when decorator is added.
|
|
91
|
+
# Without this import, the decorator will cause a NameError when the server executes the code.
|
|
92
|
+
# TESTED: Commenting out this import causes NameError when server tries to use the decorator.
|
|
93
|
+
# This import is added automatically during bundling so source files can remain clean.
|
|
94
|
+
if add_tool_plugin_decorator:
|
|
95
|
+
self._ensure_tool_plugin_import(all_external_imports)
|
|
96
|
+
|
|
74
97
|
# Build bundled code
|
|
75
98
|
bundled_code = ["# Bundled tool with inlined local imports\n"]
|
|
76
99
|
bundled_code.extend(self._import_resolver.format_external_imports(all_external_imports))
|
|
@@ -109,6 +132,103 @@ class ToolBundler:
|
|
|
109
132
|
main_code_nodes.append(ast.unparse(node))
|
|
110
133
|
return main_code_nodes
|
|
111
134
|
|
|
135
|
+
@staticmethod
|
|
136
|
+
def _add_tool_plugin_decorator(tree: ast.AST) -> None:
|
|
137
|
+
"""Add @tool_plugin decorator to BaseTool classes that don't have it.
|
|
138
|
+
|
|
139
|
+
This allows tools to be clean (without decorator) for local use,
|
|
140
|
+
while the decorator is automatically added during bundling for remote execution.
|
|
141
|
+
|
|
142
|
+
Args:
|
|
143
|
+
tree: AST tree to modify in-place.
|
|
144
|
+
"""
|
|
145
|
+
for node in ast.walk(tree):
|
|
146
|
+
if not isinstance(node, ast.ClassDef):
|
|
147
|
+
continue
|
|
148
|
+
|
|
149
|
+
if not ToolBundler._inherits_from_base_tool(node):
|
|
150
|
+
continue
|
|
151
|
+
|
|
152
|
+
if ToolBundler._has_tool_plugin_decorator(node):
|
|
153
|
+
continue
|
|
154
|
+
|
|
155
|
+
decorator_call = ToolBundler._create_tool_plugin_decorator()
|
|
156
|
+
node.decorator_list.insert(0, decorator_call)
|
|
157
|
+
|
|
158
|
+
@staticmethod
|
|
159
|
+
def _inherits_from_base_tool(class_node: ast.ClassDef) -> bool:
|
|
160
|
+
"""Check if a class inherits from BaseTool.
|
|
161
|
+
|
|
162
|
+
Args:
|
|
163
|
+
class_node: AST ClassDef node to check.
|
|
164
|
+
|
|
165
|
+
Returns:
|
|
166
|
+
True if class inherits from BaseTool.
|
|
167
|
+
"""
|
|
168
|
+
for base in class_node.bases:
|
|
169
|
+
if isinstance(base, ast.Name) and base.id == "BaseTool":
|
|
170
|
+
return True
|
|
171
|
+
if isinstance(base, ast.Attribute) and base.attr == "BaseTool":
|
|
172
|
+
# Handle nested attributes like langchain_core.tools.BaseTool
|
|
173
|
+
# Check if the value chain leads to langchain_core
|
|
174
|
+
value = base.value
|
|
175
|
+
while isinstance(value, ast.Attribute):
|
|
176
|
+
value = value.value
|
|
177
|
+
if isinstance(value, ast.Name) and value.id == "langchain_core":
|
|
178
|
+
return True
|
|
179
|
+
return False
|
|
180
|
+
|
|
181
|
+
@staticmethod
|
|
182
|
+
def _has_tool_plugin_decorator(class_node: ast.ClassDef) -> bool:
|
|
183
|
+
"""Check if a class already has the @tool_plugin decorator.
|
|
184
|
+
|
|
185
|
+
Args:
|
|
186
|
+
class_node: AST ClassDef node to check.
|
|
187
|
+
|
|
188
|
+
Returns:
|
|
189
|
+
True if decorator already exists.
|
|
190
|
+
"""
|
|
191
|
+
for decorator in class_node.decorator_list:
|
|
192
|
+
if is_tool_plugin_decorator(decorator):
|
|
193
|
+
return True
|
|
194
|
+
return False
|
|
195
|
+
|
|
196
|
+
@staticmethod
|
|
197
|
+
def _create_tool_plugin_decorator() -> ast.Call:
|
|
198
|
+
"""Create a @tool_plugin decorator AST node.
|
|
199
|
+
|
|
200
|
+
Returns:
|
|
201
|
+
AST Call node representing @tool_plugin(version="1.0.0").
|
|
202
|
+
"""
|
|
203
|
+
return ast.Call(
|
|
204
|
+
func=ast.Name(id="tool_plugin", ctx=ast.Load()),
|
|
205
|
+
args=[],
|
|
206
|
+
keywords=[ast.keyword(arg="version", value=ast.Constant(value="1.0.0"))],
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
@staticmethod
|
|
210
|
+
def _ensure_tool_plugin_import(external_imports: list) -> None:
|
|
211
|
+
"""Ensure gllm_plugin.tools import is present in external imports.
|
|
212
|
+
|
|
213
|
+
Args:
|
|
214
|
+
external_imports: List of external import nodes (modified in-place).
|
|
215
|
+
"""
|
|
216
|
+
# Check if import already exists
|
|
217
|
+
for import_node in external_imports:
|
|
218
|
+
if isinstance(import_node, ast.ImportFrom) and import_node.module == "gllm_plugin.tools":
|
|
219
|
+
# Check if tool_plugin is in the names
|
|
220
|
+
for alias in import_node.names:
|
|
221
|
+
if alias.name == "tool_plugin":
|
|
222
|
+
return # Import already present
|
|
223
|
+
|
|
224
|
+
# Add the import
|
|
225
|
+
import_node = ast.ImportFrom(
|
|
226
|
+
module="gllm_plugin.tools",
|
|
227
|
+
names=[ast.alias(name="tool_plugin")],
|
|
228
|
+
level=0,
|
|
229
|
+
)
|
|
230
|
+
external_imports.append(import_node)
|
|
231
|
+
|
|
112
232
|
@staticmethod
|
|
113
233
|
def _is_sdk_tool_subclass(node: ast.ClassDef) -> bool:
|
|
114
234
|
"""Check if AST class definition inherits from Tool.
|
|
@@ -135,7 +255,7 @@ class ToolBundler:
|
|
|
135
255
|
return False
|
|
136
256
|
|
|
137
257
|
@classmethod
|
|
138
|
-
def bundle_from_source(cls, file_path: Path) -> tuple[str, str, str]:
|
|
258
|
+
def bundle_from_source(cls, file_path: Path, add_tool_plugin_decorator: bool = True) -> tuple[str, str, str]:
|
|
139
259
|
"""Extract tool info directly from source file without importing.
|
|
140
260
|
|
|
141
261
|
This is used as a fallback when the tool class cannot be imported
|
|
@@ -143,6 +263,9 @@ class ToolBundler:
|
|
|
143
263
|
|
|
144
264
|
Args:
|
|
145
265
|
file_path: Path to the tool source file.
|
|
266
|
+
add_tool_plugin_decorator: If True, add @tool_plugin decorator to BaseTool classes.
|
|
267
|
+
Set to False for newer servers (0.1.85+) where decorator is optional.
|
|
268
|
+
Defaults to True for backward compatibility with older servers.
|
|
146
269
|
|
|
147
270
|
Returns:
|
|
148
271
|
Tuple of (name, description, bundled_source_code).
|
|
@@ -160,6 +283,12 @@ class ToolBundler:
|
|
|
160
283
|
tool_dir = file_path.parent
|
|
161
284
|
import_resolver = ImportResolver(tool_dir)
|
|
162
285
|
|
|
286
|
+
# NOTE: The @tool_plugin decorator is REQUIRED by older servers (< 0.1.85) for remote execution.
|
|
287
|
+
# Newer servers (0.1.85+) make the decorator optional.
|
|
288
|
+
# See bundle() method for detailed explanation.
|
|
289
|
+
if add_tool_plugin_decorator:
|
|
290
|
+
cls._add_tool_plugin_decorator(tree)
|
|
291
|
+
|
|
163
292
|
# Find tool name and description from class definitions
|
|
164
293
|
tool_name, tool_description = cls._extract_tool_metadata(tree, file_path.stem)
|
|
165
294
|
|
|
@@ -180,6 +309,13 @@ class ToolBundler:
|
|
|
180
309
|
|
|
181
310
|
# Build bundled code
|
|
182
311
|
all_external_imports = external_imports + inlined_external_imports
|
|
312
|
+
|
|
313
|
+
# NOTE: The gllm_plugin.tools import is REQUIRED when decorator is added.
|
|
314
|
+
# See bundle() method for detailed explanation.
|
|
315
|
+
# TESTED: Commenting out this import causes NameError when server tries to use the decorator.
|
|
316
|
+
if add_tool_plugin_decorator:
|
|
317
|
+
cls._ensure_tool_plugin_import(all_external_imports)
|
|
318
|
+
|
|
183
319
|
bundled_code = ["# Bundled tool with inlined local imports\n"]
|
|
184
320
|
bundled_code.extend(import_resolver.format_external_imports(all_external_imports))
|
|
185
321
|
|