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.
Files changed (145) hide show
  1. glaip_sdk/__init__.py +42 -5
  2. glaip_sdk/agents/base.py +362 -39
  3. glaip_sdk/branding.py +113 -2
  4. glaip_sdk/cli/account_store.py +15 -0
  5. glaip_sdk/cli/auth.py +14 -8
  6. glaip_sdk/cli/commands/accounts.py +1 -1
  7. glaip_sdk/cli/commands/agents/__init__.py +116 -0
  8. glaip_sdk/cli/commands/agents/_common.py +562 -0
  9. glaip_sdk/cli/commands/agents/create.py +155 -0
  10. glaip_sdk/cli/commands/agents/delete.py +64 -0
  11. glaip_sdk/cli/commands/agents/get.py +89 -0
  12. glaip_sdk/cli/commands/agents/list.py +129 -0
  13. glaip_sdk/cli/commands/agents/run.py +264 -0
  14. glaip_sdk/cli/commands/agents/sync_langflow.py +72 -0
  15. glaip_sdk/cli/commands/agents/update.py +112 -0
  16. glaip_sdk/cli/commands/common_config.py +15 -12
  17. glaip_sdk/cli/commands/configure.py +2 -3
  18. glaip_sdk/cli/commands/mcps/__init__.py +94 -0
  19. glaip_sdk/cli/commands/mcps/_common.py +459 -0
  20. glaip_sdk/cli/commands/mcps/connect.py +82 -0
  21. glaip_sdk/cli/commands/mcps/create.py +152 -0
  22. glaip_sdk/cli/commands/mcps/delete.py +73 -0
  23. glaip_sdk/cli/commands/mcps/get.py +212 -0
  24. glaip_sdk/cli/commands/mcps/list.py +69 -0
  25. glaip_sdk/cli/commands/mcps/tools.py +235 -0
  26. glaip_sdk/cli/commands/mcps/update.py +190 -0
  27. glaip_sdk/cli/commands/models.py +2 -4
  28. glaip_sdk/cli/commands/shared/__init__.py +21 -0
  29. glaip_sdk/cli/commands/shared/formatters.py +91 -0
  30. glaip_sdk/cli/commands/tools/__init__.py +69 -0
  31. glaip_sdk/cli/commands/tools/_common.py +80 -0
  32. glaip_sdk/cli/commands/tools/create.py +228 -0
  33. glaip_sdk/cli/commands/tools/delete.py +61 -0
  34. glaip_sdk/cli/commands/tools/get.py +103 -0
  35. glaip_sdk/cli/commands/tools/list.py +69 -0
  36. glaip_sdk/cli/commands/tools/script.py +49 -0
  37. glaip_sdk/cli/commands/tools/update.py +102 -0
  38. glaip_sdk/cli/commands/transcripts/__init__.py +90 -0
  39. glaip_sdk/cli/commands/transcripts/_common.py +9 -0
  40. glaip_sdk/cli/commands/transcripts/clear.py +5 -0
  41. glaip_sdk/cli/commands/transcripts/detail.py +5 -0
  42. glaip_sdk/cli/commands/{transcripts.py → transcripts_original.py} +2 -1
  43. glaip_sdk/cli/commands/update.py +163 -17
  44. glaip_sdk/cli/config.py +1 -0
  45. glaip_sdk/cli/core/output.py +12 -7
  46. glaip_sdk/cli/entrypoint.py +20 -0
  47. glaip_sdk/cli/main.py +127 -39
  48. glaip_sdk/cli/pager.py +3 -3
  49. glaip_sdk/cli/resolution.py +2 -1
  50. glaip_sdk/cli/slash/accounts_controller.py +112 -32
  51. glaip_sdk/cli/slash/agent_session.py +5 -2
  52. glaip_sdk/cli/slash/prompt.py +11 -0
  53. glaip_sdk/cli/slash/remote_runs_controller.py +3 -1
  54. glaip_sdk/cli/slash/session.py +375 -25
  55. glaip_sdk/cli/slash/tui/__init__.py +28 -1
  56. glaip_sdk/cli/slash/tui/accounts.tcss +97 -6
  57. glaip_sdk/cli/slash/tui/accounts_app.py +1107 -126
  58. glaip_sdk/cli/slash/tui/clipboard.py +195 -0
  59. glaip_sdk/cli/slash/tui/context.py +92 -0
  60. glaip_sdk/cli/slash/tui/indicators.py +341 -0
  61. glaip_sdk/cli/slash/tui/keybind_registry.py +235 -0
  62. glaip_sdk/cli/slash/tui/layouts/__init__.py +14 -0
  63. glaip_sdk/cli/slash/tui/layouts/harlequin.py +184 -0
  64. glaip_sdk/cli/slash/tui/loading.py +43 -21
  65. glaip_sdk/cli/slash/tui/remote_runs_app.py +152 -20
  66. glaip_sdk/cli/slash/tui/terminal.py +407 -0
  67. glaip_sdk/cli/slash/tui/theme/__init__.py +15 -0
  68. glaip_sdk/cli/slash/tui/theme/catalog.py +79 -0
  69. glaip_sdk/cli/slash/tui/theme/manager.py +112 -0
  70. glaip_sdk/cli/slash/tui/theme/tokens.py +55 -0
  71. glaip_sdk/cli/slash/tui/toast.py +388 -0
  72. glaip_sdk/cli/transcript/history.py +1 -1
  73. glaip_sdk/cli/transcript/viewer.py +5 -3
  74. glaip_sdk/cli/tui_settings.py +125 -0
  75. glaip_sdk/cli/update_notifier.py +215 -7
  76. glaip_sdk/cli/validators.py +1 -1
  77. glaip_sdk/client/__init__.py +2 -1
  78. glaip_sdk/client/_schedule_payloads.py +89 -0
  79. glaip_sdk/client/agents.py +290 -16
  80. glaip_sdk/client/base.py +25 -0
  81. glaip_sdk/client/hitl.py +136 -0
  82. glaip_sdk/client/main.py +7 -5
  83. glaip_sdk/client/mcps.py +44 -13
  84. glaip_sdk/client/payloads/agent/__init__.py +23 -0
  85. glaip_sdk/client/{_agent_payloads.py → payloads/agent/requests.py} +28 -48
  86. glaip_sdk/client/payloads/agent/responses.py +43 -0
  87. glaip_sdk/client/run_rendering.py +414 -3
  88. glaip_sdk/client/schedules.py +439 -0
  89. glaip_sdk/client/tools.py +57 -26
  90. glaip_sdk/config/constants.py +22 -2
  91. glaip_sdk/guardrails/__init__.py +80 -0
  92. glaip_sdk/guardrails/serializer.py +89 -0
  93. glaip_sdk/hitl/__init__.py +48 -0
  94. glaip_sdk/hitl/base.py +64 -0
  95. glaip_sdk/hitl/callback.py +43 -0
  96. glaip_sdk/hitl/local.py +121 -0
  97. glaip_sdk/hitl/remote.py +523 -0
  98. glaip_sdk/models/__init__.py +47 -1
  99. glaip_sdk/models/_provider_mappings.py +101 -0
  100. glaip_sdk/models/_validation.py +97 -0
  101. glaip_sdk/models/agent.py +2 -1
  102. glaip_sdk/models/agent_runs.py +2 -1
  103. glaip_sdk/models/constants.py +141 -0
  104. glaip_sdk/models/model.py +170 -0
  105. glaip_sdk/models/schedule.py +224 -0
  106. glaip_sdk/payload_schemas/agent.py +1 -0
  107. glaip_sdk/payload_schemas/guardrails.py +34 -0
  108. glaip_sdk/registry/tool.py +273 -66
  109. glaip_sdk/runner/__init__.py +76 -0
  110. glaip_sdk/runner/base.py +84 -0
  111. glaip_sdk/runner/deps.py +115 -0
  112. glaip_sdk/runner/langgraph.py +1055 -0
  113. glaip_sdk/runner/logging_config.py +77 -0
  114. glaip_sdk/runner/mcp_adapter/__init__.py +13 -0
  115. glaip_sdk/runner/mcp_adapter/base_mcp_adapter.py +43 -0
  116. glaip_sdk/runner/mcp_adapter/langchain_mcp_adapter.py +257 -0
  117. glaip_sdk/runner/mcp_adapter/mcp_config_builder.py +116 -0
  118. glaip_sdk/runner/tool_adapter/__init__.py +18 -0
  119. glaip_sdk/runner/tool_adapter/base_tool_adapter.py +44 -0
  120. glaip_sdk/runner/tool_adapter/langchain_tool_adapter.py +242 -0
  121. glaip_sdk/schedules/__init__.py +22 -0
  122. glaip_sdk/schedules/base.py +291 -0
  123. glaip_sdk/tools/base.py +67 -14
  124. glaip_sdk/utils/__init__.py +1 -0
  125. glaip_sdk/utils/a2a/__init__.py +34 -0
  126. glaip_sdk/utils/a2a/event_processor.py +188 -0
  127. glaip_sdk/utils/agent_config.py +8 -2
  128. glaip_sdk/utils/bundler.py +138 -2
  129. glaip_sdk/utils/import_resolver.py +43 -11
  130. glaip_sdk/utils/rendering/renderer/base.py +58 -0
  131. glaip_sdk/utils/runtime_config.py +120 -0
  132. glaip_sdk/utils/sync.py +31 -11
  133. glaip_sdk/utils/tool_detection.py +301 -0
  134. glaip_sdk/utils/tool_storage_provider.py +140 -0
  135. {glaip_sdk-0.6.5b3.dist-info → glaip_sdk-0.7.17.dist-info}/METADATA +49 -38
  136. glaip_sdk-0.7.17.dist-info/RECORD +224 -0
  137. {glaip_sdk-0.6.5b3.dist-info → glaip_sdk-0.7.17.dist-info}/WHEEL +2 -1
  138. glaip_sdk-0.7.17.dist-info/entry_points.txt +2 -0
  139. glaip_sdk-0.7.17.dist-info/top_level.txt +1 -0
  140. glaip_sdk/cli/commands/agents.py +0 -1509
  141. glaip_sdk/cli/commands/mcps.py +0 -1356
  142. glaip_sdk/cli/commands/tools.py +0 -576
  143. glaip_sdk/cli/utils.py +0 -263
  144. glaip_sdk-0.6.5b3.dist-info/RECORD +0 -145
  145. glaip_sdk-0.6.5b3.dist-info/entry_points.txt +0 -3
