glaip-sdk 0.1.0__py3-none-any.whl → 0.6.10__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 +5 -2
- glaip_sdk/_version.py +10 -3
- glaip_sdk/agents/__init__.py +27 -0
- glaip_sdk/agents/base.py +1191 -0
- glaip_sdk/branding.py +15 -6
- glaip_sdk/cli/account_store.py +540 -0
- glaip_sdk/cli/agent_config.py +2 -6
- glaip_sdk/cli/auth.py +265 -45
- glaip_sdk/cli/commands/__init__.py +2 -2
- glaip_sdk/cli/commands/accounts.py +746 -0
- glaip_sdk/cli/commands/agents.py +251 -173
- glaip_sdk/cli/commands/common_config.py +101 -0
- glaip_sdk/cli/commands/configure.py +735 -143
- glaip_sdk/cli/commands/mcps.py +266 -134
- glaip_sdk/cli/commands/models.py +13 -9
- glaip_sdk/cli/commands/tools.py +67 -88
- glaip_sdk/cli/commands/transcripts.py +755 -0
- glaip_sdk/cli/commands/update.py +3 -8
- glaip_sdk/cli/config.py +49 -7
- glaip_sdk/cli/constants.py +38 -0
- glaip_sdk/cli/context.py +8 -0
- glaip_sdk/cli/core/__init__.py +79 -0
- glaip_sdk/cli/core/context.py +124 -0
- glaip_sdk/cli/core/output.py +846 -0
- glaip_sdk/cli/core/prompting.py +649 -0
- glaip_sdk/cli/core/rendering.py +187 -0
- glaip_sdk/cli/display.py +45 -32
- glaip_sdk/cli/hints.py +57 -0
- glaip_sdk/cli/io.py +14 -17
- glaip_sdk/cli/main.py +232 -143
- glaip_sdk/cli/masking.py +21 -33
- glaip_sdk/cli/mcp_validators.py +5 -15
- glaip_sdk/cli/pager.py +12 -19
- glaip_sdk/cli/parsers/__init__.py +1 -3
- glaip_sdk/cli/parsers/json_input.py +11 -22
- glaip_sdk/cli/resolution.py +3 -9
- glaip_sdk/cli/rich_helpers.py +1 -3
- glaip_sdk/cli/slash/__init__.py +0 -9
- glaip_sdk/cli/slash/accounts_controller.py +578 -0
- glaip_sdk/cli/slash/accounts_shared.py +75 -0
- glaip_sdk/cli/slash/agent_session.py +65 -29
- glaip_sdk/cli/slash/prompt.py +24 -10
- glaip_sdk/cli/slash/remote_runs_controller.py +566 -0
- glaip_sdk/cli/slash/session.py +807 -225
- glaip_sdk/cli/slash/tui/__init__.py +9 -0
- glaip_sdk/cli/slash/tui/accounts.tcss +86 -0
- glaip_sdk/cli/slash/tui/accounts_app.py +876 -0
- glaip_sdk/cli/slash/tui/background_tasks.py +72 -0
- glaip_sdk/cli/slash/tui/loading.py +58 -0
- glaip_sdk/cli/slash/tui/remote_runs_app.py +628 -0
- glaip_sdk/cli/transcript/__init__.py +12 -52
- glaip_sdk/cli/transcript/cache.py +258 -60
- glaip_sdk/cli/transcript/capture.py +72 -21
- glaip_sdk/cli/transcript/history.py +815 -0
- glaip_sdk/cli/transcript/launcher.py +1 -3
- glaip_sdk/cli/transcript/viewer.py +79 -499
- glaip_sdk/cli/update_notifier.py +177 -24
- glaip_sdk/cli/utils.py +242 -1308
- glaip_sdk/cli/validators.py +16 -18
- glaip_sdk/client/__init__.py +2 -1
- glaip_sdk/client/_agent_payloads.py +53 -37
- glaip_sdk/client/agent_runs.py +147 -0
- glaip_sdk/client/agents.py +320 -92
- glaip_sdk/client/base.py +78 -35
- glaip_sdk/client/main.py +19 -10
- glaip_sdk/client/mcps.py +123 -15
- glaip_sdk/client/run_rendering.py +136 -101
- glaip_sdk/client/shared.py +21 -0
- glaip_sdk/client/tools.py +163 -34
- glaip_sdk/client/validators.py +20 -48
- glaip_sdk/config/constants.py +11 -0
- glaip_sdk/exceptions.py +1 -3
- glaip_sdk/mcps/__init__.py +21 -0
- glaip_sdk/mcps/base.py +345 -0
- glaip_sdk/models/__init__.py +90 -0
- glaip_sdk/models/agent.py +47 -0
- glaip_sdk/models/agent_runs.py +116 -0
- glaip_sdk/models/common.py +42 -0
- glaip_sdk/models/mcp.py +33 -0
- glaip_sdk/models/tool.py +33 -0
- glaip_sdk/payload_schemas/__init__.py +1 -13
- glaip_sdk/payload_schemas/agent.py +1 -3
- glaip_sdk/registry/__init__.py +55 -0
- glaip_sdk/registry/agent.py +164 -0
- glaip_sdk/registry/base.py +139 -0
- glaip_sdk/registry/mcp.py +253 -0
- glaip_sdk/registry/tool.py +232 -0
- glaip_sdk/rich_components.py +58 -2
- glaip_sdk/runner/__init__.py +59 -0
- glaip_sdk/runner/base.py +84 -0
- glaip_sdk/runner/deps.py +115 -0
- glaip_sdk/runner/langgraph.py +706 -0
- glaip_sdk/runner/mcp_adapter/__init__.py +13 -0
- glaip_sdk/runner/mcp_adapter/base_mcp_adapter.py +43 -0
- glaip_sdk/runner/mcp_adapter/langchain_mcp_adapter.py +257 -0
- glaip_sdk/runner/mcp_adapter/mcp_config_builder.py +95 -0
- glaip_sdk/runner/tool_adapter/__init__.py +18 -0
- glaip_sdk/runner/tool_adapter/base_tool_adapter.py +44 -0
- glaip_sdk/runner/tool_adapter/langchain_tool_adapter.py +219 -0
- glaip_sdk/tools/__init__.py +22 -0
- glaip_sdk/tools/base.py +435 -0
- glaip_sdk/utils/__init__.py +58 -12
- glaip_sdk/utils/a2a/__init__.py +34 -0
- glaip_sdk/utils/a2a/event_processor.py +188 -0
- glaip_sdk/utils/agent_config.py +4 -14
- glaip_sdk/utils/bundler.py +267 -0
- glaip_sdk/utils/client.py +111 -0
- glaip_sdk/utils/client_utils.py +46 -28
- glaip_sdk/utils/datetime_helpers.py +58 -0
- glaip_sdk/utils/discovery.py +78 -0
- glaip_sdk/utils/display.py +25 -21
- glaip_sdk/utils/export.py +143 -0
- glaip_sdk/utils/general.py +1 -36
- glaip_sdk/utils/import_export.py +15 -16
- glaip_sdk/utils/import_resolver.py +492 -0
- glaip_sdk/utils/instructions.py +101 -0
- glaip_sdk/utils/rendering/__init__.py +115 -1
- glaip_sdk/utils/rendering/formatting.py +7 -35
- glaip_sdk/utils/rendering/layout/__init__.py +64 -0
- glaip_sdk/utils/rendering/{renderer → layout}/panels.py +10 -3
- glaip_sdk/utils/rendering/{renderer → layout}/progress.py +73 -12
- glaip_sdk/utils/rendering/layout/summary.py +74 -0
- glaip_sdk/utils/rendering/layout/transcript.py +606 -0
- glaip_sdk/utils/rendering/models.py +3 -6
- glaip_sdk/utils/rendering/renderer/__init__.py +9 -49
- glaip_sdk/utils/rendering/renderer/base.py +258 -1577
- glaip_sdk/utils/rendering/renderer/config.py +1 -5
- glaip_sdk/utils/rendering/renderer/debug.py +30 -34
- glaip_sdk/utils/rendering/renderer/factory.py +138 -0
- glaip_sdk/utils/rendering/renderer/stream.py +10 -51
- glaip_sdk/utils/rendering/renderer/summary_window.py +79 -0
- glaip_sdk/utils/rendering/renderer/thinking.py +273 -0
- glaip_sdk/utils/rendering/renderer/toggle.py +1 -3
- glaip_sdk/utils/rendering/renderer/tool_panels.py +442 -0
- glaip_sdk/utils/rendering/renderer/transcript_mode.py +162 -0
- glaip_sdk/utils/rendering/state.py +204 -0
- glaip_sdk/utils/rendering/step_tree_state.py +1 -3
- glaip_sdk/utils/rendering/steps/__init__.py +34 -0
- glaip_sdk/utils/rendering/{steps.py → steps/event_processor.py} +76 -517
- glaip_sdk/utils/rendering/steps/format.py +176 -0
- glaip_sdk/utils/rendering/steps/manager.py +387 -0
- glaip_sdk/utils/rendering/timing.py +36 -0
- glaip_sdk/utils/rendering/viewer/__init__.py +21 -0
- glaip_sdk/utils/rendering/viewer/presenter.py +184 -0
- glaip_sdk/utils/resource_refs.py +29 -26
- glaip_sdk/utils/runtime_config.py +425 -0
- glaip_sdk/utils/serialization.py +32 -46
- glaip_sdk/utils/sync.py +142 -0
- glaip_sdk/utils/tool_detection.py +33 -0
- glaip_sdk/utils/validation.py +20 -28
- {glaip_sdk-0.1.0.dist-info → glaip_sdk-0.6.10.dist-info}/METADATA +42 -4
- glaip_sdk-0.6.10.dist-info/RECORD +159 -0
- {glaip_sdk-0.1.0.dist-info → glaip_sdk-0.6.10.dist-info}/WHEEL +1 -1
- glaip_sdk/models.py +0 -259
- glaip_sdk-0.1.0.dist-info/RECORD +0 -82
- {glaip_sdk-0.1.0.dist-info → glaip_sdk-0.6.10.dist-info}/entry_points.txt +0 -0
glaip_sdk/cli/commands/models.py
CHANGED
|
@@ -12,9 +12,8 @@ from rich.console import Console
|
|
|
12
12
|
from glaip_sdk.branding import ACCENT_STYLE, INFO, SUCCESS
|
|
13
13
|
from glaip_sdk.cli.context import output_flags
|
|
14
14
|
from glaip_sdk.cli.utils import (
|
|
15
|
-
get_client,
|
|
16
15
|
output_list,
|
|
17
|
-
|
|
16
|
+
with_client_and_spinner,
|
|
18
17
|
)
|
|
19
18
|
|
|
20
19
|
console = Console()
|
|
@@ -32,12 +31,11 @@ def models_group() -> None:
|
|
|
32
31
|
def list_models(ctx: Any) -> None:
|
|
33
32
|
"""List available language models."""
|
|
34
33
|
try:
|
|
35
|
-
|
|
36
|
-
with spinner_context(
|
|
34
|
+
with with_client_and_spinner(
|
|
37
35
|
ctx,
|
|
38
36
|
"[bold blue]Fetching language models…[/bold blue]",
|
|
39
37
|
console_override=console,
|
|
40
|
-
):
|
|
38
|
+
) as client:
|
|
41
39
|
models = client.list_language_models()
|
|
42
40
|
|
|
43
41
|
# Define table columns: (data_key, header, style, width)
|
|
@@ -50,6 +48,14 @@ def list_models(ctx: Any) -> None:
|
|
|
50
48
|
|
|
51
49
|
# Transform function for safe dictionary access
|
|
52
50
|
def transform_model(model: dict[str, Any]) -> dict[str, Any]:
|
|
51
|
+
"""Transform a model dictionary to a display row dictionary.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
model: Model dictionary to transform.
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
Dictionary with id, provider, name, and base_url fields.
|
|
58
|
+
"""
|
|
53
59
|
return {
|
|
54
60
|
"id": str(model.get("id", "N/A")),
|
|
55
61
|
"provider": model.get("provider", "N/A"),
|
|
@@ -57,9 +63,7 @@ def list_models(ctx: Any) -> None:
|
|
|
57
63
|
"base_url": model.get("base_url", "Default") or "Default",
|
|
58
64
|
}
|
|
59
65
|
|
|
60
|
-
output_list(
|
|
61
|
-
ctx, models, "🧠 Available Language Models", columns, transform_model
|
|
62
|
-
)
|
|
66
|
+
output_list(ctx, models, "🧠 Available Language Models", columns, transform_model)
|
|
63
67
|
|
|
64
68
|
except Exception as e:
|
|
65
|
-
raise click.ClickException(str(e))
|
|
69
|
+
raise click.ClickException(str(e)) from e
|
glaip_sdk/cli/commands/tools.py
CHANGED
|
@@ -10,8 +10,6 @@ from pathlib import Path
|
|
|
10
10
|
from typing import Any
|
|
11
11
|
|
|
12
12
|
import click
|
|
13
|
-
from rich.console import Console
|
|
14
|
-
|
|
15
13
|
from glaip_sdk.branding import (
|
|
16
14
|
ACCENT_STYLE,
|
|
17
15
|
ERROR_STYLE,
|
|
@@ -19,7 +17,7 @@ from glaip_sdk.branding import (
|
|
|
19
17
|
SUCCESS_STYLE,
|
|
20
18
|
WARNING_STYLE,
|
|
21
19
|
)
|
|
22
|
-
from glaip_sdk.cli.context import
|
|
20
|
+
from glaip_sdk.cli.context import get_ctx_value, output_flags
|
|
23
21
|
from glaip_sdk.cli.display import (
|
|
24
22
|
display_api_error,
|
|
25
23
|
display_confirmation_prompt,
|
|
@@ -29,12 +27,7 @@ from glaip_sdk.cli.display import (
|
|
|
29
27
|
handle_json_output,
|
|
30
28
|
handle_rich_output,
|
|
31
29
|
)
|
|
32
|
-
from glaip_sdk.cli.io import
|
|
33
|
-
export_resource_to_file_with_validation as export_resource_to_file,
|
|
34
|
-
)
|
|
35
|
-
from glaip_sdk.cli.io import (
|
|
36
|
-
fetch_raw_resource_details,
|
|
37
|
-
)
|
|
30
|
+
from glaip_sdk.cli.io import fetch_raw_resource_details
|
|
38
31
|
from glaip_sdk.cli.io import (
|
|
39
32
|
load_resource_from_file_with_validation as load_resource_from_file,
|
|
40
33
|
)
|
|
@@ -42,14 +35,17 @@ from glaip_sdk.cli.resolution import resolve_resource_reference
|
|
|
42
35
|
from glaip_sdk.cli.rich_helpers import markup_text, print_markup
|
|
43
36
|
from glaip_sdk.cli.utils import (
|
|
44
37
|
coerce_to_row,
|
|
38
|
+
format_datetime_fields,
|
|
45
39
|
get_client,
|
|
40
|
+
handle_best_effort_check,
|
|
41
|
+
handle_resource_export,
|
|
46
42
|
output_list,
|
|
47
43
|
output_result,
|
|
48
44
|
spinner_context,
|
|
49
45
|
)
|
|
50
46
|
from glaip_sdk.icons import ICON_TOOL
|
|
51
|
-
from glaip_sdk.utils import format_datetime
|
|
52
47
|
from glaip_sdk.utils.import_export import merge_import_with_cli_args
|
|
48
|
+
from rich.console import Console
|
|
53
49
|
|
|
54
50
|
console = Console()
|
|
55
51
|
|
|
@@ -60,17 +56,32 @@ def tools_group() -> None:
|
|
|
60
56
|
pass
|
|
61
57
|
|
|
62
58
|
|
|
63
|
-
def _resolve_tool(
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
59
|
+
def _resolve_tool(ctx: Any, client: Any, ref: str, select: int | None = None) -> Any | None:
|
|
60
|
+
"""Resolve a tool by ID or name, handling ambiguous matches interactively.
|
|
61
|
+
|
|
62
|
+
This function provides tool-specific resolution logic. It uses
|
|
63
|
+
resolve_resource_reference to find tools by UUID or name, with interactive
|
|
64
|
+
selection when multiple matches are found.
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
ctx: Click context for CLI operations.
|
|
68
|
+
client: API client instance.
|
|
69
|
+
ref: Tool reference (UUID string or name).
|
|
70
|
+
select: Pre-selected index for non-interactive mode (1-based).
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
Tool object if found, None otherwise.
|
|
74
|
+
"""
|
|
75
|
+
# Configure tool-specific resolution with standard fuzzy matching
|
|
76
|
+
get_by_id = client.get_tool
|
|
77
|
+
find_by_name = client.find_tools
|
|
67
78
|
return resolve_resource_reference(
|
|
68
79
|
ctx,
|
|
69
80
|
client,
|
|
70
81
|
ref,
|
|
71
82
|
"tool",
|
|
72
|
-
|
|
73
|
-
|
|
83
|
+
get_by_id,
|
|
84
|
+
find_by_name,
|
|
74
85
|
"Tool",
|
|
75
86
|
select=select,
|
|
76
87
|
)
|
|
@@ -104,22 +115,20 @@ def _validate_name_match(provided: str | None, internal: str) -> str:
|
|
|
104
115
|
|
|
105
116
|
def _check_duplicate_name(client: Any, tool_name: str) -> None:
|
|
106
117
|
"""Raise if a tool with the same name already exists."""
|
|
107
|
-
|
|
118
|
+
|
|
119
|
+
def _check_duplicate() -> None:
|
|
108
120
|
existing = client.find_tools(name=tool_name)
|
|
109
121
|
if existing:
|
|
110
122
|
raise click.ClickException(
|
|
111
123
|
f"A tool named '{tool_name}' already exists. "
|
|
112
124
|
"Please change your plugin's 'name' to a unique value, then re-run."
|
|
113
125
|
)
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
raise
|
|
117
|
-
except Exception:
|
|
118
|
-
# Non-fatal: best-effort duplicate check for other errors
|
|
119
|
-
pass
|
|
126
|
+
|
|
127
|
+
handle_best_effort_check(_check_duplicate)
|
|
120
128
|
|
|
121
129
|
|
|
122
130
|
def _parse_tags(tags: str | None) -> list[str]:
|
|
131
|
+
"""Return a cleaned list of tag strings from a comma-separated input."""
|
|
123
132
|
return [t.strip() for t in (tags.split(",") if tags else []) if t.strip()]
|
|
124
133
|
|
|
125
134
|
|
|
@@ -181,9 +190,7 @@ def _validate_creation_parameters(
|
|
|
181
190
|
) -> None:
|
|
182
191
|
"""Validate required parameters for tool creation."""
|
|
183
192
|
if not file and not import_file:
|
|
184
|
-
raise click.ClickException(
|
|
185
|
-
"A tool file must be provided. Use --file to specify the tool file to upload."
|
|
186
|
-
)
|
|
193
|
+
raise click.ClickException("A tool file must be provided. Use --file to specify the tool file to upload.")
|
|
187
194
|
|
|
188
195
|
|
|
189
196
|
@tools_group.command(name="list")
|
|
@@ -216,6 +223,14 @@ def list_tools(ctx: Any, tool_type: str | None) -> None:
|
|
|
216
223
|
|
|
217
224
|
# Transform function for safe dictionary access
|
|
218
225
|
def transform_tool(tool: Any) -> dict[str, Any]:
|
|
226
|
+
"""Transform a tool object to a display row dictionary.
|
|
227
|
+
|
|
228
|
+
Args:
|
|
229
|
+
tool: Tool object to transform.
|
|
230
|
+
|
|
231
|
+
Returns:
|
|
232
|
+
Dictionary with id, name, and framework fields.
|
|
233
|
+
"""
|
|
219
234
|
row = coerce_to_row(tool, ["id", "name", "framework"])
|
|
220
235
|
# Ensure id is always a string
|
|
221
236
|
row["id"] = str(row["id"])
|
|
@@ -224,7 +239,7 @@ def list_tools(ctx: Any, tool_type: str | None) -> None:
|
|
|
224
239
|
output_list(ctx, tools, f"{ICON_TOOL} Available Tools", columns, transform_tool)
|
|
225
240
|
|
|
226
241
|
except Exception as e:
|
|
227
|
-
raise click.ClickException(str(e))
|
|
242
|
+
raise click.ClickException(str(e)) from e
|
|
228
243
|
|
|
229
244
|
|
|
230
245
|
@tools_group.command()
|
|
@@ -263,8 +278,9 @@ def create(
|
|
|
263
278
|
tags: tuple[str, ...] | None,
|
|
264
279
|
import_file: str | None,
|
|
265
280
|
) -> None:
|
|
266
|
-
"""Create a new tool.
|
|
281
|
+
r"""Create a new tool.
|
|
267
282
|
|
|
283
|
+
\b
|
|
268
284
|
Examples:
|
|
269
285
|
aip tools create tool.py # Create from file
|
|
270
286
|
aip tools create --import tool.json # Create from exported configuration
|
|
@@ -315,7 +331,7 @@ def create(
|
|
|
315
331
|
handle_json_output(ctx, error=e)
|
|
316
332
|
if get_ctx_value(ctx, "view") != "json":
|
|
317
333
|
display_api_error(e, "tool creation")
|
|
318
|
-
raise click.ClickException(str(e))
|
|
334
|
+
raise click.ClickException(str(e)) from e
|
|
319
335
|
|
|
320
336
|
|
|
321
337
|
@tools_group.command()
|
|
@@ -329,8 +345,9 @@ def create(
|
|
|
329
345
|
@output_flags()
|
|
330
346
|
@click.pass_context
|
|
331
347
|
def get(ctx: Any, tool_ref: str, select: int | None, export: str | None) -> None:
|
|
332
|
-
"""Get tool details.
|
|
348
|
+
r"""Get tool details.
|
|
333
349
|
|
|
350
|
+
\b
|
|
334
351
|
Examples:
|
|
335
352
|
aip tools get my-tool
|
|
336
353
|
aip tools get my-tool --export tool.json # Exports complete configuration as JSON
|
|
@@ -344,37 +361,13 @@ def get(ctx: Any, tool_ref: str, select: int | None, export: str | None) -> None
|
|
|
344
361
|
|
|
345
362
|
# Handle export option
|
|
346
363
|
if export:
|
|
347
|
-
|
|
348
|
-
# Auto-detect format from file extension
|
|
349
|
-
detected_format = detect_export_format(export_path)
|
|
350
|
-
|
|
351
|
-
# Always export comprehensive data - re-fetch tool with full details if needed
|
|
352
|
-
try:
|
|
353
|
-
with spinner_context(
|
|
354
|
-
ctx,
|
|
355
|
-
"[bold blue]Fetching complete tool details…[/bold blue]",
|
|
356
|
-
console_override=console,
|
|
357
|
-
):
|
|
358
|
-
tool = client.get_tool_by_id(tool.id)
|
|
359
|
-
except Exception as e:
|
|
360
|
-
print_markup(
|
|
361
|
-
f"[{WARNING_STYLE}]⚠️ Could not fetch full tool details: {e}[/]",
|
|
362
|
-
console=console,
|
|
363
|
-
)
|
|
364
|
-
print_markup(
|
|
365
|
-
f"[{WARNING_STYLE}]⚠️ Proceeding with available data[/]",
|
|
366
|
-
console=console,
|
|
367
|
-
)
|
|
368
|
-
|
|
369
|
-
with spinner_context(
|
|
364
|
+
handle_resource_export(
|
|
370
365
|
ctx,
|
|
371
|
-
|
|
366
|
+
tool,
|
|
367
|
+
Path(export),
|
|
368
|
+
resource_type="tool",
|
|
369
|
+
get_by_id_func=client.get_tool_by_id,
|
|
372
370
|
console_override=console,
|
|
373
|
-
):
|
|
374
|
-
export_resource_to_file(tool, export_path, detected_format)
|
|
375
|
-
print_markup(
|
|
376
|
-
f"[{SUCCESS_STYLE}]✅ Complete tool configuration exported to: {export_path} (format: {detected_format})[/]",
|
|
377
|
-
console=console,
|
|
378
371
|
)
|
|
379
372
|
|
|
380
373
|
# Try to fetch raw API data first to preserve ALL fields
|
|
@@ -388,15 +381,7 @@ def get(ctx: Any, tool_ref: str, select: int | None, export: str | None) -> None
|
|
|
388
381
|
if raw_tool_data:
|
|
389
382
|
# Use raw API data - this preserves ALL fields
|
|
390
383
|
# Format dates for better display (minimal postprocessing)
|
|
391
|
-
formatted_data = raw_tool_data
|
|
392
|
-
if "created_at" in formatted_data:
|
|
393
|
-
formatted_data["created_at"] = format_datetime(
|
|
394
|
-
formatted_data["created_at"]
|
|
395
|
-
)
|
|
396
|
-
if "updated_at" in formatted_data:
|
|
397
|
-
formatted_data["updated_at"] = format_datetime(
|
|
398
|
-
formatted_data["updated_at"]
|
|
399
|
-
)
|
|
384
|
+
formatted_data = format_datetime_fields(raw_tool_data)
|
|
400
385
|
|
|
401
386
|
# Display using output_result with raw data
|
|
402
387
|
output_result(
|
|
@@ -427,7 +412,7 @@ def get(ctx: Any, tool_ref: str, select: int | None, export: str | None) -> None
|
|
|
427
412
|
)
|
|
428
413
|
|
|
429
414
|
except Exception as e:
|
|
430
|
-
raise click.ClickException(str(e))
|
|
415
|
+
raise click.ClickException(str(e)) from e
|
|
431
416
|
|
|
432
417
|
|
|
433
418
|
@tools_group.command()
|
|
@@ -461,7 +446,7 @@ def update(
|
|
|
461
446
|
):
|
|
462
447
|
tool = client.get_tool_by_id(tool_id)
|
|
463
448
|
except Exception as e:
|
|
464
|
-
raise click.ClickException(f"Tool with ID '{tool_id}' not found: {e}")
|
|
449
|
+
raise click.ClickException(f"Tool with ID '{tool_id}' not found: {e}") from e
|
|
465
450
|
|
|
466
451
|
# Prepare update data
|
|
467
452
|
update_data = {}
|
|
@@ -474,16 +459,15 @@ def update(
|
|
|
474
459
|
# Update code via file upload (custom tools only)
|
|
475
460
|
if tool.tool_type != "custom":
|
|
476
461
|
raise click.ClickException(
|
|
477
|
-
|
|
462
|
+
"File updates are only supported for custom tools. "
|
|
463
|
+
f"Tool '{tool.name}' is of type '{tool.tool_type}'."
|
|
478
464
|
)
|
|
479
465
|
with spinner_context(
|
|
480
466
|
ctx,
|
|
481
467
|
"[bold blue]Uploading new tool code…[/bold blue]",
|
|
482
468
|
console_override=console,
|
|
483
469
|
):
|
|
484
|
-
updated_tool = client.tools.update_tool_via_file(
|
|
485
|
-
tool.id, file, framework=tool.framework
|
|
486
|
-
)
|
|
470
|
+
updated_tool = client.tools.update_tool_via_file(tool.id, file, framework=tool.framework)
|
|
487
471
|
handle_rich_output(
|
|
488
472
|
ctx,
|
|
489
473
|
markup_text(f"[{SUCCESS_STYLE}]✓[/] Tool code updated from {file}"),
|
|
@@ -492,7 +476,8 @@ def update(
|
|
|
492
476
|
# Update metadata only (native tools only)
|
|
493
477
|
if tool.tool_type != "native":
|
|
494
478
|
raise click.ClickException(
|
|
495
|
-
|
|
479
|
+
"Metadata updates are only supported for native tools. "
|
|
480
|
+
f"Tool '{tool.name}' is of type '{tool.tool_type}'."
|
|
496
481
|
)
|
|
497
482
|
with spinner_context(
|
|
498
483
|
ctx,
|
|
@@ -500,13 +485,9 @@ def update(
|
|
|
500
485
|
console_override=console,
|
|
501
486
|
):
|
|
502
487
|
updated_tool = tool.update(**update_data)
|
|
503
|
-
handle_rich_output(
|
|
504
|
-
ctx, markup_text(f"[{SUCCESS_STYLE}]✓[/] Tool metadata updated")
|
|
505
|
-
)
|
|
488
|
+
handle_rich_output(ctx, markup_text(f"[{SUCCESS_STYLE}]✓[/] Tool metadata updated"))
|
|
506
489
|
else:
|
|
507
|
-
handle_rich_output(
|
|
508
|
-
ctx, markup_text(f"[{WARNING_STYLE}]No updates specified[/]")
|
|
509
|
-
)
|
|
490
|
+
handle_rich_output(ctx, markup_text(f"[{WARNING_STYLE}]No updates specified[/]"))
|
|
510
491
|
return
|
|
511
492
|
|
|
512
493
|
handle_json_output(ctx, updated_tool.model_dump())
|
|
@@ -516,7 +497,7 @@ def update(
|
|
|
516
497
|
handle_json_output(ctx, error=e)
|
|
517
498
|
if get_ctx_value(ctx, "view") != "json":
|
|
518
499
|
display_api_error(e, "tool update")
|
|
519
|
-
raise click.ClickException(str(e))
|
|
500
|
+
raise click.ClickException(str(e)) from e
|
|
520
501
|
|
|
521
502
|
|
|
522
503
|
@tools_group.command()
|
|
@@ -538,7 +519,7 @@ def delete(ctx: Any, tool_id: str, yes: bool) -> None:
|
|
|
538
519
|
):
|
|
539
520
|
tool = client.get_tool_by_id(tool_id)
|
|
540
521
|
except Exception as e:
|
|
541
|
-
raise click.ClickException(f"Tool with ID '{tool_id}' not found: {e}")
|
|
522
|
+
raise click.ClickException(f"Tool with ID '{tool_id}' not found: {e}") from e
|
|
542
523
|
|
|
543
524
|
# Confirm deletion via centralized display helper
|
|
544
525
|
if not yes and not display_confirmation_prompt("Tool", tool.name):
|
|
@@ -564,7 +545,7 @@ def delete(ctx: Any, tool_id: str, yes: bool) -> None:
|
|
|
564
545
|
handle_json_output(ctx, error=e)
|
|
565
546
|
if get_ctx_value(ctx, "view") != "json":
|
|
566
547
|
display_api_error(e, "tool deletion")
|
|
567
|
-
raise click.ClickException(str(e))
|
|
548
|
+
raise click.ClickException(str(e)) from e
|
|
568
549
|
|
|
569
550
|
|
|
570
551
|
@tools_group.command("script")
|
|
@@ -591,7 +572,5 @@ def script(ctx: Any, tool_id: str) -> None:
|
|
|
591
572
|
except Exception as e:
|
|
592
573
|
handle_json_output(ctx, error=e)
|
|
593
574
|
if get_ctx_value(ctx, "view") != "json":
|
|
594
|
-
print_markup(
|
|
595
|
-
|
|
596
|
-
)
|
|
597
|
-
raise click.ClickException(str(e))
|
|
575
|
+
print_markup(f"[{ERROR_STYLE}]Error getting tool script: {e}[/]", console=console)
|
|
576
|
+
raise click.ClickException(str(e)) from e
|