glaip-sdk 0.0.7__py3-none-any.whl → 0.0.9__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/utils.py CHANGED
@@ -8,13 +8,16 @@ from __future__ import annotations
8
8
 
9
9
  import io
10
10
  import json
11
+ import logging
11
12
  import os
12
13
  import platform
13
14
  import shlex
14
15
  import shutil
15
16
  import subprocess
17
+ import sys
16
18
  import tempfile
17
19
  from collections.abc import Callable
20
+ from contextlib import AbstractContextManager, nullcontext
18
21
  from pathlib import Path
19
22
  from typing import TYPE_CHECKING, Any
20
23
 
@@ -50,6 +53,7 @@ from glaip_sdk.utils.rendering.renderer import (
50
53
  )
51
54
 
52
55
  console = Console()
56
+ logger = logging.getLogger("glaip_sdk.cli.utils")
53
57
 
54
58
 
55
59
  # ----------------------------- Context helpers ---------------------------- #
@@ -225,6 +229,81 @@ def _get_view(ctx: Any) -> str:
225
229
  return fallback or "rich"
226
230
 
227
231
 
232
+ def spinner_context(
233
+ ctx: Any | None,
234
+ message: str,
235
+ *,
236
+ console_override: Console | None = None,
237
+ spinner: str = "dots",
238
+ spinner_style: str = "cyan",
239
+ ) -> AbstractContextManager[Any]:
240
+ """Return a context manager that renders a spinner when appropriate."""
241
+
242
+ active_console = console_override or console
243
+ if not _can_use_spinner(ctx, active_console):
244
+ return nullcontext()
245
+
246
+ return active_console.status(
247
+ message,
248
+ spinner=spinner,
249
+ spinner_style=spinner_style,
250
+ )
251
+
252
+
253
+ def _can_use_spinner(ctx: Any | None, active_console: Console) -> bool:
254
+ """Check if spinner output is allowed in the current environment."""
255
+
256
+ if ctx is not None:
257
+ tty_enabled = bool(get_ctx_value(ctx, "tty", True))
258
+ view = (_get_view(ctx) or "rich").lower()
259
+ if not tty_enabled or view not in {"", "rich"}:
260
+ return False
261
+
262
+ if not active_console.is_terminal:
263
+ return False
264
+
265
+ return _stream_supports_tty(getattr(active_console, "file", None))
266
+
267
+
268
+ def _stream_supports_tty(stream: Any) -> bool:
269
+ """Return True if the provided stream can safely render a spinner."""
270
+
271
+ target = stream if hasattr(stream, "isatty") else sys.stdout
272
+ try:
273
+ return bool(target.isatty())
274
+ except Exception:
275
+ return False
276
+
277
+
278
+ def update_spinner(status_indicator: Any | None, message: str) -> None:
279
+ """Update spinner text when a status indicator is active."""
280
+
281
+ if status_indicator is None:
282
+ return
283
+
284
+ try:
285
+ status_indicator.update(message)
286
+ except Exception: # pragma: no cover - defensive update
287
+ pass
288
+
289
+
290
+ def stop_spinner(status_indicator: Any | None) -> None:
291
+ """Stop an active spinner safely."""
292
+
293
+ if status_indicator is None:
294
+ return
295
+
296
+ try:
297
+ status_indicator.stop()
298
+ except Exception: # pragma: no cover - defensive stop
299
+ pass
300
+
301
+
302
+ # Backwards compatibility aliases for legacy callers
303
+ _spinner_update = update_spinner
304
+ _spinner_stop = stop_spinner
305
+
306
+
228
307
  # ----------------------------- Client config ----------------------------- #
229
308
 
230
309
 
@@ -507,6 +586,8 @@ def _fuzzy_pick(
507
586
  )
508
587
  except (KeyboardInterrupt, EOFError): # pragma: no cover - user cancelled input
509
588
  return None
589
+ except Exception: # pragma: no cover - prompt_toolkit not available in headless env
590
+ return None
510
591
 
511
592
  return _perform_fuzzy_search(answer, labels, by_label) if answer else None
512
593
 