glaip_sdk/branding.py CHANGED
@@ -17,6 +17,7 @@ import platform
17
17
  import sys
18
18
 
19
19
  from rich.console import Console
20
+ from rich.text import Text
20
21
 
21
22
  from glaip_sdk._version import __version__ as SDK_VERSION
22
23
  from glaip_sdk.rich_components import AIPPanel
@@ -110,9 +111,13 @@ GDP Labs AI Agents Package
110
111
  return SDK_VERSION
111
112
 
112
113
  @staticmethod
113
- def _make_console() -> Console:
114
+ def _make_console(force_terminal: bool | None = None, *, soft_wrap: bool = True) -> Console:
114
115
  """Create a Rich Console instance respecting NO_COLOR environment variables.
115
116
 
117
+ Args:
118
+ force_terminal: Override terminal detection when True/False.
119
+ soft_wrap: Whether to enable soft wrapping in the console.
120
+
116
121
  Returns:
117
122
  Console instance with color system configured based on environment.
118
123
  """
@@ -124,7 +129,12 @@ GDP Labs AI Agents Package
124
129
  else:
125
130
  color_system = "auto"
126
131
  no_color = False
127
- return Console(color_system=color_system, no_color=no_color, soft_wrap=True)
132
+ return Console(
133
+ color_system=color_system,
134
+ no_color=no_color,
135
+ soft_wrap=soft_wrap,
136
+ force_terminal=force_terminal,
137
+ )
128
138
 
