glaip-sdk 0.6.5b3__py3-none-any.whl ā 0.7.17__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 +362 -39
- 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 +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 +375 -25
- glaip_sdk/cli/slash/tui/__init__.py +28 -1
- glaip_sdk/cli/slash/tui/accounts.tcss +97 -6
- glaip_sdk/cli/slash/tui/accounts_app.py +1107 -126
- glaip_sdk/cli/slash/tui/clipboard.py +195 -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 +152 -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 +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 +290 -16
- 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 +414 -3
- glaip_sdk/client/schedules.py +439 -0
- glaip_sdk/client/tools.py +57 -26
- glaip_sdk/config/constants.py +22 -2
- 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 +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/registry/tool.py +273 -66
- glaip_sdk/runner/__init__.py +76 -0
- glaip_sdk/runner/base.py +84 -0
- glaip_sdk/runner/deps.py +115 -0
- glaip_sdk/runner/langgraph.py +1055 -0
- glaip_sdk/runner/logging_config.py +77 -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 +116 -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 +242 -0
- 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/a2a/__init__.py +34 -0
- glaip_sdk/utils/a2a/event_processor.py +188 -0
- glaip_sdk/utils/agent_config.py +8 -2
- 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 +120 -0
- glaip_sdk/utils/sync.py +31 -11
- glaip_sdk/utils/tool_detection.py +301 -0
- glaip_sdk/utils/tool_storage_provider.py +140 -0
- {glaip_sdk-0.6.5b3.dist-info ā glaip_sdk-0.7.17.dist-info}/METADATA +49 -38
- glaip_sdk-0.7.17.dist-info/RECORD +224 -0
- {glaip_sdk-0.6.5b3.dist-info ā glaip_sdk-0.7.17.dist-info}/WHEEL +2 -1
- glaip_sdk-0.7.17.dist-info/entry_points.txt +2 -0
- glaip_sdk-0.7.17.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.5b3.dist-info/RECORD +0 -145
- glaip_sdk-0.6.5b3.dist-info/entry_points.txt +0 -3
glaip_sdk/cli/commands/update.py
CHANGED
|
@@ -6,9 +6,12 @@ Author:
|
|
|
6
6
|
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
9
|
+
import importlib.util
|
|
10
|
+
import os
|
|
9
11
|
import subprocess
|
|
10
12
|
import sys
|
|
11
13
|
from collections.abc import Sequence
|
|
14
|
+
from pathlib import Path
|
|
12
15
|
|
|
13
16
|
import click
|
|
14
17
|
from rich.console import Console
|
|
@@ -18,19 +21,132 @@ from glaip_sdk.branding import ACCENT_STYLE, ERROR_STYLE, INFO_STYLE, SUCCESS_ST
|
|
|
18
21
|
PACKAGE_NAME = "glaip-sdk"
|
|
19
22
|
|
|
20
23
|
|
|
21
|
-
def
|
|
22
|
-
"""
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
24
|
+
def _is_uv_managed_environment() -> bool:
|
|
25
|
+
"""Check if running in a uv-managed tool environment.
|
|
26
|
+
|
|
27
|
+
Uses a path-based heuristic against sys.executable, sys.prefix, and UV_TOOL_DIR
|
|
28
|
+
or UV_TOOL_BIN to detect a case-insensitive "uv/tools" segment. Update if uv
|
|
29
|
+
changes its layout.
|
|
30
|
+
"""
|
|
31
|
+
if _has_uv_tool_path(sys.executable):
|
|
32
|
+
return True
|
|
33
|
+
if _has_uv_tool_path(sys.prefix):
|
|
34
|
+
return True
|
|
35
|
+
uv_tool_dir = os.environ.get("UV_TOOL_DIR") or os.environ.get("UV_TOOL_BIN")
|
|
36
|
+
if uv_tool_dir and _has_uv_tool_path(uv_tool_dir):
|
|
37
|
+
return True
|
|
38
|
+
return False
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _has_uv_tool_path(path: str) -> bool:
|
|
42
|
+
"""Return True when a path contains a case-insensitive uv/tools segment."""
|
|
43
|
+
parts = [part.lower() for part in Path(path).parts]
|
|
44
|
+
for idx, part in enumerate(parts[:-1]):
|
|
45
|
+
if part == "uv" and parts[idx + 1] == "tools":
|
|
46
|
+
return True
|
|
47
|
+
return False
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _is_pip_available() -> bool:
|
|
51
|
+
"""Return True when pip can be imported in the current interpreter."""
|
|
52
|
+
return importlib.util.find_spec("pip") is not None
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _build_missing_pip_guidance(
|
|
56
|
+
*,
|
|
57
|
+
include_prerelease: bool,
|
|
58
|
+
package_name: str = PACKAGE_NAME,
|
|
59
|
+
force_reinstall: bool = False,
|
|
60
|
+
) -> tuple[str, str]:
|
|
61
|
+
"""Return error and troubleshooting guidance when pip is unavailable."""
|
|
62
|
+
manual_cmd = _build_manual_upgrade_command(
|
|
63
|
+
include_prerelease,
|
|
64
|
+
package_name=package_name,
|
|
65
|
+
is_uv=True,
|
|
66
|
+
force_reinstall=force_reinstall,
|
|
67
|
+
)
|
|
68
|
+
error_detail = "pip is not available in this environment."
|
|
69
|
+
troubleshooting = (
|
|
70
|
+
"š” Troubleshooting:\n"
|
|
71
|
+
f" ⢠If you installed via uv tool, run: {manual_cmd}\n"
|
|
72
|
+
" ⢠Otherwise install pip: python -m ensurepip"
|
|
73
|
+
)
|
|
74
|
+
return error_detail, troubleshooting
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def _build_command_parts(
|
|
78
|
+
*,
|
|
79
|
+
package_name: str = PACKAGE_NAME,
|
|
80
|
+
is_uv: bool | None = None,
|
|
81
|
+
force_reinstall: bool = False,
|
|
82
|
+
include_prerelease: bool = False,
|
|
83
|
+
) -> tuple[list[str], str]:
|
|
84
|
+
"""Build the common parts of upgrade commands.
|
|
85
|
+
|
|
86
|
+
Returns:
|
|
87
|
+
Tuple of (command parts list, force_reinstall flag name).
|
|
88
|
+
For uv: (["uv", "tool", "install", "--upgrade", package_name], "--reinstall")
|
|
89
|
+
For pip: (["pip", "install", "--upgrade", package_name], "--force-reinstall")
|
|
90
|
+
"""
|
|
91
|
+
if is_uv is None:
|
|
92
|
+
is_uv = _is_uv_managed_environment()
|
|
93
|
+
|
|
94
|
+
if is_uv:
|
|
95
|
+
command = ["uv", "tool", "install", "--upgrade", package_name]
|
|
96
|
+
reinstall_flag = "--reinstall"
|
|
97
|
+
else:
|
|
98
|
+
command = ["pip", "install", "--upgrade", package_name]
|
|
99
|
+
reinstall_flag = "--force-reinstall"
|
|
100
|
+
|
|
101
|
+
if force_reinstall:
|
|
102
|
+
command.insert(-1, reinstall_flag)
|
|
103
|
+
|
|
31
104
|
if include_prerelease:
|
|
32
105
|
command.append("--pre")
|
|
33
|
-
|
|
106
|
+
|
|
107
|
+
return command, reinstall_flag
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def _build_upgrade_command(
|
|
111
|
+
include_prerelease: bool,
|
|
112
|
+
*,
|
|
113
|
+
package_name: str = PACKAGE_NAME,
|
|
114
|
+
is_uv: bool | None = None,
|
|
115
|
+
force_reinstall: bool = False,
|
|
116
|
+
) -> Sequence[str]:
|
|
117
|
+
"""Return the command used to upgrade the SDK (pip or uv tool install)."""
|
|
118
|
+
if is_uv is None:
|
|
119
|
+
is_uv = _is_uv_managed_environment()
|
|
120
|
+
|
|
121
|
+
command_parts, _ = _build_command_parts(
|
|
122
|
+
package_name=package_name,
|
|
123
|
+
is_uv=is_uv,
|
|
124
|
+
force_reinstall=force_reinstall,
|
|
125
|
+
include_prerelease=include_prerelease,
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
# For pip, prepend sys.executable and -m
|
|
129
|
+
if not is_uv:
|
|
130
|
+
command_parts = [sys.executable, "-m"] + command_parts
|
|
131
|
+
|
|
132
|
+
return command_parts
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def _build_manual_upgrade_command(
|
|
136
|
+
include_prerelease: bool,
|
|
137
|
+
*,
|
|
138
|
+
package_name: str = PACKAGE_NAME,
|
|
139
|
+
is_uv: bool | None = None,
|
|
140
|
+
force_reinstall: bool = False,
|
|
141
|
+
) -> str:
|
|
142
|
+
"""Return a manual upgrade command string matching the active environment."""
|
|
143
|
+
command_parts, _ = _build_command_parts(
|
|
144
|
+
package_name=package_name,
|
|
145
|
+
is_uv=is_uv,
|
|
146
|
+
force_reinstall=force_reinstall,
|
|
147
|
+
include_prerelease=include_prerelease,
|
|
148
|
+
)
|
|
149
|
+
return " ".join(command_parts)
|
|
34
150
|
|
|
35
151
|
|
|
36
152
|
@click.command(name="update")
|
|
@@ -40,22 +156,52 @@ def _build_upgrade_command(include_prerelease: bool) -> Sequence[str]:
|
|
|
40
156
|
is_flag=True,
|
|
41
157
|
help="Include pre-release versions when upgrading.",
|
|
42
158
|
)
|
|
43
|
-
|
|
44
|
-
""
|
|
159
|
+
@click.option(
|
|
160
|
+
"--reinstall",
|
|
161
|
+
"force_reinstall",
|
|
162
|
+
is_flag=True,
|
|
163
|
+
help="Force reinstall even if already up-to-date.",
|
|
164
|
+
)
|
|
165
|
+
def update_command(include_prerelease: bool, force_reinstall: bool) -> None:
|
|
166
|
+
"""Upgrade the glaip-sdk package using pip or uv tool install."""
|
|
45
167
|
console = Console()
|
|
46
|
-
|
|
168
|
+
# Call _is_uv_managed_environment() once and pass explicitly to avoid redundant calls
|
|
169
|
+
is_uv = _is_uv_managed_environment()
|
|
170
|
+
if not is_uv and not _is_pip_available():
|
|
171
|
+
error_detail, troubleshooting = _build_missing_pip_guidance(
|
|
172
|
+
include_prerelease=include_prerelease,
|
|
173
|
+
force_reinstall=force_reinstall,
|
|
174
|
+
)
|
|
175
|
+
raise click.ClickException(f"{error_detail}\n{troubleshooting}")
|
|
176
|
+
upgrade_cmd = _build_upgrade_command(
|
|
177
|
+
include_prerelease,
|
|
178
|
+
is_uv=is_uv,
|
|
179
|
+
force_reinstall=force_reinstall,
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
# Determine the appropriate manual command for error messages
|
|
183
|
+
manual_cmd = _build_manual_upgrade_command(
|
|
184
|
+
include_prerelease,
|
|
185
|
+
is_uv=is_uv,
|
|
186
|
+
force_reinstall=force_reinstall,
|
|
187
|
+
)
|
|
188
|
+
|
|
47
189
|
console.print(f"[{ACCENT_STYLE}]Upgrading {PACKAGE_NAME} using[/] [{INFO_STYLE}]{' '.join(upgrade_cmd)}[/]")
|
|
48
190
|
|
|
49
191
|
try:
|
|
50
192
|
subprocess.run(upgrade_cmd, check=True)
|
|
51
193
|
except FileNotFoundError as exc:
|
|
194
|
+
if is_uv:
|
|
195
|
+
raise click.ClickException(
|
|
196
|
+
f"Unable to locate uv executable. Please ensure uv is installed and on your PATH.\n"
|
|
197
|
+
f"Install uv: curl -LsSf https://astral.sh/uv/install.sh | sh\n"
|
|
198
|
+
f"Or run manually: {manual_cmd}"
|
|
199
|
+
) from exc
|
|
52
200
|
raise click.ClickException(
|
|
53
201
|
"Unable to locate Python executable to run pip. Please ensure Python is installed and try again."
|
|
54
202
|
) from exc
|
|
55
203
|
except subprocess.CalledProcessError as exc:
|
|
56
|
-
console.print(
|
|
57
|
-
f"[{ERROR_STYLE}]Automatic upgrade failed.[/] Please run `pip install -U {PACKAGE_NAME}` manually."
|
|
58
|
-
)
|
|
204
|
+
console.print(f"[{ERROR_STYLE}]Automatic upgrade failed.[/] Please run `{manual_cmd}` manually.")
|
|
59
205
|
raise click.ClickException("Automatic upgrade failed.") from exc
|
|
60
206
|
|
|
61
207
|
console.print(f"[{SUCCESS_STYLE}]ā
{PACKAGE_NAME} upgraded successfully.[/]")
|
glaip_sdk/cli/config.py
CHANGED
glaip_sdk/cli/core/output.py
CHANGED
|
@@ -29,12 +29,6 @@ from glaip_sdk.cli.io import export_resource_to_file_with_validation
|
|
|
29
29
|
from glaip_sdk.cli.rich_helpers import markup_text, print_markup
|
|
30
30
|
from glaip_sdk.rich_components import AIPPanel, AIPTable
|
|
31
31
|
from glaip_sdk.utils import format_datetime, is_uuid
|
|
32
|
-
|
|
33
|
-
try:
|
|
34
|
-
from glaip_sdk import _version as _version_module
|
|
35
|
-
except ImportError: # pragma: no cover - defensive import
|
|
36
|
-
_version_module = None
|
|
37
|
-
|
|
38
32
|
from .prompting import (
|
|
39
33
|
_fuzzy_pick,
|
|
40
34
|
_fuzzy_pick_for_resources,
|
|
@@ -43,6 +37,9 @@ from .prompting import (
|
|
|
43
37
|
)
|
|
44
38
|
from .rendering import _spinner_stop, _spinner_update, spinner_context
|
|
45
39
|
|
|
40
|
+
_VERSION_MODULE_MISSING = object()
|
|
41
|
+
_version_module: Any | None = _VERSION_MODULE_MISSING
|
|
42
|
+
|
|
46
43
|
console = Console()
|
|
47
44
|
pager.console = console
|
|
48
45
|
logger = logging.getLogger("glaip_sdk.cli.core.output")
|
|
@@ -236,7 +233,15 @@ def handle_resource_export(
|
|
|
236
233
|
|
|
237
234
|
def sdk_version() -> str:
|
|
238
235
|
"""Return the current SDK version, warning if metadata is unavailable."""
|
|
239
|
-
global _WARNED_SDK_VERSION_FALLBACK
|
|
236
|
+
global _WARNED_SDK_VERSION_FALLBACK, _version_module
|
|
237
|
+
|
|
238
|
+
if _version_module is _VERSION_MODULE_MISSING:
|
|
239
|
+
try:
|
|
240
|
+
from importlib import import_module # noqa: PLC0415
|
|
241
|
+
|
|
242
|
+
_version_module = import_module("glaip_sdk._version")
|
|
243
|
+
except Exception: # pragma: no cover - defensive fallback
|
|
244
|
+
_version_module = None
|
|
240
245
|
|
|
241
246
|
if _version_module is None:
|
|
242
247
|
if not _WARNED_SDK_VERSION_FALLBACK:
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""Entry point wrapper for early logging configuration.
|
|
2
|
+
|
|
3
|
+
This must be imported BEFORE glaip_sdk.cli.main to catch import-time warnings.
|
|
4
|
+
|
|
5
|
+
Authors:
|
|
6
|
+
Raymond Christopher (raymond.christopher@gdplabs.id)
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import sys
|
|
10
|
+
|
|
11
|
+
# Configure logging BEFORE importing anything else
|
|
12
|
+
from glaip_sdk.runner.logging_config import setup_cli_logging
|
|
13
|
+
|
|
14
|
+
setup_cli_logging()
|
|
15
|
+
|
|
16
|
+
# Now import and run CLI
|
|
17
|
+
from glaip_sdk.cli import main # noqa: E402
|
|
18
|
+
|
|
19
|
+
if __name__ == "__main__":
|
|
20
|
+
sys.exit(main()) # pylint: disable=no-value-for-parameter
|
glaip_sdk/cli/main.py
CHANGED
|
@@ -11,8 +11,6 @@ from typing import Any
|
|
|
11
11
|
|
|
12
12
|
import click
|
|
13
13
|
from rich.console import Console
|
|
14
|
-
|
|
15
|
-
from glaip_sdk import Client
|
|
16
14
|
from glaip_sdk.branding import (
|
|
17
15
|
ERROR,
|
|
18
16
|
ERROR_STYLE,
|
|
@@ -37,21 +35,50 @@ from glaip_sdk.cli.commands.mcps import mcps_group
|
|
|
37
35
|
from glaip_sdk.cli.commands.models import models_group
|
|
38
36
|
from glaip_sdk.cli.commands.tools import tools_group
|
|
39
37
|
from glaip_sdk.cli.commands.transcripts import transcripts_group
|
|
40
|
-
from glaip_sdk.cli.commands.update import
|
|
38
|
+
from glaip_sdk.cli.commands.update import (
|
|
39
|
+
_build_missing_pip_guidance,
|
|
40
|
+
_build_manual_upgrade_command,
|
|
41
|
+
_build_upgrade_command,
|
|
42
|
+
_is_pip_available,
|
|
43
|
+
_is_uv_managed_environment,
|
|
44
|
+
update_command,
|
|
45
|
+
)
|
|
41
46
|
from glaip_sdk.cli.config import load_config
|
|
42
47
|
from glaip_sdk.cli.hints import in_slash_mode
|
|
48
|
+
from glaip_sdk.cli.core.output import format_size, sdk_version
|
|
49
|
+
from glaip_sdk.cli.core.rendering import spinner_context, update_spinner
|
|
43
50
|
from glaip_sdk.cli.transcript import get_transcript_cache_stats
|
|
44
51
|
from glaip_sdk.cli.update_notifier import maybe_notify_update
|
|
45
|
-
from glaip_sdk.cli.utils import format_size, sdk_version, spinner_context, update_spinner
|
|
46
52
|
from glaip_sdk.config.constants import (
|
|
47
53
|
DEFAULT_AGENT_RUN_TIMEOUT,
|
|
48
54
|
)
|
|
49
55
|
from glaip_sdk.icons import ICON_AGENT
|
|
50
56
|
from glaip_sdk.rich_components import AIPPanel, AIPTable
|
|
51
57
|
|
|
58
|
+
# Constants
|
|
59
|
+
UPDATE_ERROR_TITLE = "ā Update Error"
|
|
60
|
+
|
|
61
|
+
Client: type[Any] | None = None
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _resolve_client_class() -> type[Any]:
|
|
65
|
+
"""Resolve the Client class lazily to avoid heavy imports at CLI startup."""
|
|
66
|
+
global Client
|
|
67
|
+
if Client is None:
|
|
68
|
+
from glaip_sdk import Client as ClientClass # noqa: PLC0415
|
|
69
|
+
|
|
70
|
+
Client = ClientClass
|
|
71
|
+
return Client
|
|
72
|
+
|
|
52
73
|
|
|
53
74
|
def _suppress_chatty_loggers() -> None:
|
|
54
75
|
"""Silence noisy SDK/httpx logs for CLI output."""
|
|
76
|
+
# Ensure CLI logging is configured (idempotent)
|
|
77
|
+
from glaip_sdk.runner.logging_config import setup_cli_logging # noqa: PLC0415
|
|
78
|
+
|
|
79
|
+
setup_cli_logging()
|
|
80
|
+
|
|
81
|
+
# Also suppress SDK-specific loggers
|
|
55
82
|
noisy_loggers = [
|
|
56
83
|
"glaip_sdk.client",
|
|
57
84
|
"httpx",
|
|
@@ -227,26 +254,40 @@ def _load_and_merge_config(ctx: click.Context) -> dict:
|
|
|
227
254
|
|
|
228
255
|
def _validate_config_and_show_error(config: dict, console: Console) -> None:
|
|
229
256
|
"""Validate configuration and show error if incomplete."""
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
257
|
+
if config.get("api_url") and config.get("api_key"):
|
|
258
|
+
return
|
|
259
|
+
|
|
260
|
+
# Best effort: avoid failing validation due to config I/O issues.
|
|
261
|
+
has_accounts = True
|
|
262
|
+
logger = logging.getLogger(__name__)
|
|
263
|
+
try:
|
|
264
|
+
store = get_account_store()
|
|
265
|
+
try:
|
|
266
|
+
has_accounts = bool(store.list_accounts())
|
|
267
|
+
except Exception:
|
|
268
|
+
logger.warning("Failed to list accounts from account store.", exc_info=True)
|
|
269
|
+
has_accounts = True
|
|
270
|
+
except Exception:
|
|
271
|
+
logger.warning("Failed to initialize account store.", exc_info=True)
|
|
272
|
+
has_accounts = True
|
|
273
|
+
|
|
274
|
+
no_accounts_hint = "" if has_accounts else "\n ⢠No accounts found; create one now to continue"
|
|
275
|
+
console.print(
|
|
276
|
+
AIPPanel(
|
|
277
|
+
f"[{ERROR_STYLE}]ā Configuration incomplete[/]\n\n"
|
|
278
|
+
f"š Current config:\n"
|
|
279
|
+
f" ⢠API URL: {config.get('api_url', 'Not set')}\n"
|
|
280
|
+
f" ⢠API Key: {'***' + config.get('api_key', '')[-4:] if config.get('api_key') else 'Not set'}\n\n"
|
|
281
|
+
f"š” To fix this:\n"
|
|
282
|
+
f" ⢠Run 'aip accounts add default' to set up credentials\n"
|
|
283
|
+
f" ⢠Or run 'aip configure' for interactive setup\n"
|
|
284
|
+
f" ⢠Or run 'aip accounts list' to see current accounts{no_accounts_hint}",
|
|
285
|
+
title="ā Configuration Error",
|
|
286
|
+
border_style=ERROR,
|
|
287
|
+
),
|
|
288
|
+
)
|
|
289
|
+
console.print(f"\n[{SUCCESS_STYLE}]ā
AIP - Ready[/] (SDK v{sdk_version()}) - Configure to connect")
|
|
290
|
+
sys.exit(1)
|
|
250
291
|
|
|
251
292
|
|
|
252
293
|
def _resolve_status_console(ctx: Any) -> tuple[Console, bool]:
|
|
@@ -339,14 +380,15 @@ def _safe_list_call(obj: Any, attr: str) -> list[Any]:
|
|
|
339
380
|
|
|
340
381
|
def _get_client_from_config(config: dict) -> Any:
|
|
341
382
|
"""Return a Client instance built from config."""
|
|
342
|
-
|
|
383
|
+
client_class = _resolve_client_class()
|
|
384
|
+
return client_class(
|
|
343
385
|
api_url=config["api_url"],
|
|
344
386
|
api_key=config["api_key"],
|
|
345
387
|
timeout=config.get("timeout", 30.0),
|
|
346
388
|
)
|
|
347
389
|
|
|
348
390
|
|
|
349
|
-
def _create_and_test_client(config: dict, console: Console, *, compact: bool = False) ->
|
|
391
|
+
def _create_and_test_client(config: dict, console: Console, *, compact: bool = False) -> Any:
|
|
350
392
|
"""Create client and test connection by fetching resources."""
|
|
351
393
|
client: Any = _get_client_from_config(config)
|
|
352
394
|
|
|
@@ -538,13 +580,39 @@ def update(check_only: bool, force: bool) -> None:
|
|
|
538
580
|
),
|
|
539
581
|
)
|
|
540
582
|
|
|
541
|
-
# Update using pip
|
|
583
|
+
# Update using pip or uv tool install
|
|
542
584
|
try:
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
585
|
+
is_uv = _is_uv_managed_environment()
|
|
586
|
+
if not is_uv and not _is_pip_available():
|
|
587
|
+
error_detail, troubleshooting = _build_missing_pip_guidance(
|
|
588
|
+
include_prerelease=False,
|
|
589
|
+
package_name="glaip-sdk",
|
|
590
|
+
force_reinstall=force,
|
|
591
|
+
)
|
|
592
|
+
console.print(
|
|
593
|
+
AIPPanel(
|
|
594
|
+
f"[{ERROR_STYLE}]ā Update failed[/]\n\nš Error: {error_detail}\n\n{troubleshooting}",
|
|
595
|
+
title=UPDATE_ERROR_TITLE,
|
|
596
|
+
border_style=ERROR,
|
|
597
|
+
padding=(0, 1),
|
|
598
|
+
),
|
|
599
|
+
)
|
|
600
|
+
sys.exit(1)
|
|
601
|
+
cmd = list(
|
|
602
|
+
_build_upgrade_command(
|
|
603
|
+
include_prerelease=False,
|
|
604
|
+
package_name="glaip-sdk",
|
|
605
|
+
is_uv=is_uv,
|
|
606
|
+
force_reinstall=force,
|
|
607
|
+
)
|
|
608
|
+
)
|
|
609
|
+
|
|
610
|
+
manual_cmd = _build_manual_upgrade_command(
|
|
611
|
+
include_prerelease=False,
|
|
612
|
+
package_name="glaip-sdk",
|
|
613
|
+
is_uv=is_uv,
|
|
614
|
+
force_reinstall=force,
|
|
615
|
+
)
|
|
548
616
|
subprocess.run(cmd, capture_output=True, text=True, check=True)
|
|
549
617
|
|
|
550
618
|
verify_hint = ""
|
|
@@ -571,16 +639,36 @@ def update(check_only: bool, force: bool) -> None:
|
|
|
571
639
|
)
|
|
572
640
|
console.print(f"š New version: {version_result.stdout.strip()}")
|
|
573
641
|
|
|
642
|
+
except FileNotFoundError:
|
|
643
|
+
troubleshooting = f"š” Troubleshooting:\n ⢠Try running: {manual_cmd}\n"
|
|
644
|
+
if is_uv:
|
|
645
|
+
troubleshooting += " ⢠Ensure uv is installed: curl -LsSf https://astral.sh/uv/install.sh | sh"
|
|
646
|
+
error_detail = "uv executable not found in your PATH."
|
|
647
|
+
else:
|
|
648
|
+
troubleshooting += " ⢠Ensure Python and pip are installed"
|
|
649
|
+
error_detail = "Python executable not found to run pip."
|
|
650
|
+
console.print(
|
|
651
|
+
AIPPanel(
|
|
652
|
+
f"[{ERROR_STYLE}]ā Update failed[/]\n\nš Error: {error_detail}\n\n{troubleshooting}",
|
|
653
|
+
title=UPDATE_ERROR_TITLE,
|
|
654
|
+
border_style=ERROR,
|
|
655
|
+
padding=(0, 1),
|
|
656
|
+
),
|
|
657
|
+
)
|
|
658
|
+
sys.exit(1)
|
|
574
659
|
except subprocess.CalledProcessError as e:
|
|
660
|
+
troubleshooting = (
|
|
661
|
+
f"š” Troubleshooting:\n ⢠Check your internet connection\n ⢠Try running: {manual_cmd}\n"
|
|
662
|
+
)
|
|
663
|
+
if is_uv:
|
|
664
|
+
troubleshooting += " ⢠Ensure uv is installed: curl -LsSf https://astral.sh/uv/install.sh | sh"
|
|
665
|
+
else:
|
|
666
|
+
troubleshooting += " ⢠Check if you have write permissions"
|
|
667
|
+
|
|
575
668
|
console.print(
|
|
576
669
|
AIPPanel(
|
|
577
|
-
f"[{ERROR_STYLE}]ā Update failed[/]\n\n"
|
|
578
|
-
|
|
579
|
-
"š” Troubleshooting:\n"
|
|
580
|
-
" ⢠Check your internet connection\n"
|
|
581
|
-
" ⢠Try running: pip install --upgrade glaip-sdk\n"
|
|
582
|
-
" ⢠Check if you have write permissions",
|
|
583
|
-
title="ā Update Error",
|
|
670
|
+
f"[{ERROR_STYLE}]ā Update failed[/]\n\nš Error: {e.stderr}\n\n{troubleshooting}",
|
|
671
|
+
title=UPDATE_ERROR_TITLE,
|
|
584
672
|
border_style=ERROR,
|
|
585
673
|
padding=(0, 1),
|
|
586
674
|
),
|
glaip_sdk/cli/pager.py
CHANGED
|
@@ -46,11 +46,11 @@ def _get_console() -> Console:
|
|
|
46
46
|
"""
|
|
47
47
|
global console
|
|
48
48
|
try:
|
|
49
|
-
|
|
49
|
+
cli_output = importlib.import_module("glaip_sdk.cli.core.output")
|
|
50
50
|
except Exception: # pragma: no cover - fallback during import cycles
|
|
51
|
-
|
|
51
|
+
cli_output = None
|
|
52
52
|
|
|
53
|
-
current_console = getattr(
|
|
53
|
+
current_console = getattr(cli_output, "console", None) if cli_output else None
|
|
54
54
|
if current_console is not None and current_console is not console:
|
|
55
55
|
console = current_console
|
|
56
56
|
|
glaip_sdk/cli/resolution.py
CHANGED
|
@@ -13,7 +13,8 @@ from typing import Any
|
|
|
13
13
|
import click
|
|
14
14
|
|
|
15
15
|
from glaip_sdk.branding import ACCENT_STYLE
|
|
16
|
-
from glaip_sdk.cli.
|
|
16
|
+
from glaip_sdk.cli.core.output import resolve_resource
|
|
17
|
+
from glaip_sdk.cli.core.rendering import spinner_context
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
def resolve_resource_reference(
|