@@ -794,22 +875,64 @@ def _handle_empty_items(title: str) -> None:
794
875
  console.print(Text(f"[yellow]No {title.lower()} found.[/yellow]"))
795
876
 
796
877
 
878
+ def _should_use_fuzzy_picker() -> bool:
879
+ """Return True when the interactive fuzzy picker can be shown."""
880
+
881
+ return console.is_terminal and os.isatty(1)
882
+
883
+
884
+ def _try_fuzzy_pick(
885
+ rows: list[dict[str, Any]], columns: list[tuple], title: str
886
+ ) -> dict[str, Any] | None:
887
+ """Best-effort fuzzy selection; returns None if the picker fails."""
888
+
889
+ if not _should_use_fuzzy_picker():
890
+ return None
891
+
892
+ try:
893
+ return _fuzzy_pick(rows, columns, title)
894
+ except Exception:
895
+ logger.debug("Fuzzy picker failed; falling back to table output", exc_info=True)
896
+ return None
897
+
898
+
899
+ def _resource_tip_command(title: str) -> str:
900
+ """Resolve the follow-up command hint for the given table title."""
901
+
902
+ title_lower = title.lower()
903
+ mapping = {
904
+ "agent": "aip agents get",
905
+ "tool": "aip tools get",
906
+ "mcp": "aip mcps get",
907
+ "model": "aip models list", # models only ship a list command
908
+ }
909
+ for keyword, command in mapping.items():
910
+ if keyword in title_lower:
911
+ return command
912
+ return "aip agents get"
913
+
914
+
915
+ def _print_selection_tip(title: str) -> None:
916
+ """Print the contextual follow-up tip after a fuzzy selection."""
917
+
918
+ tip_cmd = _resource_tip_command(title)
919
+ console.print(Text(f"\n[dim]Tip: use `{tip_cmd} <ID>` for details[/dim]"))
920
+
921
+
797
922
  def _handle_fuzzy_pick_selection(
798
923
  rows: list[dict[str, Any]], columns: list[tuple], title: str
799
924
  ) -> bool:
800
925
  """Handle fuzzy picker selection, returns True if selection was made."""
801
- picked = (
802
- _fuzzy_pick(rows, columns, title)
803
- if console.is_terminal and os.isatty(1)
804
- else None
805
- )
806
- if picked:
807
- table = _create_table(columns, title)
808
- table.add_row(*[str(picked.get(key, "N/A")) for key, _, _, _ in columns])
809
- console.print(table)
810
- console.print(Text("\n[dim]Tip: use `aip agents get <ID>` for details[/dim]"))
811
- return True
812
- return False
926
+
927
+ picked = _try_fuzzy_pick(rows, columns, title)
928
+ if picked is None:
929
+ return False
930
+
931
+ table = _create_table(columns, title)
932
+ table.add_row(*[str(picked.get(key, "N/A")) for key, _, _, _ in columns])
933
+ console.print(table)
934
+ _print_selection_tip(title)
935
+ return True
813
936
 
814
937
 
