glaip-sdk 0.0.10__py3-none-any.whl → 0.0.11__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/cli/auth.py +414 -0
- glaip_sdk/cli/commands/agents.py +25 -3
- glaip_sdk/cli/commands/mcps.py +276 -92
- glaip_sdk/cli/main.py +8 -0
- glaip_sdk/cli/slash/session.py +24 -9
- glaip_sdk/cli/update_notifier.py +107 -0
- glaip_sdk/cli/utils.py +23 -8
- glaip_sdk/models.py +0 -2
- glaip_sdk/utils/import_export.py +3 -7
- glaip_sdk/utils/serialization.py +93 -2
- {glaip_sdk-0.0.10.dist-info → glaip_sdk-0.0.11.dist-info}/METADATA +2 -1
- {glaip_sdk-0.0.10.dist-info → glaip_sdk-0.0.11.dist-info}/RECORD +14 -12
- {glaip_sdk-0.0.10.dist-info → glaip_sdk-0.0.11.dist-info}/WHEEL +0 -0
- {glaip_sdk-0.0.10.dist-info → glaip_sdk-0.0.11.dist-info}/entry_points.txt +0 -0
glaip_sdk/cli/utils.py
CHANGED
|
@@ -828,7 +828,7 @@ def _build_table_group(
|
|
|
828
828
|
table = _create_table(columns, title)
|
|
829
829
|
for row in rows:
|
|
830
830
|
table.add_row(*[str(row.get(key, "N/A")) for key, _, _, _ in columns])
|
|
831
|
-
footer = Text(f"\n[dim]Total {len(rows)} items[/dim]")
|
|
831
|
+
footer = Text.from_markup(f"\n[dim]Total {len(rows)} items[/dim]")
|
|
832
832
|
return Group(table, footer)
|
|
833
833
|
|
|
834
834
|
|
|
@@ -872,7 +872,7 @@ def _handle_markdown_output(
|
|
|
872
872
|
|
|
873
873
|
def _handle_empty_items(title: str) -> None:
|
|
874
874
|
"""Handle case when no items are found."""
|
|
875
|
-
console.print(Text(f"[yellow]No {title.lower()} found.[/yellow]"))
|
|
875
|
+
console.print(Text.from_markup(f"[yellow]No {title.lower()} found.[/yellow]"))
|
|
876
876
|
|
|
877
877
|
|
|
878
878
|
def _should_use_fuzzy_picker() -> bool:
|
|
@@ -916,7 +916,9 @@ def _print_selection_tip(title: str) -> None:
|
|
|
916
916
|
"""Print the contextual follow-up tip after a fuzzy selection."""
|
|
917
917
|
|
|
918
918
|
tip_cmd = _resource_tip_command(title)
|
|
919
|
-
console.print(
|
|
919
|
+
console.print(
|
|
920
|
+
Text.from_markup(f"\n[dim]Tip: use `{tip_cmd} <ID>` for details[/dim]")
|
|
921
|
+
)
|
|
920
922
|
|
|
921
923
|
|
|
922
924
|
def _handle_fuzzy_pick_selection(
|
|
@@ -936,11 +938,21 @@ def _handle_fuzzy_pick_selection(
|
|
|
936
938
|
|
|
937
939
|
|
|
938
940
|
def _handle_table_output(
|
|
939
|
-
rows: list[dict[str, Any]],
|
|
941
|
+
rows: list[dict[str, Any]],
|
|
942
|
+
columns: list[tuple],
|
|
943
|
+
title: str,
|
|
944
|
+
*,
|
|
945
|
+
use_pager: bool | None = None,
|
|
940
946
|
) -> None:
|
|
941
947
|
"""Handle table output with paging."""
|
|
942
948
|
content = _build_table_group(rows, columns, title)
|
|
943
|
-
|
|
949
|
+
should_page = (
|
|
950
|
+
_should_page_output(len(rows), console.is_terminal and os.isatty(1))
|
|
951
|
+
if use_pager is None
|
|
952
|
+
else use_pager
|
|
953
|
+
)
|
|
954
|
+
|
|
955
|
+
if should_page:
|
|
944
956
|
ansi = _render_ansi(content)
|
|
945
957
|
if not _page_with_system_pager(ansi):
|
|
946
958
|
with console.pager(styles=True):
|
|
@@ -955,8 +967,11 @@ def output_list(
|
|
|
955
967
|
title: str,
|
|
956
968
|
columns: list[tuple[str, str, str, int | None]],
|
|
957
969
|
transform_func: Callable | None = None,
|
|
970
|
+
*,
|
|
971
|
+
skip_picker: bool = False,
|
|
972
|
+
use_pager: bool | None = None,
|
|
958
973
|
) -> None:
|
|
959
|
-
"""Display a list with fuzzy palette
|
|
974
|
+
"""Display a list with optional fuzzy palette for quick selection."""
|
|
960
975
|
fmt = _get_view(ctx)
|
|
961
976
|
rows = _normalise_rows(items, transform_func)
|
|
962
977
|
rows = _mask_rows_if_configured(rows)
|
|
@@ -983,10 +998,10 @@ def output_list(
|
|
|
983
998
|
except Exception:
|
|
984
999
|
pass
|
|
985
1000
|
|
|
986
|
-
if _handle_fuzzy_pick_selection(rows, columns, title):
|
|
1001
|
+
if not skip_picker and _handle_fuzzy_pick_selection(rows, columns, title):
|
|
987
1002
|
return
|
|
988
1003
|
|
|
989
|
-
_handle_table_output(rows, columns, title)
|
|
1004
|
+
_handle_table_output(rows, columns, title, use_pager=use_pager)
|
|
990
1005
|
|
|
991
1006
|
|
|
992
1007
|
# ------------------------- Output flags decorator ------------------------ #
|
glaip_sdk/models.py
CHANGED
|
@@ -179,8 +179,6 @@ class MCP(BaseModel):
|
|
|
179
179
|
name: str
|
|
180
180
|
description: str | None = None
|
|
181
181
|
config: dict[str, Any] | None = None
|
|
182
|
-
framework: str | None = None
|
|
183
|
-
version: str | None = None
|
|
184
182
|
transport: str | None = None # "sse" or "http"
|
|
185
183
|
authentication: dict[str, Any] | None = None
|
|
186
184
|
metadata: dict[str, Any] | None = None
|
glaip_sdk/utils/import_export.py
CHANGED
|
@@ -57,13 +57,9 @@ def convert_export_to_import_format(
|
|
|
57
57
|
"""
|
|
58
58
|
import_data = data.copy()
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
# Convert agents from dicts to IDs
|
|
65
|
-
if "agents" in import_data and isinstance(import_data["agents"], list):
|
|
66
|
-
import_data["agents"] = extract_ids_from_export(import_data["agents"])
|
|
60
|
+
for key in ["tools", "agents", "mcps"]:
|
|
61
|
+
if key in import_data and isinstance(import_data[key], list):
|
|
62
|
+
import_data[key] = extract_ids_from_export(import_data[key])
|
|
67
63
|
|
|
68
64
|
return import_data
|
|
69
65
|
|
glaip_sdk/utils/serialization.py
CHANGED
|
@@ -10,10 +10,15 @@ Authors:
|
|
|
10
10
|
import json
|
|
11
11
|
from collections.abc import Callable, Iterable
|
|
12
12
|
from pathlib import Path
|
|
13
|
-
from typing import Any
|
|
13
|
+
from typing import TYPE_CHECKING, Any
|
|
14
14
|
|
|
15
15
|
import yaml
|
|
16
16
|
|
|
17
|
+
if TYPE_CHECKING: # pragma: no cover - type-only imports
|
|
18
|
+
from rich.console import Console
|
|
19
|
+
|
|
20
|
+
from glaip_sdk.models import MCP
|
|
21
|
+
|
|
17
22
|
|
|
18
23
|
def read_json(file_path: Path) -> dict[str, Any]:
|
|
19
24
|
"""Read data from JSON file.
|
|
@@ -132,7 +137,8 @@ def load_resource_from_file(file_path: Path) -> dict[str, Any]:
|
|
|
132
137
|
return read_json(file_path)
|
|
133
138
|
else:
|
|
134
139
|
raise ValueError(
|
|
135
|
-
f"Unsupported file format: {file_path.suffix}.
|
|
140
|
+
f"Unsupported file format: {file_path.suffix}. "
|
|
141
|
+
f"Only JSON and YAML files are supported."
|
|
136
142
|
)
|
|
137
143
|
|
|
138
144
|
|
|
@@ -305,6 +311,91 @@ def _should_include_attribute(key: str, value: Any) -> bool:
|
|
|
305
311
|
return True
|
|
306
312
|
|
|
307
313
|
|
|
314
|
+
def strip_empty_fields(data: dict[str, Any]) -> dict[str, Any]:
|
|
315
|
+
"""Recursively remove None values and empty dictionaries from a dictionary.
|
|
316
|
+
|
|
317
|
+
Args:
|
|
318
|
+
data: Dictionary to clean
|
|
319
|
+
|
|
320
|
+
Returns:
|
|
321
|
+
Cleaned dictionary with None values and empty dicts removed
|
|
322
|
+
"""
|
|
323
|
+
if not isinstance(data, dict):
|
|
324
|
+
return data
|
|
325
|
+
|
|
326
|
+
cleaned = {}
|
|
327
|
+
for key, value in data.items():
|
|
328
|
+
if value is None:
|
|
329
|
+
continue
|
|
330
|
+
if isinstance(value, dict):
|
|
331
|
+
nested = strip_empty_fields(value)
|
|
332
|
+
if nested: # Only include non-empty dicts
|
|
333
|
+
cleaned[key] = nested
|
|
334
|
+
else:
|
|
335
|
+
cleaned[key] = value
|
|
336
|
+
|
|
337
|
+
return cleaned
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
def build_mcp_export_payload(
|
|
341
|
+
mcp: "MCP",
|
|
342
|
+
*,
|
|
343
|
+
prompt_for_secrets: bool,
|
|
344
|
+
placeholder: str,
|
|
345
|
+
console: "Console",
|
|
346
|
+
) -> dict[str, Any]:
|
|
347
|
+
"""Build MCP export payload with authentication secret handling.
|
|
348
|
+
|
|
349
|
+
This function prepares an MCP resource for export by:
|
|
350
|
+
1. Starting from model_dump(exclude_none=True) for API alignment
|
|
351
|
+
2. Cleaning internal fields (_client, empty metadata)
|
|
352
|
+
3. Processing authentication with secret capture/placeholder logic
|
|
353
|
+
4. Removing empty fields recursively
|
|
354
|
+
|
|
355
|
+
Args:
|
|
356
|
+
mcp: MCP model instance to export
|
|
357
|
+
prompt_for_secrets: Whether to interactively prompt for missing secrets
|
|
358
|
+
placeholder: Placeholder text for missing secrets
|
|
359
|
+
console: Rich Console instance for user interaction
|
|
360
|
+
|
|
361
|
+
Returns:
|
|
362
|
+
Dictionary ready for export (JSON/YAML serialization)
|
|
363
|
+
|
|
364
|
+
Raises:
|
|
365
|
+
ImportError: If required modules (auth helpers) are not available
|
|
366
|
+
"""
|
|
367
|
+
# Import here to avoid circular dependency
|
|
368
|
+
from glaip_sdk.cli.auth import prepare_authentication_export
|
|
369
|
+
|
|
370
|
+
# Start with model dump (excludes None values automatically)
|
|
371
|
+
payload = mcp.model_dump(exclude_none=True)
|
|
372
|
+
|
|
373
|
+
# Remove internal/CLI fields
|
|
374
|
+
payload.pop("_client", None)
|
|
375
|
+
|
|
376
|
+
# Remove empty metadata dict
|
|
377
|
+
if "metadata" in payload and not payload["metadata"]:
|
|
378
|
+
payload.pop("metadata")
|
|
379
|
+
|
|
380
|
+
# Process authentication section
|
|
381
|
+
if "authentication" in payload:
|
|
382
|
+
processed_auth = prepare_authentication_export(
|
|
383
|
+
payload["authentication"],
|
|
384
|
+
prompt_for_secrets=prompt_for_secrets,
|
|
385
|
+
placeholder=placeholder,
|
|
386
|
+
console=console,
|
|
387
|
+
)
|
|
388
|
+
if processed_auth:
|
|
389
|
+
payload["authentication"] = processed_auth
|
|
390
|
+
else:
|
|
391
|
+
payload.pop("authentication")
|
|
392
|
+
|
|
393
|
+
# Apply final cleanup to remove any remaining empty fields
|
|
394
|
+
payload = strip_empty_fields(payload)
|
|
395
|
+
|
|
396
|
+
return payload
|
|
397
|
+
|
|
398
|
+
|
|
308
399
|
def validate_json_string(json_str: str) -> dict[str, Any]:
|
|
309
400
|
"""Validate JSON string and return parsed data.
|
|
310
401
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: glaip-sdk
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.11
|
|
4
4
|
Summary: Python SDK for GL AIP (GDP Labs AI Agent Package) - Simplified CLI Design
|
|
5
5
|
License: MIT
|
|
6
6
|
Author: Raymond Christopher
|
|
@@ -13,6 +13,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.12
|
|
14
14
|
Requires-Dist: click (>=8.2.0,<8.3.0)
|
|
15
15
|
Requires-Dist: httpx (>=0.28.1)
|
|
16
|
+
Requires-Dist: packaging (>=23.2)
|
|
16
17
|
Requires-Dist: pydantic (>=2.0.0)
|
|
17
18
|
Requires-Dist: python-dotenv (>=1.1.1,<2.0.0)
|
|
18
19
|
Requires-Dist: pyyaml (>=6.0.0)
|
|
@@ -3,21 +3,23 @@ glaip_sdk/_version.py,sha256=tGkFWAVu2ry4Hy7j-u7ophGbPRX8y-ngBbXDhN1VBIQ,2007
|
|
|
3
3
|
glaip_sdk/branding.py,sha256=xsHL7nRAWuwJrAvCi2fZhaPD-AWvdcLNoTVmlw4gZKc,5604
|
|
4
4
|
glaip_sdk/cli/__init__.py,sha256=xCCfuF1Yc7mpCDcfhHZTX0vizvtrDSLeT8MJ3V7m5A0,156
|
|
5
5
|
glaip_sdk/cli/agent_config.py,sha256=VHjebw68wAdhGUzYdPH8qz10oADZPRgUQcPW6F7iHIU,2421
|
|
6
|
+
glaip_sdk/cli/auth.py,sha256=eYdtGmJ3XgiO96hq_69GF6b3W-aRWZrDQ-6bHuaRX4M,13517
|
|
6
7
|
glaip_sdk/cli/commands/__init__.py,sha256=x0CZlZbZHoHvuzfoTWIyEch6WmNnbPzxajrox6riYp0,173
|
|
7
|
-
glaip_sdk/cli/commands/agents.py,sha256=
|
|
8
|
+
glaip_sdk/cli/commands/agents.py,sha256=97dzowjHgk5knyHuI-0z2ojvqNlkebNN1-ikGEoS5sc,40623
|
|
8
9
|
glaip_sdk/cli/commands/configure.py,sha256=eRDzsaKV4fl2lJt8ieS4g2-xRnaa02eAAPW8xBf-tqA,7507
|
|
9
|
-
glaip_sdk/cli/commands/mcps.py,sha256=
|
|
10
|
+
glaip_sdk/cli/commands/mcps.py,sha256=a2p8KfPYv4YaC9qiC7LEyh8oPsbLAwXv4dsnwxZ_juI,19752
|
|
10
11
|
glaip_sdk/cli/commands/models.py,sha256=Ra3-50BPScNs0Q-j4b7U4iK0hNooucEyVgHpQ11-pt8,1700
|
|
11
12
|
glaip_sdk/cli/commands/tools.py,sha256=MOM9Db3HGL1stF-WvL5cZXjw-iZo2qc-oyKQHy6VwIM,18690
|
|
12
13
|
glaip_sdk/cli/display.py,sha256=jE20swoRKzpYUmc0jgbeonaXKeE9x95hfjWAEdnBYRc,8727
|
|
13
14
|
glaip_sdk/cli/io.py,sha256=GPkw3pQMLBGoD5GH-KlbKpNRlVWFZOXHE17F7V3kQsI,3343
|
|
14
|
-
glaip_sdk/cli/main.py,sha256=
|
|
15
|
+
glaip_sdk/cli/main.py,sha256=3Bl8u9t1MekzaNrAZqsx4TukbzzFdi6Wss6jvTDos00,12930
|
|
15
16
|
glaip_sdk/cli/resolution.py,sha256=BOw2NchReLKewAwBAZLWw_3_bI7u3tfzQEO7kQbIiGE,2067
|
|
16
17
|
glaip_sdk/cli/slash/__init__.py,sha256=Vdv6Y8bu-pA8dxDlyP4XrhudBPivztUozhLAz9vaLig,682
|
|
17
18
|
glaip_sdk/cli/slash/agent_session.py,sha256=pDOwGXNHuyJIulrGYu1pacyF3oxHWeDQY-Uv92h2qVg,6859
|
|
18
19
|
glaip_sdk/cli/slash/prompt.py,sha256=Pr5SSTOKFssRsi-AujOm5_BCW_f5MxgLwJ3CCji1ogM,7356
|
|
19
|
-
glaip_sdk/cli/slash/session.py,sha256=
|
|
20
|
-
glaip_sdk/cli/
|
|
20
|
+
glaip_sdk/cli/slash/session.py,sha256=U5UEL6eIvNkIJcSz04Uf8Ql0EptmLJukqHxDCAJ-nOQ,31097
|
|
21
|
+
glaip_sdk/cli/update_notifier.py,sha256=uVbjZJnW4znTzx4AkqsDO4NfXiF-mtQiypTkJByAVuM,3236
|
|
22
|
+
glaip_sdk/cli/utils.py,sha256=98n1tovTUSqS5BIUl4cz6zGoRSSJiXFGJW8oD0xIm2g,42537
|
|
21
23
|
glaip_sdk/cli/validators.py,sha256=USbBgY86AwuDHO-Q_g8g7hu-ot4NgITBsWjTWIl62ms,5569
|
|
22
24
|
glaip_sdk/client/__init__.py,sha256=nYLXfBVTTWwKjP0e63iumPYO4k5FifwWaELQPaPIKIg,188
|
|
23
25
|
glaip_sdk/client/agents.py,sha256=FSKubF40wptMNIheC3_iawiX2CRbhTcNLFiz4qkPC6k,34659
|
|
@@ -28,14 +30,14 @@ glaip_sdk/client/tools.py,sha256=n8DIiOOf1YU_j9JK3Bx2-rDnkpckPi0MI9Ok2s1kwa4,166
|
|
|
28
30
|
glaip_sdk/client/validators.py,sha256=NtPsWjQLjj25LiUnmR-WuS8lL5p4MVRaYT9UVRmj9bo,8809
|
|
29
31
|
glaip_sdk/config/constants.py,sha256=ysEobMiXlLZGIOEaqTdHpPF8kmg5nbLn7BIcBvTCuHM,819
|
|
30
32
|
glaip_sdk/exceptions.py,sha256=DJgaIcvGA09qIX10-ypYgQQ5_k5N3qknmiIFP3p4Z7E,1872
|
|
31
|
-
glaip_sdk/models.py,sha256=
|
|
33
|
+
glaip_sdk/models.py,sha256=0Y65LXpLqUY3IYVPIzP7jm8gdZUMw-EKRKGC1ZOLOcA,8758
|
|
32
34
|
glaip_sdk/rich_components.py,sha256=pmJd-81OQE8bC9UOXtga5rsax4zphKlzCZ1JoWbbQzQ,803
|
|
33
35
|
glaip_sdk/utils/__init__.py,sha256=fmVGcUFa7G0CCfSMSqfNU2BqFl36G1gOFyDfTvtJfVw,926
|
|
34
36
|
glaip_sdk/utils/agent_config.py,sha256=b7_J5DELyk0b_XEoi7tsxbS3wqzAKbMa-3_C-65pPIY,6791
|
|
35
37
|
glaip_sdk/utils/client_utils.py,sha256=M6rZloMKyONaZfI0RtU5tnkibwrIJL5Udw4wPMKkJcw,13588
|
|
36
38
|
glaip_sdk/utils/display.py,sha256=94s9lYF_8ra8jpeqOkbVrUm8oidtCE6OtucyxLQPKmU,3105
|
|
37
39
|
glaip_sdk/utils/general.py,sha256=V5hJrIpYDvDsldU_nChHpuvV2AwhFLUI7Qvcaihq_8A,2270
|
|
38
|
-
glaip_sdk/utils/import_export.py,sha256=
|
|
40
|
+
glaip_sdk/utils/import_export.py,sha256=az_0jCpMB7I6N5HygS2uc62-W6ddm4buEwm6gTsalhY,5203
|
|
39
41
|
glaip_sdk/utils/rendering/__init__.py,sha256=vXjwk5rPhhfPyD8S0DnV4GFFEtPJp4HCCg1Um9SXfs0,70
|
|
40
42
|
glaip_sdk/utils/rendering/formatting.py,sha256=_k8tkcobctmHvdygMljZF7-ALGXpD9-hHF1CNtM2KMU,7201
|
|
41
43
|
glaip_sdk/utils/rendering/models.py,sha256=SS34_00FaoGuSYn-viBkAtIbq7cJNwwPjpxnvyeUmxI,1567
|
|
@@ -51,9 +53,9 @@ glaip_sdk/utils/rendering/steps.py,sha256=4zdeyKxMbUzCal4-yv8yf18144cs5wwXaxhe6m
|
|
|
51
53
|
glaip_sdk/utils/resource_refs.py,sha256=0YzblJNfRhz9xhpaKE9aE68XEV-6_ssr0fIkiMVOka0,5489
|
|
52
54
|
glaip_sdk/utils/rich_utils.py,sha256=-Ij-1bIJvnVAi6DrfftchIlMcvOTjVmSE0Qqax0EY_s,763
|
|
53
55
|
glaip_sdk/utils/run_renderer.py,sha256=d_VMI6LbvHPUUeRmGqh5wK_lHqDEIAcym2iqpbtDad0,1365
|
|
54
|
-
glaip_sdk/utils/serialization.py,sha256=
|
|
56
|
+
glaip_sdk/utils/serialization.py,sha256=T1yt_8G2DCFpcxx7XnqFl5slksRXfBCUuLQJTreGYEQ,11806
|
|
55
57
|
glaip_sdk/utils/validation.py,sha256=QNORcdyvuliEs4EH2_mkDgmoyT9utgl7YNhaf45SEf8,6992
|
|
56
|
-
glaip_sdk-0.0.
|
|
57
|
-
glaip_sdk-0.0.
|
|
58
|
-
glaip_sdk-0.0.
|
|
59
|
-
glaip_sdk-0.0.
|
|
58
|
+
glaip_sdk-0.0.11.dist-info/METADATA,sha256=Z8hxLQAn8fWQtisQyZAi6QgOCSxDpEWw4gLbTBMDrxU,4984
|
|
59
|
+
glaip_sdk-0.0.11.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
60
|
+
glaip_sdk-0.0.11.dist-info/entry_points.txt,sha256=EGs8NO8J1fdFMWA3CsF7sKBEvtHb_fujdCoNPhfMouE,47
|
|
61
|
+
glaip_sdk-0.0.11.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|