129
139
  # ---- public API -----------------------------------------------------------
130
140
  def get_welcome_banner(self) -> str:
@@ -209,3 +219,104 @@ GDP Labs AI Agents Package
209
219
  AIPBranding instance
210
220
  """
211
221
  return cls(version=sdk_version, package_name=package_name)
222
+
223
+
224
+ class LogoAnimator:
225
+ """Animated logo with pulse effect for CLI startup.
226
+
227
+ Provides a "Knight Rider" style light pulse animation that sweeps across
228
+ the GL AIP logo during initialization tasks. Respects NO_COLOR and non-TTY
229
+ environments with graceful degradation.
230
+ """
231
+
232
+ # Animation colors from GDP Labs brand palette
233
+ BASE_BLUE = SECONDARY_MEDIUM # "#005CB8" - Medium Blue
234
+ HIGHLIGHT = SECONDARY_LIGHT # "#40B4E5" - Light Blue
235
+ WHITE = "#FFFFFF" # Bright white center
236
+
237
+ def __init__(self, console: Console | None = None) -> None:
238
+ """Initialize LogoAnimator.
239
+
240
+ Args:
241
+ console: Optional console instance. If None, creates a default console.
242
+ """
243
+ self.console = console or AIPBranding._make_console()
244
+ self.logo = AIPBranding.AIP_LOGO
245
+ self.lines = self.logo.split("\n")
246
+ self.max_width = max(len(line) for line in self.lines) if self.lines else 0
247
+
248
+ def generate_frame(self, step: int, status_text: str = "") -> Text:
249
+ """Generate a single animation frame with logo pulse and status.
250
+
251
+ Args:
252
+ step: Current animation step (position of the pulse).
253
+ status_text: Optional status text to display below the logo.
254
+
255
+ Returns:
256
+ Text object with styled logo and status.
257
+ """
258
+ text = Text()
259
+
260
+ for line in self.lines:
261
+ for x, char in enumerate(line):
262
+ distance = abs(x - step)
263
+
264
+ if distance == 0:
265
+ style = f"bold {self.WHITE}" # Bright white center
266
+ elif distance <= 3:
267
+ style = f"bold {self.HIGHLIGHT}" # Light blue glow
268
+ else:
269
+ style = self.BASE_BLUE # Base blue
270
+
271
+ text.append(char, style=style)
272
+ text.append("\n")
273
+
274
+ # Add status area below the logo
275
+ if status_text:
276
+ text.append(f"\n{status_text}\n")
277
+
278
+ return text
279
+
280
+ def should_animate(self) -> bool:
281
+ """Check if animation should be used.
282
+
283
+ Returns:
284
+ True if animation should be used (interactive TTY with colors),
285
+ False otherwise (NO_COLOR set or non-TTY).
286
+ """
287
+ # Check for NO_COLOR environment variables
288
+ no_color = os.getenv("NO_COLOR") is not None or os.getenv("AIP_NO_COLOR") is not None
289
+ if no_color:
290
+ return False
291
+
292
+ # Check if console is a TTY
293
+ if not self.console.is_terminal:
294
+ return False
295
+
296
+ # Check if console explicitly disables colors
297
+ if self.console.no_color:
298
+ return False
299
+
300
+ # If we get here, we have a TTY without NO_COLOR set
301
+ # Rich will handle color detection, so we can animate
302
+ return True
303
+
304
+ def display_static_logo(self, status_text: str = "") -> None:
305
+ """Display static logo without animation (for non-TTY or NO_COLOR).
306
+
307
+ Args:
308
+ status_text: Optional status text to display below the logo.
309
+ """
310
+ self.console.print(self.static_frame(status_text))
311
+
312
+ def static_frame(self, status_text: str = "") -> Text:
313
+ """Return a static logo frame for use in non-animated renders.
314
+
315
+ Args:
316
+ status_text: Optional status text to display below the logo.
317
+ """
318
+ logo_text = Text(self.logo, style=self.BASE_BLUE)
319
+ if status_text:
320
+ logo_text.append("\n")
321
+ logo_text.append(status_text)
322
+ return logo_text
@@ -523,6 +523,21 @@ class AccountStore:
523
523
 
524
524
  self._save_config(config)
525
525
 
526
+ def save_config_updates(self, config: dict[str, Any]) -> None:
527
+ """Save config updates, preserving all existing keys.
528
+
529
+ This method allows external code to update arbitrary config keys
530
+ (e.g., TUI preferences) while preserving the full config structure.
531
+
532
+ Args:
533
+ config: Complete configuration dictionary to save. This should
534
+ include all keys that should be preserved, not just updates.
535
+
536
+ Raises:
537
+ AccountStoreError: If config file cannot be written.
538
+ """
539
+ self._save_config(config)
540
+
526
541
 
527
542
  # Global instance for convenience
528
543
  _account_store = AccountStore()
glaip_sdk/cli/auth.py CHANGED
@@ -19,8 +19,7 @@ from rich.console import Console
19
19
 
20
20
  from glaip_sdk.branding import HINT_PREFIX_STYLE, WARNING_STYLE
21
21
  from glaip_sdk.cli.account_store import AccountNotFoundError, AccountStoreError, get_account_store
22
- from glaip_sdk.cli.hints import format_command_hint
23
- from glaip_sdk.cli.utils import command_hint
22
+ from glaip_sdk.cli.hints import command_hint, format_command_hint
24
23
 
25
24
 
26
25
  def prepare_authentication_export(
@@ -526,12 +525,19 @@ def resolve_api_url_from_context(
526
525
  elif hasattr(ctx, "obj") and isinstance(ctx.obj, dict):
527
526
  account_name = ctx.obj.get("account_name")
528
527
 
529
- resolved_url, _, _ = resolve_credentials(
530
- account_name=account_name,
531
- api_url=api_url,
532
- api_key=None,
533
- ignore_env_creds=True,
534
- )
528
+ if isinstance(api_url, str) and api_url.strip():
529
+ return api_url.strip()
530
+
531
+ try:
532
+ resolved_url, _, _ = resolve_credentials(
533
+ account_name=account_name,
534
+ api_url=None,
535
+ api_key=None,
536
+ ignore_env_creds=True,
537
+ )
538
+ except Exception:
539
+ return None
540
+
535
541
  return resolved_url
536
542
 
537
543
 
@@ -33,7 +33,7 @@ from glaip_sdk.cli.commands.common_config import check_connection, render_brandi
33
33
  from glaip_sdk.cli.hints import format_command_hint
34
34
  from glaip_sdk.cli.masking import mask_api_key_display
35
35
  from glaip_sdk.cli.slash.accounts_shared import env_credentials_present
36
- from glaip_sdk.cli.utils import command_hint
36
+ from glaip_sdk.cli.hints import command_hint
37
37
  from glaip_sdk.icons import ICON_TOOL
38
38
  from glaip_sdk.rich_components import AIPPanel, AIPTable
39
39
 
@@ -0,0 +1,116 @@
1
+ """Agent CLI commands package.
2
+
3
+ This package contains agent management commands split by operation.
4
+ The package is the canonical import surface.
5
+
6
+ Authors:
7
+ Raymond Christopher (raymond.christopher@gdplabs.id)
8
+ """
9
+
10
+ # pylint: disable=duplicate-code
11
+ # Import from submodules
12
+ from glaip_sdk.cli.commands.agents._common import ( # noqa: E402
13
+ AGENT_NOT_FOUND_ERROR,
14
+ _coerce_mapping_candidate,
15
+ _display_agent_details,
16
+ _emit_verbose_guidance,
17
+ _fetch_full_agent_details,
18
+ _get_agent_for_update,
19
+ _get_agent_model_name,
20
+ _get_language_model_display_name,
21
+ _model_from_config,
22
+ _prepare_agent_output,
23
+ _resolve_agent,
24
+ _resolve_resources_by_name,
25
+ agents_group,
26
+ console,
27
+ )
28
+ from glaip_sdk.cli.commands.agents.create import create # noqa: E402
29
+ from glaip_sdk.cli.commands.agents.delete import delete # noqa: E402
30
+ from glaip_sdk.cli.commands.agents.get import get # noqa: E402
31
+ from glaip_sdk.cli.commands.agents.list import list_agents # noqa: E402
32
+ from glaip_sdk.cli.commands.agents.run import _maybe_attach_transcript_toggle, run # noqa: E402
33
+ from glaip_sdk.cli.commands.agents.sync_langflow import sync_langflow # noqa: E402
34
+ from glaip_sdk.cli.commands.agents.update import update # noqa: E402
35
+
36
+ # Import core functions for test compatibility
37
+ from glaip_sdk.cli.core.context import get_client # noqa: E402
38
+
39
+ # Import core output functions for test compatibility
40
+ from glaip_sdk.cli.core.output import ( # noqa: E402
41
+ handle_resource_export,
42
+ output_list,
43
+ )
44
+
45
+ # Import rendering functions for test compatibility
46
+ from glaip_sdk.cli.core.rendering import ( # noqa: E402
47
+ build_renderer,
48
+ with_client_and_spinner, # noqa: E402
49
+ )
50
+
51
+ # Import display functions for test compatibility
52
+ # Import display functions for test compatibility
53
+ from glaip_sdk.cli.display import ( # noqa: E402 # noqa: E402
54
+ display_agent_run_suggestions,
55
+ handle_json_output,
56
+ handle_rich_output,
57
+ )
58
+
59
+ # Import IO functions for test compatibility
60
+ from glaip_sdk.cli.io import ( # noqa: E402
61
+ fetch_raw_resource_details,
62
+ )
63
+
64
+ # Import rich helpers for test compatibility
65
+ from glaip_sdk.cli.rich_helpers import ( # noqa: E402
66
+ markup_text,
67
+ )
68
+
69
+ # Import transcript functions for test compatibility
70
+ from glaip_sdk.cli.transcript import ( # noqa: E402
71
+ maybe_launch_post_run_viewer,
72
+ store_transcript_for_session,
73
+ )
74
+
75
+ # Import utils for test compatibility
76
+ from glaip_sdk.utils import ( # noqa: E402
77
+ is_uuid,
78
+ )
79
+
80
+ __all__ = [
81
+ "AGENT_NOT_FOUND_ERROR",
82
+ "agents_group",
83
+ "create",
84
+ "delete",
85
+ "get",
86
+ "list_agents",
87
+ "run",
88
+ "sync_langflow",
89
+ "update",
90
+ "_get_agent_for_update",
91
+ "_resolve_agent",
92
+ "_coerce_mapping_candidate",
93
+ "_display_agent_details",
94
+ "_emit_verbose_guidance",
95
+ "_fetch_full_agent_details",
96
+ "_get_agent_model_name",
97
+ "_get_language_model_display_name",
98
+ "_model_from_config",
99
+ "_prepare_agent_output",
100
+ "_resolve_resources_by_name",
101
+ "_maybe_attach_transcript_toggle",
102
+ "get_client",
103
+ "with_client_and_spinner",
104
+ "console",
105
+ "handle_json_output",
106
+ "handle_rich_output",
107
+ "output_list",
108
+ "handle_resource_export",
109
+ "build_renderer",
110
+ "display_agent_run_suggestions",
111
+ "markup_text",
112
+ "maybe_launch_post_run_viewer",
113
+ "store_transcript_for_session",
114
+ "fetch_raw_resource_details",
115
+ "is_uuid",
116
+ ]