815
938
  def _handle_table_output(
@@ -1096,6 +1219,7 @@ def resolve_resource(
1096
1219
  label: str,
1097
1220
  select: int | None = None,
1098
1221
  interface_preference: str = "fuzzy",
1222
+ status_indicator: Any | None = None,
1099
1223
  ) -> Any | None:
1100
1224
  """Resolve resource reference (ID or name) with ambiguity handling.
1101
1225
 
@@ -1107,32 +1231,46 @@ def resolve_resource(
1107
1231
  label: Resource type label for error messages
1108
1232
  select: Optional selection index for ambiguity resolution
1109
1233
  interface_preference: "fuzzy" for fuzzy picker, "questionary" for up/down list
1234
+ status_indicator: Optional Rich status indicator for wait animations
1110
1235
 
1111
1236
  Returns:
1112
1237
  Resolved resource object
1113
1238
  """
1239
+ spinner = status_indicator
1240
+ _spinner_update(spinner, f"[bold blue]Resolving {label}…[/bold blue]")
1241
+
1114
1242
  # Try to resolve by ID first
1243
+ _spinner_update(spinner, f"[bold blue]Fetching {label} by ID…[/bold blue]")
1115
1244
  result = _resolve_by_id(ref, get_by_id)
1116
1245
  if result is not None:
1246
+ _spinner_update(spinner, f"[bold green]{label} found[/bold green]")
1117
1247
  return result
1118
1248
 
1119
1249
  # If get_by_id returned None, the resource doesn't exist
1120
1250
  if is_uuid(ref):
1251
+ _spinner_stop(spinner)
1121
1252
  raise click.ClickException(f"{label} '{ref}' not found")
1122
1253
 
1123
1254
  # Find resources by name
1255
+ _spinner_update(
1256
+ spinner, f"[bold blue]Searching {label}s matching '{ref}'…[/bold blue]"
1257
+ )
1124
1258
  matches = find_by_name(name=ref)
1125
1259
  if not matches:
1260
+ _spinner_stop(spinner)
1126
1261
  raise click.ClickException(f"{label} '{ref}' not found")
1127
1262
 
1128
1263
  if len(matches) == 1:
1264
+ _spinner_update(spinner, f"[bold green]{label} found[/bold green]")
1129
1265
  return matches[0]
1130
1266
 
1131
1267
  # Multiple matches found, handle ambiguity
1132
1268
  if select:
1269
+ _spinner_stop(spinner)
1133
1270
  return _resolve_by_name_multiple_with_select(matches, select)
1134
1271
 
1135
1272
  # Choose interface based on preference
1273
+ _spinner_stop(spinner)
1136
1274
  if interface_preference == "fuzzy":
1137
1275
  return _resolve_by_name_multiple_fuzzy(ctx, ref, matches, label)
1138
1276
  else:
@@ -179,7 +179,7 @@ class RichStreamRenderer:
179
179
  AIPPanel(
180
180
  Markdown(f"**Query:** {query}"),
181
181
  title="User Request",
182
- border_style="yellow",
182
+ border_style="#d97706",
183
183
  padding=(0, 1),
184
184
  )
185
185
  )
@@ -311,6 +311,24 @@ class RichStreamRenderer:
311
311
  def _ensure_live(self) -> None:
312
312
  """Ensure live display is updated."""
313
313
  # Lazily create Live if needed
314
+ # Rich's Live expects the console to maintain a _live_stack list. When tests
315
+ # or callers provide a lightweight console double (e.g. unittest.mock.Mock),
316
+ # the attribute might be missing or replaced with another type which breaks
317
+ # the background refresh thread. Normal Rich consoles always expose
318
+ # _live_stack as a list, so we defensively initialise it if needed.
319
+ live_stack = getattr(self.console, "_live_stack", None)
320
+ if not isinstance(live_stack, list):
321
+ try:
322
+ self.console._live_stack = [] # type: ignore[attr-defined]
323
+ except Exception:
324
+ # If the console forbids attribute assignment we simply skip the
325
+ # live update for this cycle and fall back to buffered printing.
326
+ logger.debug(
327
+ "Console missing _live_stack; skipping live UI initialisation",
328
+ exc_info=True,
329
+ )
330
+ return
331
+
314
332
  if self.live is None and self.cfg.live:
315
333
  try:
316
334
  self.live = Live(
@@ -1023,7 +1041,7 @@ class RichStreamRenderer:
1023
1041
 
1024
1042
  return create_tool_panel(
1025
1043
  title=adjusted_title,
1026
- content=body or "Processing...",
1044
+ content=body,
1027
1045
  status=status,
1028
1046
  theme=self.cfg.theme,
1029
1047
  is_delegation=is_delegation,
@@ -6,12 +6,25 @@ Authors:
6
6
 
7
7
  from __future__ import annotations
8
8
 
9
+ from rich.align import Align
9
10
  from rich.markdown import Markdown
11
+ from rich.spinner import Spinner
10
12
  from rich.text import Text
11
13
 
12
14
  from glaip_sdk.rich_components import AIPPanel
13
15
 
14
16
 
17
+ def _spinner_renderable(message: str = "Processing...") -> Align:
18
+ """Build a Rich spinner renderable for loading placeholders."""
19
+
20
+ spinner = Spinner(
21
+ "dots",
22
+ text=Text(f" {message}", style="dim"),
23
+ style="cyan",
24
+ )
25
+ return Align.left(spinner)
26
+
27
+
15
28
  def create_main_panel(content: str, title: str, theme: str = "dark") -> AIPPanel:
16
29
  """Create a main content panel.
17
30
 
@@ -30,10 +43,8 @@ def create_main_panel(content: str, title: str, theme: str = "dark") -> AIPPanel
30
43
  border_style="green",
31
44
  )
32
45
  else:
33
- # Placeholder panel
34
- placeholder = Text("Processing...", style="dim")
35
46
  return AIPPanel(
36
- placeholder,
47
+ _spinner_renderable(),
37
48
  title=title,
38
49
  border_style="green",
39
50
  )
@@ -61,11 +72,14 @@ def create_tool_panel(
61
72
  mark = "✓" if status == "finished" else "⟳"
62
73
  border_style = "magenta" if is_delegation else "blue"
63
74
 
75
+ body_renderable = (
76
+ Markdown(content, code_theme=("monokai" if theme == "dark" else "github"))
77
+ if content
78
+ else _spinner_renderable()
79
+ )
80
+
64
81
  return AIPPanel(
65
- Markdown(
66
- content or "Processing...",
67
- code_theme=("monokai" if theme == "dark" else "github"),
68
- ),
82
+ body_renderable,
69
83
  title=f"{title} {mark}",
70
84
  border_style=border_style,
71
85
  )
@@ -8,7 +8,7 @@ Authors:
8
8
  """
9
9
 
10
10
  import json
11
- from collections.abc import Iterable
11
+ from collections.abc import Callable, Iterable
12
12
  from pathlib import Path
13
13
  from typing import Any
14
14
 
@@ -217,13 +217,13 @@ def _coerce_resource_to_mapping(resource: Any) -> dict[str, Any] | None:
217
217
  if isinstance(resource, dict):
218
218
  return resource
219
219
 
220
- if hasattr(resource, "__dict__"):
221
- try:
220
+ try:
221
+ if hasattr(resource, "__dict__"):
222
222
  return dict(resource.__dict__)
223
- except (
224
- Exception
225
- ): # pragma: no cover - pathological objects can still defeat coercion
226
- return None
223
+ except (
224
+ Exception
225
+ ): # pragma: no cover - pathological objects can still defeat coercion
226
+ return None
227
227
 
228
228
  return None
229
229
 
@@ -235,27 +235,59 @@ def _iter_public_attribute_names(resource: Any) -> Iterable[str]:
235
235
  names: list[str] = []
236
236
 
237
237
  def _collect(candidates: Iterable[str] | None) -> None:
238
- if candidates is None:
239
- return
240
- for candidate in candidates:
238
+ for candidate in candidates or ():
241
239
  if candidate not in seen:
242
240
  seen.add(candidate)
243
241
  names.append(candidate)
244
242
 
245
- _collect(
246
- getattr(resource, "__dict__", {}).keys()
247
- if hasattr(resource, "__dict__")
248
- else None
249
- )
250
- _collect(getattr(resource, "__annotations__", {}).keys())
243
+ # Collect from __dict__
244
+ _collect_from_dict(resource, _collect)
245
+
246
+ # Collect from __annotations__
247
+ _collect_from_annotations(resource, _collect)
248
+
249
+ # Collect from __slots__
251
250
  _collect(getattr(resource, "__slots__", ()))
252
251
 
252
+ # Fallback to dir() if no names found
253
253
  if not names:
254
- _collect(name for name in dir(resource) if not name.startswith("__"))
254
+ _collect_from_dir(resource, _collect)
255
255
 
256
256
  return iter(names)
257
257
 
258
258
 
259
+ def _collect_from_dict(
260
+ resource: Any, collect_func: Callable[[Iterable[str]], None]
261
+ ) -> None:
262
+ """Safely collect attribute names from __dict__."""
263
+ try:
264
+ if hasattr(resource, "__dict__"):
265
+ dict_keys = getattr(resource, "__dict__", {})
266
+ if dict_keys:
267
+ collect_func(dict_keys.keys())
268
+ except Exception: # pragma: no cover - defensive programming
269
+ pass
270
+
271
+
272
+ def _collect_from_annotations(
273
+ resource: Any, collect_func: Callable[[Iterable[str]], None]
274
+ ) -> None:
275
+ """Safely collect attribute names from __annotations__."""
276
+ annotations = getattr(resource, "__annotations__", {})
277
+ if annotations:
278
+ collect_func(annotations.keys())
279
+
280
+
281
+ def _collect_from_dir(
282
+ resource: Any, collect_func: Callable[[Iterable[str]], None]
283
+ ) -> None:
284
+ """Safely collect attribute names from dir()."""
285
+ try:
286
+ collect_func(name for name in dir(resource) if not name.startswith("__"))
287
+ except Exception: # pragma: no cover - defensive programming
288
+ pass
289
+
290
+
259
291
  def _safe_getattr(resource: Any, name: str) -> Any:
260
292
  try:
261
293
  return getattr(resource, name)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: glaip-sdk
3
- Version: 0.0.7
3
+ Version: 0.0.9
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
@@ -11,7 +11,7 @@ Classifier: Programming Language :: Python :: 3
11
11
  Classifier: Programming Language :: Python :: 3.10
12
12
  Classifier: Programming Language :: Python :: 3.11
13
13
  Classifier: Programming Language :: Python :: 3.12
14
- Requires-Dist: click (>=8.2.0)
14
+ Requires-Dist: click (>=8.2.0,<8.3.0)
15
15
  Requires-Dist: httpx (>=0.28.1)
16
16
  Requires-Dist: pydantic (>=2.0.0)
17
17
  Requires-Dist: python-dotenv (>=1.1.1,<2.0.0)
@@ -1,19 +1,23 @@
1
1
  glaip_sdk/__init__.py,sha256=FD-oTyFUKsTB9xTuGiqvkhuFXfeZ-TspjkeXERglha8,370
2
2
  glaip_sdk/_version.py,sha256=tGkFWAVu2ry4Hy7j-u7ophGbPRX8y-ngBbXDhN1VBIQ,2007
3
- glaip_sdk/branding.py,sha256=d-yGCYbUcdOlEH87E5PmGIyj6uBywsnf-Yd7zs__mUs,5371
3
+ glaip_sdk/branding.py,sha256=_TiQtiwH3ZSWaQhooWPHioriL0goTiYANeN6DT8lQX8,5398
4
4
  glaip_sdk/cli/__init__.py,sha256=xCCfuF1Yc7mpCDcfhHZTX0vizvtrDSLeT8MJ3V7m5A0,156
5
5
  glaip_sdk/cli/agent_config.py,sha256=VHjebw68wAdhGUzYdPH8qz10oADZPRgUQcPW6F7iHIU,2421
6
6
  glaip_sdk/cli/commands/__init__.py,sha256=x0CZlZbZHoHvuzfoTWIyEch6WmNnbPzxajrox6riYp0,173
7
- glaip_sdk/cli/commands/agents.py,sha256=xiFKK76AeqkHyyQo7asdqNDy_VqbIzFHBUEvdE6lnwQ,36943
7
+ glaip_sdk/cli/commands/agents.py,sha256=1xGSoH6C9hSaGglXf4pnloqX5gJQIPsgHhkliiWQQcY,39988
8
8
  glaip_sdk/cli/commands/configure.py,sha256=eRDzsaKV4fl2lJt8ieS4g2-xRnaa02eAAPW8xBf-tqA,7507
9
- glaip_sdk/cli/commands/mcps.py,sha256=ZfmFkisXHHqgFH6WU7W5qPvfdt5Dxd5ZFZb_Ml3POoQ,12794
10
- glaip_sdk/cli/commands/models.py,sha256=lHEVuXT8Sq239C_2LneV8PimVZSm9DXJKajdSVO-N50,1496
11
- glaip_sdk/cli/commands/tools.py,sha256=Xm_qCe0h2EqhbqNuKTBvow1HMc7MbLYx6j92A6rLwu0,16743
12
- glaip_sdk/cli/display.py,sha256=Wr86LTdwUaaTceXwi2v5rJAYaWaYYYhnt3PinSSAQP8,8605
9
+ glaip_sdk/cli/commands/mcps.py,sha256=fRCRQMAnogT76lHUn_nuqkge_x75Fj023CDRgdoj0kQ,14343
10
+ glaip_sdk/cli/commands/models.py,sha256=Ra3-50BPScNs0Q-j4b7U4iK0hNooucEyVgHpQ11-pt8,1700
11
+ glaip_sdk/cli/commands/tools.py,sha256=MOM9Db3HGL1stF-WvL5cZXjw-iZo2qc-oyKQHy6VwIM,18690
12
+ glaip_sdk/cli/display.py,sha256=jE20swoRKzpYUmc0jgbeonaXKeE9x95hfjWAEdnBYRc,8727
13
13
  glaip_sdk/cli/io.py,sha256=GPkw3pQMLBGoD5GH-KlbKpNRlVWFZOXHE17F7V3kQsI,3343
14
- glaip_sdk/cli/main.py,sha256=Z1uMlmU72FFXC2ushNTWpemhQWKbIJNFJauH6FOCPqA,11059
15
- glaip_sdk/cli/resolution.py,sha256=4PEW_KZfN13k7GGEWpx3dOTywE_d-ujSlUhO4liov5w,1673
16
- glaip_sdk/cli/utils.py,sha256=GQ_VwY374D8aLlySWYdExOZMap7Bb0nFIzS9gRhR5gs,37660
14
+ glaip_sdk/cli/main.py,sha256=uWuntvFl0hQSLfNa1rXb-J2zUK_msf3vrSbbrqBcEc4,12692
15
+ glaip_sdk/cli/resolution.py,sha256=BOw2NchReLKewAwBAZLWw_3_bI7u3tfzQEO7kQbIiGE,2067
16
+ glaip_sdk/cli/slash/__init__.py,sha256=Vdv6Y8bu-pA8dxDlyP4XrhudBPivztUozhLAz9vaLig,682
17
+ glaip_sdk/cli/slash/agent_session.py,sha256=JFIFBxB4xzigqHtpLGbl2fgg7RHNwy3e-kUMPMK9MdM,5006
18
+ glaip_sdk/cli/slash/prompt.py,sha256=QFWYgNt5AhBRYGGyUkH30ToZE7B6LS-eZGzoyibYrK8,6064
19
+ glaip_sdk/cli/slash/session.py,sha256=GtnnBqV79KtFJHeLfCKKnCXJ6SU1AmeXquPjy72T20E,24215
20
+ glaip_sdk/cli/utils.py,sha256=S7aa4-v808BEZGvEhKn8N8HQr2slSpvV-TtWw3j15S8,41779
17
21
  glaip_sdk/cli/validators.py,sha256=USbBgY86AwuDHO-Q_g8g7hu-ot4NgITBsWjTWIl62ms,5569
18
22
  glaip_sdk/client/__init__.py,sha256=nYLXfBVTTWwKjP0e63iumPYO4k5FifwWaELQPaPIKIg,188
19
23
  glaip_sdk/client/agents.py,sha256=FSKubF40wptMNIheC3_iawiX2CRbhTcNLFiz4qkPC6k,34659
@@ -36,20 +40,20 @@ glaip_sdk/utils/rendering/__init__.py,sha256=vXjwk5rPhhfPyD8S0DnV4GFFEtPJp4HCCg1
36
40
  glaip_sdk/utils/rendering/formatting.py,sha256=_k8tkcobctmHvdygMljZF7-ALGXpD9-hHF1CNtM2KMU,7201
37
41
  glaip_sdk/utils/rendering/models.py,sha256=SS34_00FaoGuSYn-viBkAtIbq7cJNwwPjpxnvyeUmxI,1567
38
42
  glaip_sdk/utils/rendering/renderer/__init__.py,sha256=EXwVBmGkSYcype4ocAXo69Z1kXu0gpNXmhH5LW0_B7A,2939
39
- glaip_sdk/utils/rendering/renderer/base.py,sha256=4WdvYwsvCBtiIaB-LVteDORyxZN1HCT2jFfU0X0ReXY,39977
43
+ glaip_sdk/utils/rendering/renderer/base.py,sha256=HfIeq-izi3WprbKX_qxNeQRrpernFtoCvgQqrIyVYSU,40950
40
44
  glaip_sdk/utils/rendering/renderer/config.py,sha256=E4ER8TJJbqr1hcWjkwG7XROqLuccQy4EL99CbuLvSXE,783
41
45
  glaip_sdk/utils/rendering/renderer/console.py,sha256=4cLOw4Q1fkHkApuj6dWW8eYpeYdcT0t2SO5MbVt5UTc,1844
42
46
  glaip_sdk/utils/rendering/renderer/debug.py,sha256=FEYxAu4ZB0CjrJKevqQ2TKDgElA2cf6GqZXCNm12sNQ,3721
43
- glaip_sdk/utils/rendering/renderer/panels.py,sha256=_KJohKOsyOBkqKzlC-hOSwZt1SGsJRhQwizlrRgWMis,3040
47
+ glaip_sdk/utils/rendering/renderer/panels.py,sha256=05u6SjU53iP9VD0YHTNruzD7sO6qYCp-P5dTTSdSZmU,3364
44
48
  glaip_sdk/utils/rendering/renderer/progress.py,sha256=i4HG_iNwtK4c3Gf2sviLCiOJ-5ydX4t-YE5dgtLOxNI,3438
45
49
  glaip_sdk/utils/rendering/renderer/stream.py,sha256=1RP5TIV7tqg07X9gPN053XeabFGVT4jPplxaoPU0L38,8601
46
50
  glaip_sdk/utils/rendering/steps.py,sha256=4zdeyKxMbUzCal4-yv8yf18144cs5wwXaxhe6mt2KiE,7307
47
51
  glaip_sdk/utils/resource_refs.py,sha256=0YzblJNfRhz9xhpaKE9aE68XEV-6_ssr0fIkiMVOka0,5489
48
52
  glaip_sdk/utils/rich_utils.py,sha256=-Ij-1bIJvnVAi6DrfftchIlMcvOTjVmSE0Qqax0EY_s,763
49
53
  glaip_sdk/utils/run_renderer.py,sha256=d_VMI6LbvHPUUeRmGqh5wK_lHqDEIAcym2iqpbtDad0,1365
50
- glaip_sdk/utils/serialization.py,sha256=DAOxi42xgE3EFCcdMLxPhQblL3uWVhndJXA2Jc-UF-I,8051
54
+ glaip_sdk/utils/serialization.py,sha256=cUE6PxqTsfJuEEmsk_Li3QmaDavTIPotEA-BQ-v5exY,9043
51
55
  glaip_sdk/utils/validation.py,sha256=QNORcdyvuliEs4EH2_mkDgmoyT9utgl7YNhaf45SEf8,6992
52
- glaip_sdk-0.0.7.dist-info/METADATA,sha256=2NLkepPjdP_WEon0dKF2IZGi3Co6a4rzPznhpP_HAUY,4942
53
- glaip_sdk-0.0.7.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
54
- glaip_sdk-0.0.7.dist-info/entry_points.txt,sha256=EGs8NO8J1fdFMWA3CsF7sKBEvtHb_fujdCoNPhfMouE,47
55
- glaip_sdk-0.0.7.dist-info/RECORD,,
56
+ glaip_sdk-0.0.9.dist-info/METADATA,sha256=f2-GNqMR8cLgyQnA4f7TCPZv1ETZE4S8LSpQaPD6GrE,4949
57
+ glaip_sdk-0.0.9.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
58
+ glaip_sdk-0.0.9.dist-info/entry_points.txt,sha256=EGs8NO8J1fdFMWA3CsF7sKBEvtHb_fujdCoNPhfMouE,47
59
+ glaip_sdk-0.0.9.dist-info/RECORD,,