glaip-sdk 0.6.15b2__py3-none-any.whl → 0.6.16__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.
Files changed (154) hide show
  1. glaip_sdk/agents/__init__.py +27 -0
  2. glaip_sdk/agents/base.py +1196 -0
  3. glaip_sdk/cli/__init__.py +9 -0
  4. glaip_sdk/cli/account_store.py +540 -0
  5. glaip_sdk/cli/agent_config.py +78 -0
  6. glaip_sdk/cli/auth.py +699 -0
  7. glaip_sdk/cli/commands/__init__.py +5 -0
  8. glaip_sdk/cli/commands/accounts.py +746 -0
  9. glaip_sdk/cli/commands/agents.py +1509 -0
  10. glaip_sdk/cli/commands/common_config.py +104 -0
  11. glaip_sdk/cli/commands/configure.py +896 -0
  12. glaip_sdk/cli/commands/mcps.py +1356 -0
  13. glaip_sdk/cli/commands/models.py +69 -0
  14. glaip_sdk/cli/commands/tools.py +576 -0
  15. glaip_sdk/cli/commands/transcripts.py +755 -0
  16. glaip_sdk/cli/commands/update.py +61 -0
  17. glaip_sdk/cli/config.py +95 -0
  18. glaip_sdk/cli/constants.py +38 -0
  19. glaip_sdk/cli/context.py +150 -0
  20. glaip_sdk/cli/core/__init__.py +79 -0
  21. glaip_sdk/cli/core/context.py +124 -0
  22. glaip_sdk/cli/core/output.py +851 -0
  23. glaip_sdk/cli/core/prompting.py +649 -0
  24. glaip_sdk/cli/core/rendering.py +187 -0
  25. glaip_sdk/cli/display.py +355 -0
  26. glaip_sdk/cli/hints.py +57 -0
  27. glaip_sdk/cli/io.py +112 -0
  28. glaip_sdk/cli/main.py +615 -0
  29. glaip_sdk/cli/masking.py +136 -0
  30. glaip_sdk/cli/mcp_validators.py +287 -0
  31. glaip_sdk/cli/pager.py +266 -0
  32. glaip_sdk/cli/parsers/__init__.py +7 -0
  33. glaip_sdk/cli/parsers/json_input.py +177 -0
  34. glaip_sdk/cli/resolution.py +67 -0
  35. glaip_sdk/cli/rich_helpers.py +27 -0
  36. glaip_sdk/cli/slash/__init__.py +15 -0
  37. glaip_sdk/cli/slash/accounts_controller.py +578 -0
  38. glaip_sdk/cli/slash/accounts_shared.py +75 -0
  39. glaip_sdk/cli/slash/agent_session.py +285 -0
  40. glaip_sdk/cli/slash/prompt.py +256 -0
  41. glaip_sdk/cli/slash/remote_runs_controller.py +566 -0
  42. glaip_sdk/cli/slash/session.py +1708 -0
  43. glaip_sdk/cli/slash/tui/__init__.py +9 -0
  44. glaip_sdk/cli/slash/tui/accounts_app.py +876 -0
  45. glaip_sdk/cli/slash/tui/background_tasks.py +72 -0
  46. glaip_sdk/cli/slash/tui/loading.py +58 -0
  47. glaip_sdk/cli/slash/tui/remote_runs_app.py +628 -0
  48. glaip_sdk/cli/transcript/__init__.py +31 -0
  49. glaip_sdk/cli/transcript/cache.py +536 -0
  50. glaip_sdk/cli/transcript/capture.py +329 -0
  51. glaip_sdk/cli/transcript/export.py +38 -0
  52. glaip_sdk/cli/transcript/history.py +815 -0
  53. glaip_sdk/cli/transcript/launcher.py +77 -0
  54. glaip_sdk/cli/transcript/viewer.py +374 -0
  55. glaip_sdk/cli/update_notifier.py +290 -0
  56. glaip_sdk/cli/utils.py +263 -0
  57. glaip_sdk/cli/validators.py +238 -0
  58. glaip_sdk/client/__init__.py +11 -0
  59. glaip_sdk/client/_agent_payloads.py +520 -0
  60. glaip_sdk/client/agent_runs.py +147 -0
  61. glaip_sdk/client/agents.py +1335 -0
  62. glaip_sdk/client/base.py +502 -0
  63. glaip_sdk/client/main.py +249 -0
  64. glaip_sdk/client/mcps.py +370 -0
  65. glaip_sdk/client/run_rendering.py +700 -0
  66. glaip_sdk/client/shared.py +21 -0
  67. glaip_sdk/client/tools.py +661 -0
  68. glaip_sdk/client/validators.py +198 -0
  69. glaip_sdk/config/constants.py +52 -0
  70. glaip_sdk/mcps/__init__.py +21 -0
  71. glaip_sdk/mcps/base.py +345 -0
  72. glaip_sdk/models/__init__.py +90 -0
  73. glaip_sdk/models/agent.py +47 -0
  74. glaip_sdk/models/agent_runs.py +116 -0
  75. glaip_sdk/models/common.py +42 -0
  76. glaip_sdk/models/mcp.py +33 -0
  77. glaip_sdk/models/tool.py +33 -0
  78. glaip_sdk/payload_schemas/__init__.py +7 -0
  79. glaip_sdk/payload_schemas/agent.py +85 -0
  80. glaip_sdk/registry/__init__.py +55 -0
  81. glaip_sdk/registry/agent.py +164 -0
  82. glaip_sdk/registry/base.py +139 -0
  83. glaip_sdk/registry/mcp.py +253 -0
  84. glaip_sdk/registry/tool.py +232 -0
  85. glaip_sdk/runner/__init__.py +59 -0
  86. glaip_sdk/runner/base.py +84 -0
  87. glaip_sdk/runner/deps.py +112 -0
  88. glaip_sdk/runner/langgraph.py +782 -0
  89. glaip_sdk/runner/mcp_adapter/__init__.py +13 -0
  90. glaip_sdk/runner/mcp_adapter/base_mcp_adapter.py +43 -0
  91. glaip_sdk/runner/mcp_adapter/langchain_mcp_adapter.py +257 -0
  92. glaip_sdk/runner/mcp_adapter/mcp_config_builder.py +95 -0
  93. glaip_sdk/runner/tool_adapter/__init__.py +18 -0
  94. glaip_sdk/runner/tool_adapter/base_tool_adapter.py +44 -0
  95. glaip_sdk/runner/tool_adapter/langchain_tool_adapter.py +219 -0
  96. glaip_sdk/tools/__init__.py +22 -0
  97. glaip_sdk/tools/base.py +435 -0
  98. glaip_sdk/utils/__init__.py +86 -0
  99. glaip_sdk/utils/a2a/__init__.py +34 -0
  100. glaip_sdk/utils/a2a/event_processor.py +188 -0
  101. glaip_sdk/utils/agent_config.py +194 -0
  102. glaip_sdk/utils/bundler.py +267 -0
  103. glaip_sdk/utils/client.py +111 -0
  104. glaip_sdk/utils/client_utils.py +486 -0
  105. glaip_sdk/utils/datetime_helpers.py +58 -0
  106. glaip_sdk/utils/discovery.py +78 -0
  107. glaip_sdk/utils/display.py +135 -0
  108. glaip_sdk/utils/export.py +143 -0
  109. glaip_sdk/utils/general.py +61 -0
  110. glaip_sdk/utils/import_export.py +168 -0
  111. glaip_sdk/utils/import_resolver.py +492 -0
  112. glaip_sdk/utils/instructions.py +101 -0
  113. glaip_sdk/utils/rendering/__init__.py +115 -0
  114. glaip_sdk/utils/rendering/formatting.py +264 -0
  115. glaip_sdk/utils/rendering/layout/__init__.py +64 -0
  116. glaip_sdk/utils/rendering/layout/panels.py +156 -0
  117. glaip_sdk/utils/rendering/layout/progress.py +202 -0
  118. glaip_sdk/utils/rendering/layout/summary.py +74 -0
  119. glaip_sdk/utils/rendering/layout/transcript.py +606 -0
  120. glaip_sdk/utils/rendering/models.py +85 -0
  121. glaip_sdk/utils/rendering/renderer/__init__.py +55 -0
  122. glaip_sdk/utils/rendering/renderer/base.py +1024 -0
  123. glaip_sdk/utils/rendering/renderer/config.py +27 -0
  124. glaip_sdk/utils/rendering/renderer/console.py +55 -0
  125. glaip_sdk/utils/rendering/renderer/debug.py +178 -0
  126. glaip_sdk/utils/rendering/renderer/factory.py +138 -0
  127. glaip_sdk/utils/rendering/renderer/stream.py +202 -0
  128. glaip_sdk/utils/rendering/renderer/summary_window.py +79 -0
  129. glaip_sdk/utils/rendering/renderer/thinking.py +273 -0
  130. glaip_sdk/utils/rendering/renderer/toggle.py +182 -0
  131. glaip_sdk/utils/rendering/renderer/tool_panels.py +442 -0
  132. glaip_sdk/utils/rendering/renderer/transcript_mode.py +162 -0
  133. glaip_sdk/utils/rendering/state.py +204 -0
  134. glaip_sdk/utils/rendering/step_tree_state.py +100 -0
  135. glaip_sdk/utils/rendering/steps/__init__.py +34 -0
  136. glaip_sdk/utils/rendering/steps/event_processor.py +778 -0
  137. glaip_sdk/utils/rendering/steps/format.py +176 -0
  138. glaip_sdk/utils/rendering/steps/manager.py +387 -0
  139. glaip_sdk/utils/rendering/timing.py +36 -0
  140. glaip_sdk/utils/rendering/viewer/__init__.py +21 -0
  141. glaip_sdk/utils/rendering/viewer/presenter.py +184 -0
  142. glaip_sdk/utils/resource_refs.py +195 -0
  143. glaip_sdk/utils/run_renderer.py +41 -0
  144. glaip_sdk/utils/runtime_config.py +425 -0
  145. glaip_sdk/utils/serialization.py +424 -0
  146. glaip_sdk/utils/sync.py +142 -0
  147. glaip_sdk/utils/tool_detection.py +33 -0
  148. glaip_sdk/utils/validation.py +264 -0
  149. {glaip_sdk-0.6.15b2.dist-info → glaip_sdk-0.6.16.dist-info}/METADATA +4 -5
  150. glaip_sdk-0.6.16.dist-info/RECORD +160 -0
  151. glaip_sdk-0.6.15b2.dist-info/RECORD +0 -12
  152. {glaip_sdk-0.6.15b2.dist-info → glaip_sdk-0.6.16.dist-info}/WHEEL +0 -0
  153. {glaip_sdk-0.6.15b2.dist-info → glaip_sdk-0.6.16.dist-info}/entry_points.txt +0 -0
  154. {glaip_sdk-0.6.15b2.dist-info → glaip_sdk-0.6.16.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,290 @@
1
+ """Utility helpers for checking and displaying SDK update notifications.
2
+
3
+ Author:
4
+ Raymond Christopher (raymond.christopher@gdplabs.id)
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import importlib
10
+ import logging
11
+ import sys
12
+ from collections.abc import Callable, Iterable, Iterator
13
+ from contextlib import contextmanager
14
+ from typing import Any, Literal
15
+
16
+ import click
17
+ import httpx
18
+ from packaging.version import InvalidVersion, Version
19
+ from rich import box
20
+ from rich.console import Console
21
+
22
+ from glaip_sdk.branding import (
23
+ ACCENT_STYLE,
24
+ ERROR_STYLE,
25
+ SUCCESS_STYLE,
26
+ WARNING_STYLE,
27
+ )
28
+ from glaip_sdk.cli.commands.update import update_command
29
+ from glaip_sdk.cli.constants import UPDATE_CHECK_ENABLED
30
+ from glaip_sdk.cli.hints import format_command_hint
31
+ from glaip_sdk.cli.utils import command_hint
32
+ from glaip_sdk.rich_components import AIPPanel
33
+
34
+ FetchLatestVersion = Callable[[], str | None]
35
+
36
+ PYPI_JSON_URL = "https://pypi.org/pypi/{package}/json"
37
+ DEFAULT_TIMEOUT = 1.5 # seconds
38
+
39
+ _LOGGER = logging.getLogger(__name__)
40
+
41
+
42
+ def _parse_version(value: str) -> Version | None:
43
+ """Parse a version string into a `Version`, returning None on failure."""
44
+ try:
45
+ return Version(value)
46
+ except InvalidVersion:
47
+ return None
48
+
49
+
50
+ def _fetch_latest_version(package_name: str) -> str | None:
51
+ """Fetch the latest published version from PyPI."""
52
+ url = PYPI_JSON_URL.format(package=package_name)
53
+ timeout = httpx.Timeout(DEFAULT_TIMEOUT)
54
+
55
+ try:
56
+ with _suppress_library_logging():
57
+ with httpx.Client(timeout=timeout) as client:
58
+ response = client.get(url, headers={"Accept": "application/json"})
59
+ response.raise_for_status()
60
+ payload = response.json()
61
+ except httpx.HTTPError as exc:
62
+ _LOGGER.debug("Update check failed: %s", exc, exc_info=True)
63
+ return None
64
+ except ValueError as exc:
65
+ _LOGGER.debug("Invalid JSON while checking for updates: %s", exc, exc_info=True)
66
+ return None
67
+
68
+ info = payload.get("info") if isinstance(payload, dict) else None
69
+ latest_version = info.get("version") if isinstance(info, dict) else None
70
+ if isinstance(latest_version, str) and latest_version.strip():
71
+ return latest_version.strip()
72
+ return None
73
+
74
+
75
+ def _should_check_for_updates() -> bool:
76
+ """Return False when update checks are explicitly disabled."""
77
+ # Check module attribute first (for test overrides), then fall back to imported constant
78
+ module = sys.modules.get(__name__)
79
+ if module and hasattr(module, "UPDATE_CHECK_ENABLED"):
80
+ return getattr(module, "UPDATE_CHECK_ENABLED")
81
+ return UPDATE_CHECK_ENABLED
82
+
83
+
84
+ def _build_update_panel(
85
+ current_version: str,
86
+ latest_version: str,
87
+ command_text: str,
88
+ *,
89
+ show_command_hint: bool,
90
+ ) -> AIPPanel:
91
+ """Create a Rich panel that prompts the user to update."""
92
+ command_markup = format_command_hint(command_text) or command_text
93
+ message = (
94
+ f"[{WARNING_STYLE}]✨ Update available![/] "
95
+ f"{current_version} → {latest_version}\n\n"
96
+ "See the latest release notes:\n"
97
+ f"https://pypi.org/project/glaip-sdk/{latest_version}/"
98
+ )
99
+ if show_command_hint:
100
+ message += f"\n\n[{ACCENT_STYLE}]Run[/] {command_markup} to install."
101
+ return AIPPanel(
102
+ message,
103
+ title=f"[{SUCCESS_STYLE}]AIP SDK Update[/]",
104
+ box=box.ROUNDED,
105
+ padding=(0, 3),
106
+ expand=False,
107
+ )
108
+
109
+
110
+ def maybe_notify_update(
111
+ current_version: str,
112
+ *,
113
+ package_name: str = "glaip-sdk",
114
+ console: Console | None = None,
115
+ fetch_latest_version: FetchLatestVersion | None = None,
116
+ ctx: Any | None = None,
117
+ slash_command: str | None = None,
118
+ style: Literal["panel", "inline"] = "panel",
119
+ ) -> None:
120
+ """Check PyPI for a newer version and display a prompt if one exists."""
121
+ if not _should_check_for_updates():
122
+ return
123
+
124
+ fetcher = fetch_latest_version or (lambda: _fetch_latest_version(package_name))
125
+ latest_version = fetcher()
126
+ if not latest_version:
127
+ return
128
+
129
+ current = _parse_version(current_version)
130
+ latest = _parse_version(latest_version)
131
+ if current is None or latest is None or latest <= current:
132
+ return
133
+
134
+ command_text = command_hint("update", slash_command=slash_command, ctx=ctx)
135
+ if command_text is None:
136
+ return
137
+
138
+ active_console = console or Console()
139
+ should_prompt = _should_prompt_for_action(active_console, ctx)
140
+
141
+ if style == "inline":
142
+ if should_prompt:
143
+ message = (
144
+ f"[{WARNING_STYLE}]✨ Update[/] "
145
+ f"{current_version} → {latest_version} "
146
+ "- choose Update now or Skip to continue."
147
+ )
148
+ active_console.print(message)
149
+ _handle_update_decision(active_console, ctx)
150
+ return
151
+
152
+ command_markup = format_command_hint(command_text) or command_text
153
+ active_console.print(f"[{WARNING_STYLE}]✨ Update[/] {current_version} → {latest_version} - {command_markup}")
154
+ return
155
+
156
+ panel = _build_update_panel(
157
+ current_version,
158
+ latest_version,
159
+ command_text,
160
+ show_command_hint=not should_prompt,
161
+ )
162
+ active_console.print(panel)
163
+ if should_prompt:
164
+ _handle_update_decision(active_console, ctx)
165
+
166
+
167
+ def _handle_update_decision(console: Console, ctx: Any) -> None:
168
+ """Prompt the user to take action on the available update."""
169
+ choice = _prompt_update_decision(console)
170
+ if choice == "skip":
171
+ return
172
+
173
+ _run_update_command(console, ctx)
174
+
175
+
176
+ def _should_prompt_for_action(console: Console, ctx: Any | None) -> bool:
177
+ """Return True when we can safely block for interactive input."""
178
+ if ctx is None or not hasattr(ctx, "invoke"):
179
+ return False
180
+
181
+ is_interactive = getattr(console, "is_interactive", False)
182
+ if not isinstance(is_interactive, bool) or not is_interactive:
183
+ return False
184
+
185
+ is_terminal = getattr(console, "is_terminal", False)
186
+ if not isinstance(is_terminal, bool) or not is_terminal:
187
+ return False
188
+
189
+ input_method = getattr(console, "input", None)
190
+ return callable(input_method)
191
+
192
+
193
+ def _prompt_update_decision(console: Console) -> Literal["update", "skip"]:
194
+ """Ask the user to choose between updating now or skipping."""
195
+ console.print(
196
+ f"[{ACCENT_STYLE}]Select an option to continue:[/]\n"
197
+ f" [{SUCCESS_STYLE}]1.[/] Update now\n"
198
+ f" [{WARNING_STYLE}]2.[/] Skip\n"
199
+ )
200
+ console.print("[dim]Press Enter after typing your choice.[/]")
201
+
202
+ while True:
203
+ try:
204
+ response = console.input("Choice [1/2]: ").strip().lower()
205
+ except (KeyboardInterrupt, EOFError):
206
+ console.print(f"\n[{WARNING_STYLE}]Update skipped.[/]")
207
+ return "skip"
208
+
209
+ if response in {"1", "update", "u"}:
210
+ return "update"
211
+ if response in {"2", "skip", "s"}:
212
+ return "skip"
213
+
214
+ console.print(f"[{ERROR_STYLE}]Please enter 1 to update now or 2 to skip.[/]")
215
+
216
+
217
+ def _run_update_command(console: Console, ctx: Any) -> None:
218
+ """Invoke the built-in update command and surface any errors."""
219
+ try:
220
+ ctx.invoke(update_command)
221
+ except click.ClickException as exc:
222
+ exc.show()
223
+ console.print(f"[{ERROR_STYLE}]Update command exited with an error.[/]")
224
+ except click.Abort:
225
+ console.print(f"[{WARNING_STYLE}]Update aborted by user.[/]")
226
+ except Exception as exc: # pragma: no cover - defensive guard
227
+ console.print(f"[{ERROR_STYLE}]Unexpected error while running update: {exc}[/]")
228
+ else:
229
+ _refresh_installed_version(console, ctx)
230
+
231
+
232
+ @contextmanager
233
+ def _suppress_library_logging(
234
+ logger_names: Iterable[str] | None = None, *, level: int = logging.WARNING
235
+ ) -> Iterator[None]:
236
+ """Temporarily raise log level for selected libraries during update checks."""
237
+ names = tuple(logger_names) if logger_names is not None else ("httpx",)
238
+ captured: list[tuple[logging.Logger, int]] = []
239
+ try:
240
+ for name in names:
241
+ logger = logging.getLogger(name)
242
+ captured.append((logger, logger.level))
243
+ logger.setLevel(level)
244
+ yield
245
+ finally:
246
+ for logger, previous_level in captured:
247
+ logger.setLevel(previous_level)
248
+
249
+
250
+ def _refresh_installed_version(console: Console, ctx: Any) -> None:
251
+ """Reload runtime metadata after an in-process upgrade."""
252
+ new_version: str | None = None
253
+ branding_module: Any | None = None
254
+
255
+ try:
256
+ version_module = importlib.reload(importlib.import_module("glaip_sdk._version"))
257
+ new_version = getattr(version_module, "__version__", None)
258
+ except Exception as exc: # pragma: no cover - defensive guard
259
+ _LOGGER.debug("Failed to reload glaip_sdk._version: %s", exc, exc_info=True)
260
+
261
+ try:
262
+ branding_module = importlib.reload(importlib.import_module("glaip_sdk.branding"))
263
+ if new_version:
264
+ branding_module.SDK_VERSION = new_version
265
+ except Exception as exc: # pragma: no cover - defensive guard
266
+ _LOGGER.debug("Failed to update branding metadata: %s", exc, exc_info=True)
267
+ branding_module = None
268
+
269
+ session = _get_slash_session(ctx)
270
+ if session and hasattr(session, "refresh_branding"):
271
+ try:
272
+ branding_cls = getattr(branding_module, "AIPBranding", None) if branding_module else None
273
+ session.refresh_branding(new_version, branding_cls=branding_cls)
274
+ return
275
+ except Exception as exc: # pragma: no cover - defensive guard
276
+ _LOGGER.debug("Failed to refresh active slash session: %s", exc, exc_info=True)
277
+
278
+ if new_version:
279
+ console.print(f"[{SUCCESS_STYLE}]CLI now running glaip-sdk {new_version}.[/]")
280
+
281
+
282
+ def _get_slash_session(ctx: Any) -> Any | None:
283
+ """Return active slash session from the Click context if present."""
284
+ ctx_obj = getattr(ctx, "obj", None)
285
+ if isinstance(ctx_obj, dict):
286
+ return ctx_obj.get("_slash_session")
287
+ return None
288
+
289
+
290
+ __all__ = ["maybe_notify_update"]
glaip_sdk/cli/utils.py ADDED
@@ -0,0 +1,263 @@
1
+ """CLI utilities for glaip-sdk (facade for backward compatibility).
2
+
3
+ This module is a backward-compatible facade that re-exports functions from
4
+ glaip_sdk.cli.core.* modules. New code should import directly from the core modules.
5
+ The facade is deprecated and will be removed after consumers migrate to core modules;
6
+ see docs/specs/refactor/cli-core-modularization.md for the migration plan.
7
+
8
+ Authors:
9
+ Raymond Christopher (raymond.christopher@gdplabs.id)
10
+ Putu Ravindra Wiguna (putu.r.wiguna@gdplabs.id)
11
+ """ # pylint: disable=duplicate-code
12
+
13
+ from __future__ import annotations
14
+
15
+ import threading
16
+ import warnings
17
+
18
+ # Re-export from core modules
19
+ from glaip_sdk.cli.core.context import (
20
+ bind_slash_session_context,
21
+ get_client,
22
+ handle_best_effort_check,
23
+ restore_slash_session_context,
24
+ )
25
+ from glaip_sdk.cli.core.output import (
26
+ coerce_to_row,
27
+ detect_export_format,
28
+ fetch_resource_for_export,
29
+ format_datetime_fields,
30
+ format_size,
31
+ handle_ambiguous_resource,
32
+ handle_resource_export,
33
+ output_list,
34
+ output_result,
35
+ parse_json_line,
36
+ resolve_resource,
37
+ sdk_version,
38
+ # Private functions for backward compatibility (used in tests)
39
+ _build_table_group,
40
+ _build_yaml_renderable,
41
+ _coerce_result_payload,
42
+ _create_table,
43
+ _ensure_displayable,
44
+ _format_yaml_text,
45
+ _get_interface_order,
46
+ _handle_empty_items,
47
+ _handle_fallback_numeric_ambiguity,
48
+ _handle_fuzzy_pick_selection,
49
+ _handle_json_output,
50
+ _handle_json_view_ambiguity,
51
+ _handle_markdown_output,
52
+ _handle_plain_output,
53
+ _handle_questionary_ambiguity,
54
+ _handle_table_output,
55
+ _literal_str_representer,
56
+ _normalise_rows,
57
+ _normalize_interface_preference,
58
+ _print_selection_tip,
59
+ _render_markdown_list,
60
+ _render_markdown_output,
61
+ _render_plain_list,
62
+ _resolve_by_id,
63
+ _resolve_by_name_multiple_fuzzy,
64
+ _resolve_by_name_multiple_questionary,
65
+ _resolve_by_name_multiple_with_select,
66
+ _resource_tip_command,
67
+ _should_fallback_to_numeric_prompt,
68
+ _should_sort_rows,
69
+ _should_use_fuzzy_picker,
70
+ _try_fuzzy_pick,
71
+ _try_fuzzy_selection,
72
+ _try_interface_selection,
73
+ _try_questionary_selection,
74
+ _LiteralYamlDumper,
75
+ )
76
+ from glaip_sdk.cli.core.prompting import (
77
+ _FuzzyCompleter, # Private class for backward compatibility (used in tests)
78
+ _fuzzy_pick_for_resources,
79
+ prompt_export_choice_questionary,
80
+ questionary_safe_ask,
81
+ # Private functions for backward compatibility (used in tests)
82
+ _asyncio_loop_running,
83
+ _basic_prompt,
84
+ _build_resource_labels,
85
+ _build_display_parts,
86
+ _build_primary_parts,
87
+ _build_unique_labels,
88
+ _calculate_consecutive_bonus,
89
+ _calculate_exact_match_bonus,
90
+ _calculate_length_bonus,
91
+ _check_fuzzy_pick_requirements,
92
+ _extract_display_fields,
93
+ _extract_fallback_values,
94
+ _extract_id_suffix,
95
+ _get_fallback_columns,
96
+ _fuzzy_pick,
97
+ _fuzzy_score,
98
+ _is_fuzzy_match,
99
+ _is_standard_field,
100
+ _load_questionary_module,
101
+ _make_questionary_choice,
102
+ _perform_fuzzy_search,
103
+ _prompt_with_auto_select,
104
+ _rank_labels,
105
+ _row_display,
106
+ _run_questionary_in_thread,
107
+ _strip_spaces_for_matching,
108
+ )
109
+ from glaip_sdk.cli.core.rendering import (
110
+ build_renderer,
111
+ spinner_context,
112
+ stop_spinner,
113
+ update_spinner,
114
+ with_client_and_spinner,
115
+ # Private functions for backward compatibility (used in tests)
116
+ _can_use_spinner,
117
+ _register_renderer_with_session,
118
+ _spinner_stop,
119
+ _spinner_update,
120
+ _stream_supports_tty,
121
+ )
122
+
123
+ # Re-export from other modules for backward compatibility
124
+ from glaip_sdk.cli.context import get_ctx_value
125
+ from glaip_sdk.cli.hints import command_hint
126
+ from glaip_sdk.utils import is_uuid
127
+
128
+ # Re-export module-level variables for backward compatibility
129
+ # Note: console is re-exported from output.py since that's where _handle_table_output uses it
130
+ from glaip_sdk.cli.core.output import console
131
+ import logging
132
+
133
+ logger = logging.getLogger("glaip_sdk.cli.utils")
134
+ questionary = None # type: ignore[assignment]
135
+
136
+ _warn_lock = threading.Lock()
137
+ _warned = False
138
+
139
+
140
+ def _warn_once() -> None:
141
+ """Emit the deprecation warning once in a thread-safe way."""
142
+ global _warned
143
+ if _warned:
144
+ return
145
+ with _warn_lock:
146
+ if _warned:
147
+ return
148
+ warnings.warn(
149
+ "Importing from glaip_sdk.cli.utils is deprecated. Use glaip_sdk.cli.core.* modules instead.",
150
+ DeprecationWarning,
151
+ stacklevel=3,
152
+ )
153
+ _warned = True
154
+
155
+
156
+ _warn_once()
157
+
158
+ # Re-export everything for backward compatibility
159
+ __all__ = [
160
+ # Context
161
+ "bind_slash_session_context",
162
+ "get_client",
163
+ "get_ctx_value", # Re-exported from context module
164
+ "handle_best_effort_check",
165
+ "restore_slash_session_context",
166
+ # Prompting
167
+ "_FuzzyCompleter", # Private class for backward compatibility (used in tests)
168
+ "_asyncio_loop_running", # Private function for backward compatibility (used in tests)
169
+ "_basic_prompt", # Private function for backward compatibility (used in tests)
170
+ "_build_display_parts", # Private function for backward compatibility (used in tests)
171
+ "_build_primary_parts", # Private function for backward compatibility (used in tests)
172
+ "_build_resource_labels", # Private function for backward compatibility (used in tests)
173
+ "_build_unique_labels", # Private function for backward compatibility (used in tests)
174
+ "_calculate_consecutive_bonus", # Private function for backward compatibility (used in tests)
175
+ "_calculate_exact_match_bonus", # Private function for backward compatibility (used in tests)
176
+ "_calculate_length_bonus", # Private function for backward compatibility (used in tests)
177
+ "_check_fuzzy_pick_requirements", # Private function for backward compatibility (used in tests)
178
+ "_extract_display_fields", # Private function for backward compatibility (used in tests)
179
+ "_extract_fallback_values", # Private function for backward compatibility (used in tests)
180
+ "_extract_id_suffix", # Private function for backward compatibility (used in tests)
181
+ "_fuzzy_pick", # Private function for backward compatibility (used in tests)
182
+ "_fuzzy_pick_for_resources",
183
+ "_fuzzy_score", # Private function for backward compatibility (used in tests)
184
+ "_get_fallback_columns", # Private function for backward compatibility (used in tests)
185
+ "_is_fuzzy_match", # Private function for backward compatibility (used in tests)
186
+ "_is_standard_field", # Private function for backward compatibility (used in tests)
187
+ "_load_questionary_module", # Private function for backward compatibility (used in tests)
188
+ "_make_questionary_choice", # Private function for backward compatibility (used in tests)
189
+ "_perform_fuzzy_search", # Private function for backward compatibility (used in tests)
190
+ "_prompt_with_auto_select", # Private function for backward compatibility (used in tests)
191
+ "_rank_labels", # Private function for backward compatibility (used in tests)
192
+ "_row_display", # Private function for backward compatibility (used in tests)
193
+ "_run_questionary_in_thread", # Private function for backward compatibility (used in tests)
194
+ "_strip_spaces_for_matching", # Private function for backward compatibility (used in tests)
195
+ "prompt_export_choice_questionary",
196
+ "questionary_safe_ask",
197
+ # Rendering
198
+ "_can_use_spinner", # Private function for backward compatibility (used in tests)
199
+ "_register_renderer_with_session", # Private function for backward compatibility (used in tests)
200
+ "_spinner_stop", # Private function for backward compatibility (used in tests)
201
+ "_spinner_update", # Private function for backward compatibility (used in tests)
202
+ "_stream_supports_tty", # Private function for backward compatibility (used in tests)
203
+ "build_renderer",
204
+ "console", # Module-level variable for backward compatibility
205
+ "logger", # Module-level variable for backward compatibility
206
+ "questionary", # Module-level variable for backward compatibility
207
+ "spinner_context",
208
+ "stop_spinner",
209
+ "update_spinner",
210
+ "with_client_and_spinner",
211
+ # Output
212
+ "_LiteralYamlDumper", # Private class for backward compatibility (used in tests)
213
+ "_build_table_group", # Private function for backward compatibility (used in tests)
214
+ "_build_yaml_renderable", # Private function for backward compatibility (used in tests)
215
+ "_coerce_result_payload", # Private function for backward compatibility (used in tests)
216
+ "_create_table", # Private function for backward compatibility (used in tests)
217
+ "_ensure_displayable", # Private function for backward compatibility (used in tests)
218
+ "_format_yaml_text", # Private function for backward compatibility (used in tests)
219
+ "_get_interface_order", # Private function for backward compatibility (used in tests)
220
+ "_handle_empty_items", # Private function for backward compatibility (used in tests)
221
+ "_handle_fallback_numeric_ambiguity", # Private function for backward compatibility (used in tests)
222
+ "_handle_fuzzy_pick_selection", # Private function for backward compatibility (used in tests)
223
+ "_handle_json_output", # Private function for backward compatibility (used in tests)
224
+ "_handle_json_view_ambiguity", # Private function for backward compatibility (used in tests)
225
+ "_handle_markdown_output", # Private function for backward compatibility (used in tests)
226
+ "_handle_plain_output", # Private function for backward compatibility (used in tests)
227
+ "_handle_questionary_ambiguity", # Private function for backward compatibility (used in tests)
228
+ "_handle_table_output", # Private function for backward compatibility (used in tests)
229
+ "_literal_str_representer", # Private function for backward compatibility (used in tests)
230
+ "_normalise_rows", # Private function for backward compatibility (used in tests)
231
+ "_normalize_interface_preference", # Private function for backward compatibility (used in tests)
232
+ "_print_selection_tip", # Private function for backward compatibility (used in tests)
233
+ "_render_markdown_list", # Private function for backward compatibility (used in tests)
234
+ "_render_markdown_output", # Private function for backward compatibility (used in tests)
235
+ "_render_plain_list", # Private function for backward compatibility (used in tests)
236
+ "_resolve_by_id", # Private function for backward compatibility (used in tests)
237
+ "_resolve_by_name_multiple_fuzzy", # Private function for backward compatibility (used in tests)
238
+ "_resolve_by_name_multiple_questionary", # Private function for backward compatibility (used in tests)
239
+ "_resolve_by_name_multiple_with_select", # Private function for backward compatibility (used in tests)
240
+ "_resource_tip_command", # Private function for backward compatibility (used in tests)
241
+ "_should_fallback_to_numeric_prompt", # Private function for backward compatibility (used in tests)
242
+ "_should_sort_rows", # Private function for backward compatibility (used in tests)
243
+ "_should_use_fuzzy_picker", # Private function for backward compatibility (used in tests)
244
+ "_try_fuzzy_pick", # Private function for backward compatibility (used in tests)
245
+ "_try_fuzzy_selection", # Private function for backward compatibility (used in tests)
246
+ "_try_interface_selection", # Private function for backward compatibility (used in tests)
247
+ "_try_questionary_selection", # Private function for backward compatibility (used in tests)
248
+ "coerce_to_row",
249
+ "command_hint", # Re-exported from hints module
250
+ "detect_export_format",
251
+ "fetch_resource_for_export",
252
+ "format_datetime_fields",
253
+ "format_size",
254
+ "handle_ambiguous_resource",
255
+ "handle_resource_export",
256
+ "output_list",
257
+ "output_result",
258
+ "parse_json_line",
259
+ "resolve_resource",
260
+ "sdk_version",
261
+ # Utils
262
+ "is_uuid", # Re-exported from glaip_sdk.utils for backward compatibility
263
+ ]