glaip-sdk 0.7.12__py3-none-any.whl → 0.7.13__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/agents/base.py CHANGED
@@ -185,6 +185,18 @@ class Agent:
185
185
  self._framework = kwargs.pop("framework", Agent._UNSET) # type: ignore[assignment]
186
186
  self._version = kwargs.pop("version", Agent._UNSET) # type: ignore[assignment]
187
187
  self._agent_type = kwargs.pop("agent_type", Agent._UNSET) # type: ignore[assignment]
188
+
189
+ # Handle 'type' as a legacy alias for 'agent_type'
190
+ legacy_type = kwargs.pop("type", Agent._UNSET)
191
+ if legacy_type is not Agent._UNSET:
192
+ warnings.warn(
193
+ "The 'type' parameter is deprecated and will be removed in a future version. Use 'agent_type' instead.",
194
+ DeprecationWarning,
195
+ stacklevel=2,
196
+ )
197
+ if self._agent_type is Agent._UNSET:
198
+ self._agent_type = legacy_type
199
+
188
200
  self._agent_config = kwargs.pop("agent_config", Agent._UNSET) # type: ignore[assignment]
189
201
  self._tool_configs = kwargs.pop("tool_configs", Agent._UNSET) # type: ignore[assignment]
190
202
  self._mcp_configs = kwargs.pop("mcp_configs", Agent._UNSET) # type: ignore[assignment]
@@ -848,21 +860,42 @@ class Agent:
848
860
  """Return a dict representation of the Agent.
849
861
 
850
862
  Provides Pydantic-style serialization for backward compatibility.
863
+ This implementation avoids triggering external tool resolution to ensure
864
+ it remains robust even when the environment is not fully configured.
851
865
 
852
866
  Args:
853
867
  exclude_none: If True, exclude None values from the output.
854
868
 
855
869
  Returns:
856
- Dictionary containing Agent attributes.
870
+ Dictionary containing Agent attributes. Note: Mutable fields (dicts, lists)
871
+ are returned as references. Modify with caution or make a deep copy if needed.
857
872
  """
858
- config = self._build_config(get_tool_registry(), get_mcp_registry())
873
+ # Map convenience timeout to agent_config if not already present
874
+ agent_config = self.agent_config if self.agent_config is not self._UNSET else {}
875
+ agent_config = dict(agent_config) if agent_config else {}
876
+
877
+ if self.timeout and "execution_timeout" not in agent_config:
878
+ agent_config["execution_timeout"] = self.timeout
879
+
880
+ # Handle guardrail serialization without full config build
881
+ if self.guardrail:
882
+ try:
883
+ from glaip_sdk.guardrails.serializer import ( # noqa: PLC0415
884
+ serialize_guardrail_manager,
885
+ )
886
+
887
+ agent_config["guardrails"] = serialize_guardrail_manager(self.guardrail)
888
+ except ImportError: # pragma: no cover
889
+ # Serializer not available (optional dependency); skip guardrail data
890
+ pass
859
891
 
860
892
  data = {
861
893
  "id": self._id,
862
894
  "name": self.name,
863
895
  "instruction": self.instruction,
864
896
  "description": self.description,
865
- "type": self.agent_type,
897
+ "agent_type": self.agent_type,
898
+ "type": self.agent_type, # Legacy key for backward compatibility
866
899
  "framework": self.framework,
867
900
  "version": self.version,
868
901
  "tools": self.tools,
@@ -870,7 +903,8 @@ class Agent:
870
903
  "mcps": self.mcps,
871
904
  "timeout": self.timeout,
872
905
  "metadata": self.metadata,
873
- "agent_config": config.get("agent_config"),
906
+ "model": self.model,
907
+ "agent_config": agent_config,
874
908
  "tool_configs": self.tool_configs,
875
909
  "mcp_configs": self.mcp_configs,
876
910
  "a2a_profile": self.a2a_profile,
@@ -878,6 +912,7 @@ class Agent:
878
912
  "created_at": self._created_at,
879
913
  "updated_at": self._updated_at,
880
914
  }
915
+
881
916
  if exclude_none:
882
917
  return {k: v for k, v in data.items() if v is not None}
883
918
  return data
@@ -53,6 +53,10 @@ Screen {
53
53
  margin-left: 1;
54
54
  }
55
55
 
56
+ Button:hover {
57
+ background: $surface-lighten-1;
58
+ }
59
+
56
60
  #accounts-table {
57
61
  padding: 0 1 0 1;
58
62
  margin: 0 0 0 0;
@@ -60,6 +64,14 @@ Screen {
60
64
  border: tall $primary;
61
65
  }
62
66
 
67
+ #accounts-table > .datatable--row:hover {
68
+ background: $surface-lighten-1;
69
+ }
70
+
71
+ .sidebar-block:hover {
72
+ background: $surface-lighten-1;
73
+ }
74
+
63
75
  #status-bar {
64
76
  height: 3;
65
77
  padding: 0 1;
@@ -37,11 +37,19 @@ from glaip_sdk.cli.slash.tui.terminal import TerminalCapabilities
37
37
  from glaip_sdk.cli.slash.tui.theme.catalog import _BUILTIN_THEMES
38
38
 
39
39
  try: # pragma: no cover - optional dependency
40
- from glaip_sdk.cli.slash.tui.toast import ClipboardToastMixin, Toast, ToastBus, ToastHandlerMixin, ToastVariant
40
+ from glaip_sdk.cli.slash.tui.toast import (
41
+ ClipboardToastMixin,
42
+ Toast,
43
+ ToastBus,
44
+ ToastContainer,
45
+ ToastHandlerMixin,
46
+ ToastVariant,
47
+ )
41
48
  except Exception: # pragma: no cover - optional dependency
42
49
  ClipboardToastMixin = object # type: ignore[assignment, misc]
43
50
  Toast = None # type: ignore[assignment]
44
51
  ToastBus = None # type: ignore[assignment]
52
+ ToastContainer = None # type: ignore[assignment]
45
53
  ToastHandlerMixin = object # type: ignore[assignment, misc]
46
54
  ToastVariant = None # type: ignore[assignment]
47
55
  from glaip_sdk.cli.validators import validate_api_key
@@ -51,7 +59,8 @@ try: # pragma: no cover - optional dependency
51
59
  from textual import events
52
60
  from textual.app import App, ComposeResult
53
61
  from textual.binding import Binding
54
- from textual.containers import Container, Horizontal, Vertical
62
+ from textual.containers import Horizontal, Vertical
63
+ from textual.coordinate import Coordinate
55
64
  from textual.screen import ModalScreen
56
65
  from textual.suggester import SuggestFromList
57
66
  from textual.widgets import Button, Checkbox, DataTable, Footer, Header, Input, LoadingIndicator, Static
@@ -60,9 +69,9 @@ except Exception: # pragma: no cover - optional dependency
60
69
  App = None # type: ignore[assignment]
61
70
  ComposeResult = None # type: ignore[assignment]
62
71
  Binding = None # type: ignore[assignment]
63
- Container = None # type: ignore[assignment]
64
72
  Horizontal = None # type: ignore[assignment]
65
73
  Vertical = None # type: ignore[assignment]
74
+ Coordinate = None # type: ignore[assignment]
66
75
  Button = None # type: ignore[assignment]
67
76
  Checkbox = None # type: ignore[assignment]
68
77
  DataTable = None # type: ignore[assignment]
@@ -527,7 +536,7 @@ class AccountsHarlequinScreen( # pragma: no cover - interactive
527
536
 
528
537
  def compose(self) -> ComposeResult: # type: ignore[return]
529
538
  """Compose the Harlequin layout with account list and detail panes."""
530
- if not TEXTUAL_SUPPORTED or Horizontal is None or Vertical is None or Container is None:
539
+ if not TEXTUAL_SUPPORTED or Horizontal is None or Vertical is None or Static is None:
531
540
  return # type: ignore[return-value]
532
541
 
533
542
  # Main container with horizontal split (25/75)
@@ -561,8 +570,8 @@ class AccountsHarlequinScreen( # pragma: no cover - interactive
561
570
  )
562
571
 
563
572
  # Toast container for notifications
564
- if Toast is not None:
565
- yield Container(Toast(), id="toast-container")
573
+ if Toast is not None and ToastContainer is not None:
574
+ yield ToastContainer(Toast(), id="toast-container")
566
575
 
567
576
  def on_mount(self) -> None:
568
577
  """Configure the screen after mount."""
@@ -833,6 +842,21 @@ class AccountsHarlequinScreen( # pragma: no cover - interactive
833
842
  if not self._is_switching:
834
843
  self.action_switch_account()
835
844
 
845
+ def on_data_table_cell_selected(self, event: DataTable.CellSelected) -> None: # type: ignore[override]
846
+ """Handle mouse click selection by triggering switch."""
847
+ if not TEXTUAL_SUPPORTED:
848
+ return
849
+ table = self.query_one(HARLEQUIN_ACCOUNTS_LIST_ID, DataTable)
850
+ try:
851
+ table.cursor_coordinate = (event.coordinate.row, 0)
852
+ except Exception:
853
+ return
854
+ filtered = self._filtered_rows()
855
+ if event.coordinate.row < len(filtered):
856
+ self._update_selected_account(filtered[event.coordinate.row])
857
+ if not self._is_switching:
858
+ self.action_switch_account()
859
+
836
860
  def on_data_table_cursor_row_changed(self, event: DataTable.CursorRowChanged) -> None: # type: ignore[override]
837
861
  """Handle cursor movement in the accounts list."""
838
862
  if not TEXTUAL_SUPPORTED:
@@ -875,6 +899,8 @@ class AccountsHarlequinScreen( # pragma: no cover - interactive
875
899
  """Open edit account modal."""
876
900
  if self._check_env_lock():
877
901
  return
902
+ # Get account from cursor position if not explicitly selected
903
+ self._ensure_account_selected_from_cursor()
878
904
  name = self._get_selected_name()
879
905
  if not name:
880
906
  self._set_status("Select an account to edit.", "yellow")
@@ -897,6 +923,8 @@ class AccountsHarlequinScreen( # pragma: no cover - interactive
897
923
  """Open delete confirmation modal."""
898
924
  if self._check_env_lock():
899
925
  return
926
+ # Get account from cursor position if not explicitly selected
927
+ self._ensure_account_selected_from_cursor()
900
928
  name = self._get_selected_name()
901
929
  if not name:
902
930
  self._set_status("Select an account to delete.", "yellow")
@@ -987,7 +1015,7 @@ class AccountsHarlequinScreen( # pragma: no cover - interactive
987
1015
  if output is None:
988
1016
  return None
989
1017
 
990
- def _write(sequence: str, _output=output) -> None:
1018
+ def _write(sequence: str, _output: Any = output) -> None:
991
1019
  _output.write(sequence)
992
1020
  _output.flush()
993
1021
 
@@ -1310,20 +1338,33 @@ class AccountsTextualApp( # pragma: no cover - interactive
1310
1338
  self._queue_switch(name)
1311
1339
 
1312
1340
  def on_data_table_row_selected(self, event: DataTable.RowSelected) -> None: # type: ignore[override]
1313
- """Handle mouse click selection by triggering switch.
1341
+ """Handle row selection by triggering switch."""
1342
+ self._handle_table_click(self._event_row(event))
1314
1343
 
1315
- Note: This handler is for the old table layout. When using HarlequinScreen,
1316
- the screen handles row selection directly. This handler gracefully skips
1317
- if the old table doesn't exist.
1318
- """
1344
+ def on_data_table_cell_selected(self, event: DataTable.CellSelected) -> None: # type: ignore[override]
1345
+ """Handle mouse click selection by triggering switch."""
1346
+ self._handle_table_click(self._event_row(event))
1347
+
1348
+ def _event_row(self, event: object) -> int | None:
1349
+ """Extract the row index from a DataTable event."""
1350
+ row = getattr(event, "cursor_row", None)
1351
+ if row is not None:
1352
+ return int(row)
1353
+ coordinate = getattr(event, "coordinate", None)
1354
+ return getattr(coordinate, "row", None) if coordinate is not None else None
1355
+
1356
+ def _handle_table_click(self, row: int | None) -> None:
1357
+ """Move the cursor to a clicked row and trigger the switch action."""
1358
+ if row is None:
1359
+ return
1319
1360
  try:
1320
1361
  table = self.query_one(ACCOUNTS_TABLE_ID, DataTable)
1321
1362
  except Exception:
1322
- # Harlequin screen is active, let it handle the event
1363
+ # Harlequin screen is active, let it handle the action
1323
1364
  return
1324
1365
  try:
1325
1366
  # Move cursor to clicked row then switch
1326
- table.cursor_coordinate = (event.cursor_row, 0)
1367
+ table.cursor_coordinate = Coordinate(row, 0)
1327
1368
  except Exception:
1328
1369
  return
1329
1370
  self.action_switch_row()
@@ -1654,7 +1695,7 @@ class AccountsTextualApp( # pragma: no cover - interactive
1654
1695
  if output is None:
1655
1696
  return None
1656
1697
 
1657
- def _write(sequence: str, _output=output) -> None:
1698
+ def _write(sequence: str, _output: Any = output) -> None:
1658
1699
  _output.write(sequence)
1659
1700
  _output.flush()
1660
1701
 
@@ -61,13 +61,18 @@ class TUIContext:
61
61
  store = get_account_store()
62
62
  settings = load_tui_settings(store=store)
63
63
 
64
- # Handle env var override: normalize empty strings and "default" to None
65
- # Empty string from os.getenv() is falsy, so strip() result becomes None in the or expression
66
64
  env_theme = os.getenv("AIP_TUI_THEME")
67
65
  env_theme = env_theme.strip() if env_theme else None
68
66
  if env_theme and env_theme.lower() == "default":
69
67
  env_theme = None
70
68
 
69
+ env_mouse = os.getenv("AIP_TUI_MOUSE_CAPTURE")
70
+ mouse_capture = settings.mouse_capture
71
+ if env_mouse is not None:
72
+ mouse_capture = env_mouse.lower() == "true"
73
+
74
+ terminal.mouse = mouse_capture
75
+
71
76
  theme_name = env_theme or settings.theme_name
72
77
  theme = ThemeManager(
73
78
  terminal,
@@ -19,8 +19,8 @@ from __future__ import annotations
19
19
  from typing import TYPE_CHECKING, Any
20
20
 
21
21
  try: # pragma: no cover - optional dependency
22
- from textual.containers import Container, Horizontal, Vertical
23
22
  from textual.screen import Screen
23
+ from textual.widget import Widget
24
24
  except Exception: # pragma: no cover - optional dependency
25
25
 
26
26
  class Screen: # type: ignore[no-redef]
@@ -30,23 +30,47 @@ except Exception: # pragma: no cover - optional dependency
30
30
  """Return the class for typing subscripts."""
31
31
  return cls
32
32
 
33
- Horizontal = None # type: ignore[assignment]
34
- Vertical = None # type: ignore[assignment]
35
- Container = None # type: ignore[assignment]
33
+ Widget = None # type: ignore[assignment]
36
34
 
37
35
  if TYPE_CHECKING:
38
36
  from glaip_sdk.cli.slash.tui.context import TUIContext
39
37
 
40
38
  try: # pragma: no cover - optional dependency
41
- from glaip_sdk.cli.slash.tui.toast import Toast
39
+ from glaip_sdk.cli.slash.tui.toast import Toast, ToastContainer
42
40
  except Exception: # pragma: no cover - optional dependency
43
41
  Toast = None # type: ignore[assignment, misc]
42
+ ToastContainer = None # type: ignore[assignment, misc]
44
43
 
45
44
  # GDP Labs Brand Palette
46
45
  PRIMARY_BLUE = "#005CB8"
47
46
  BLACK_BACKGROUND = "#000000"
48
47
 
49
48
 
49
+ if Widget is not None:
50
+
51
+ class HarlequinContainer(Widget):
52
+ """Base container for the Harlequin layout."""
53
+
54
+ DEFAULT_CSS = """
55
+ HarlequinContainer {
56
+ layout: horizontal;
57
+ }
58
+ """
59
+
60
+ class HarlequinPane(Widget):
61
+ """Pane container for Harlequin layout sections."""
62
+
63
+ DEFAULT_CSS = """
64
+ HarlequinPane {
65
+ layout: vertical;
66
+ }
67
+ """
68
+
69
+ else:
70
+ HarlequinContainer = None # type: ignore[assignment, misc]
71
+ HarlequinPane = None # type: ignore[assignment, misc]
72
+
73
+
50
74
  class HarlequinScreen(Screen[None]): # type: ignore[misc]
51
75
  """Base class for Harlequin-style multi-pane screens.
52
76
 
@@ -136,19 +160,19 @@ class HarlequinScreen(Screen[None]): # type: ignore[misc]
136
160
  Returns:
137
161
  ComposeResult yielding the base layout containers.
138
162
  """
139
- if Horizontal is None or Vertical is None or Container is None:
163
+ if HarlequinContainer is None or HarlequinPane is None:
140
164
  return
141
165
 
142
166
  # Main container with horizontal split (25/75)
143
- yield Horizontal(
144
- Vertical(id="left-pane"),
145
- Vertical(id="right-pane"),
167
+ yield HarlequinContainer(
168
+ HarlequinPane(id="left-pane"),
169
+ HarlequinPane(id="right-pane"),
146
170
  id="harlequin-container",
147
171
  )
148
172
 
149
173
  # Toast container for notifications
150
- if Toast is not None and Container is not None:
151
- yield Container(Toast(), id="toast-container")
174
+ if Toast is not None and ToastContainer is not None:
175
+ yield ToastContainer(Toast(), id="toast-container")
152
176
 
153
177
  @property
154
178
  def ctx(self) -> TUIContext | None:
@@ -17,18 +17,35 @@ from dataclasses import dataclass
17
17
  from typing import Any
18
18
 
19
19
  from rich.text import Text
20
- from textual.app import App, ComposeResult
21
- from textual.binding import Binding
22
- from textual.containers import Container, Horizontal, Vertical
23
- from textual.coordinate import Coordinate
24
- from textual.reactive import ReactiveError
25
- from textual.screen import ModalScreen
26
- from textual.widgets import DataTable, Footer, Header, LoadingIndicator, RichLog, Static
20
+
21
+ try: # pragma: no cover - optional dependency
22
+ from textual.app import App, ComposeResult
23
+ from textual.binding import Binding
24
+ from textual.containers import Horizontal, Vertical
25
+ from textual.coordinate import Coordinate
26
+ from textual.reactive import ReactiveError
27
+ from textual.screen import ModalScreen
28
+ from textual.widgets import DataTable, Footer, Header, LoadingIndicator, RichLog, Static
29
+ except Exception: # pragma: no cover - optional dependency
30
+ App = None # type: ignore[assignment]
31
+ ComposeResult = None # type: ignore[assignment]
32
+ Binding = None # type: ignore[assignment]
33
+ Horizontal = None # type: ignore[assignment]
34
+ Vertical = None # type: ignore[assignment]
35
+ Coordinate = None # type: ignore[assignment]
36
+ ReactiveError = Exception # type: ignore[assignment, misc]
37
+ ModalScreen = object # type: ignore[assignment, misc]
38
+ DataTable = None # type: ignore[assignment]
39
+ Footer = None # type: ignore[assignment]
40
+ Header = None # type: ignore[assignment]
41
+ LoadingIndicator = None # type: ignore[assignment]
42
+ RichLog = None # type: ignore[assignment]
43
+ Static = None # type: ignore[assignment]
27
44
 
28
45
  from glaip_sdk.cli.slash.tui.clipboard import ClipboardAdapter
29
46
  from glaip_sdk.cli.slash.tui.context import TUIContext
30
47
  from glaip_sdk.cli.slash.tui.loading import hide_loading_indicator, show_loading_indicator
31
- from glaip_sdk.cli.slash.tui.toast import ClipboardToastMixin, Toast, ToastBus, ToastHandlerMixin
48
+ from glaip_sdk.cli.slash.tui.toast import ClipboardToastMixin, Toast, ToastBus, ToastContainer, ToastHandlerMixin
32
49
 
33
50
  logger = logging.getLogger(__name__)
34
51
 
@@ -149,7 +166,7 @@ class RunDetailScreen(ToastHandlerMixin, ClipboardToastMixin, ModalScreen[None])
149
166
  RichLog(id="detail-events", wrap=False),
150
167
  )
151
168
  yield main_content
152
- yield Container(Toast(), id="toast-container")
169
+ yield ToastContainer(Toast(), id="toast-container")
153
170
  yield Footer()
154
171
 
155
172
  def on_mount(self) -> None:
@@ -369,7 +386,7 @@ class RemoteRunsTextualApp(ToastHandlerMixin, App[None]):
369
386
  def compose(self) -> ComposeResult:
370
387
  """Build layout."""
371
388
  yield Header()
372
- yield Container(Toast(), id="toast-container")
389
+ yield ToastContainer(Toast(), id="toast-container")
373
390
  table = DataTable(id=RUNS_TABLE_ID) # pragma: no cover - mocked in tests
374
391
  table.cursor_type = "row" # pragma: no cover - mocked in tests
375
392
  table.add_columns( # pragma: no cover - mocked in tests
@@ -478,6 +495,26 @@ class RemoteRunsTextualApp(ToastHandlerMixin, App[None]):
478
495
  """Track cursor position when DataTable selection changes."""
479
496
  self.cursor_index = getattr(event, "cursor_row", self.cursor_index)
480
497
 
498
+ def _handle_table_click(self, row: int | None) -> None:
499
+ if row is None:
500
+ return
501
+ table = self.query_one(RUNS_TABLE_SELECTOR, DataTable)
502
+ self.cursor_index = row
503
+ try:
504
+ table.cursor_coordinate = Coordinate(row, 0)
505
+ except Exception:
506
+ return
507
+ self.action_open_detail()
508
+
509
+ def on_data_table_row_selected(self, event: DataTable.RowSelected) -> None: # pragma: no cover - UI hook
510
+ """Handle row selection event from DataTable."""
511
+ self._handle_table_click(getattr(event, "cursor_row", None))
512
+
513
+ def on_data_table_cell_selected(self, event: DataTable.CellSelected) -> None: # pragma: no cover - UI hook
514
+ """Handle cell selection event from DataTable."""
515
+ row = getattr(event.coordinate, "row", None) if event.coordinate else None
516
+ self._handle_table_click(row)
517
+
481
518
  def action_page_left(self) -> None:
482
519
  """Navigate to the previous page."""
483
520
  if not self.current_page.has_prev:
@@ -10,6 +10,7 @@ from typing import Any, cast
10
10
 
11
11
  from rich.text import Text
12
12
  from textual.message import Message
13
+ from textual.widget import Widget
13
14
  from textual.widgets import Static
14
15
 
15
16
 
@@ -290,6 +291,19 @@ class ClipboardToastMixin:
290
291
  self._append_copy_fallback(text)
291
292
 
292
293
 
294
+ class ToastContainer(Widget):
295
+ """Simple wrapper for docking toast widgets without relying on containers.
296
+
297
+ This class exists to provide a lightweight widget wrapper for toast containers
298
+ that avoids direct dependency on Textual's Container class. It allows the toast
299
+ system to work consistently across different Textual versions and provides a
300
+ stable API for toast container composition.
301
+
302
+ Usage:
303
+ yield ToastContainer(Toast(), id="toast-container")
304
+ """
305
+
306
+
293
307
  class Toast(Static):
294
308
  """A Textual widget that displays toast notifications at the top-right of the screen.
295
309
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: glaip-sdk
3
- Version: 0.7.12
3
+ Version: 0.7.13
4
4
  Summary: Python SDK and CLI for GL AIP (GDP Labs AI Agent Package) - Build, run, and manage AI agents
5
5
  Author-email: Raymond Christopher <raymond.christopher@gdplabs.id>
6
6
  License: MIT
@@ -5,7 +5,7 @@ glaip_sdk/exceptions.py,sha256=iAChFClkytXRBLP0vZq1_YjoZxA9i4m4bW1gDLiGR1g,2321
5
5
  glaip_sdk/icons.py,sha256=J5THz0ReAmDwIiIooh1_G3Le-mwTJyEjhJDdJ13KRxM,524
6
6
  glaip_sdk/rich_components.py,sha256=44Z0V1ZQleVh9gUDGwRR5mriiYFnVGOhm7fFxZYbP8c,4052
7
7
  glaip_sdk/agents/__init__.py,sha256=VfYov56edbWuySXFEbWJ_jLXgwnFzPk1KB-9-mfsUCc,776
8
- glaip_sdk/agents/base.py,sha256=6528sEC2RGwOn0sWqiKiqf5Y_uHEuleN0nT42XlaC0U,46317
8
+ glaip_sdk/agents/base.py,sha256=TKULRlc3wSPLd901_e2h5dXorYVbGt_Nc9YHkDVqp6A,47979
9
9
  glaip_sdk/cli/__init__.py,sha256=xCCfuF1Yc7mpCDcfhHZTX0vizvtrDSLeT8MJ3V7m5A0,156
10
10
  glaip_sdk/cli/account_store.py,sha256=u_memecwEQssustZs2wYBrHbEmKUlDfmmL-zO1F3n3A,19034
11
11
  glaip_sdk/cli/agent_config.py,sha256=YAbFKrTNTRqNA6b0i0Q3pH-01rhHDRi5v8dxSFwGSwM,2401
@@ -80,18 +80,18 @@ glaip_sdk/cli/slash/prompt.py,sha256=q4f1c2zr7ZMUeO6AgOBF2Nz4qgMOXrVPt6WzPRQMbAM
80
80
  glaip_sdk/cli/slash/remote_runs_controller.py,sha256=iLl4a-mu9QU7dcedgEILewPtDIVtFUJkbKGtcx1F66U,21445
81
81
  glaip_sdk/cli/slash/session.py,sha256=YJ7UIeWyged1znmBVnGweOzH2l4NKeF5lT9VGdDvQWo,75998
82
82
  glaip_sdk/cli/slash/tui/__init__.py,sha256=oBUzeoslYwPKVlhqhgg4I7480b77vQNc9ec0NgdTC1s,977
83
- glaip_sdk/cli/slash/tui/accounts.tcss,sha256=eqFMAuN3PI3YVNDUbrCQpO1-Ko5WZpempPq75_Aejq0,2159
84
- glaip_sdk/cli/slash/tui/accounts_app.py,sha256=thS4r1NELB9K_OoEI4uJdDGSkRyhzek_2Y0k0yoPvss,71799
83
+ glaip_sdk/cli/slash/tui/accounts.tcss,sha256=GA5NFu_VSPRQdpfTaO0iUHjGDh8U0QDYqiI-WY59ZTc,2356
84
+ glaip_sdk/cli/slash/tui/accounts_app.py,sha256=mv4SzBZrAvS-q-_kMEQQbQStiJPaJ71AmvcaoXiQm0A,73518
85
85
  glaip_sdk/cli/slash/tui/background_tasks.py,sha256=SAe1mV2vXB3mJcSGhelU950vf8Lifjhws9iomyIVFKw,2422
86
86
  glaip_sdk/cli/slash/tui/clipboard.py,sha256=7fEshhTwHYaj-n7n0W0AsWTs8W0RLZw_9luXxrFTrtw,6227
87
- glaip_sdk/cli/slash/tui/context.py,sha256=v7XOdRtk5AQ4ZE-QWUhc1s9xVROu8_JjdjVnKx0X9p8,3270
87
+ glaip_sdk/cli/slash/tui/context.py,sha256=mzI4TDXnfZd42osACp5uo10d10y1_A0z6IxRK1KVoVk,3320
88
88
  glaip_sdk/cli/slash/tui/keybind_registry.py,sha256=_rK05BxTxNudYc4iJ9gDxpgeUkjDAq8rarIT-9A-jyM,6739
89
89
  glaip_sdk/cli/slash/tui/loading.py,sha256=nW5pv_Tnl9FUOPR3Qf2O5gt1AGHSo3b5-Uofg34F6AE,1909
90
- glaip_sdk/cli/slash/tui/remote_runs_app.py,sha256=DOmUHeaBg8puERn-htDnYAJgcUHETl457HamQkd0nxY,28550
90
+ glaip_sdk/cli/slash/tui/remote_runs_app.py,sha256=F50pn2VmCN6RQImhQjNZvpE4gU3eUj6dV32_w1Gg5JU,30282
91
91
  glaip_sdk/cli/slash/tui/terminal.py,sha256=ZAC3sB17TGpl-GFeRVm_nI8DQTN3pyti3ynlZ41wT_A,12323
92
- glaip_sdk/cli/slash/tui/toast.py,sha256=QLL6BBBMjEagzpSEPf3PNBNzQG_EdN5JeAigk66AjVs,11920
92
+ glaip_sdk/cli/slash/tui/toast.py,sha256=XGITLHhO40xIGmtg9hanPmDsPCQY2hQXzoM_9mJXQyg,12442
93
93
  glaip_sdk/cli/slash/tui/layouts/__init__.py,sha256=KT77pZHa7Wz84QlHYT2mfhQ_AXUA-T0eHv_HtAvc1ac,473
94
- glaip_sdk/cli/slash/tui/layouts/harlequin.py,sha256=pR5BHdWCVK0QZCyr8q6O-vCL_MTZKjMVASdYzkFUkt4,5122
94
+ glaip_sdk/cli/slash/tui/layouts/harlequin.py,sha256=JOsaK18jTojzZ-Py-87foxfijuRDWwi8LIWmqM6qS0k,5644
95
95
  glaip_sdk/cli/slash/tui/theme/__init__.py,sha256=rtM2ik83YNCRcI1qh_Sf3rnxco2OvCNNT3NbHY6cLvw,432
96
96
  glaip_sdk/cli/slash/tui/theme/catalog.py,sha256=G52eU3h8YI9D8XUALVg1KVZ4Lq65VnZdgPS3F_P7XLE,2544
97
97
  glaip_sdk/cli/slash/tui/theme/manager.py,sha256=LBnxEMIwz-8cAlZGYk5tIoAJbOJyGYsmDlyuGJ-LlX4,3945
@@ -212,8 +212,8 @@ glaip_sdk/utils/rendering/steps/format.py,sha256=Chnq7OBaj8XMeBntSBxrX5zSmrYeGcO
212
212
  glaip_sdk/utils/rendering/steps/manager.py,sha256=BiBmTeQMQhjRMykgICXsXNYh1hGsss-fH9BIGVMWFi0,13194
213
213
  glaip_sdk/utils/rendering/viewer/__init__.py,sha256=XrxmE2cMAozqrzo1jtDFm8HqNtvDcYi2mAhXLXn5CjI,457
214
214
  glaip_sdk/utils/rendering/viewer/presenter.py,sha256=mlLMTjnyeyPVtsyrAbz1BJu9lFGQSlS-voZ-_Cuugv0,5725
215
- glaip_sdk-0.7.12.dist-info/METADATA,sha256=yz1DiHtSCtTlxKsNE93PKSHWqRVDHhN-P_BUfMmUafw,8528
216
- glaip_sdk-0.7.12.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
217
- glaip_sdk-0.7.12.dist-info/entry_points.txt,sha256=NkhO6FfgX9Zrjn63GuKphf-dLw7KNJvucAcXc7P3aMk,54
218
- glaip_sdk-0.7.12.dist-info/top_level.txt,sha256=td7yXttiYX2s94-4wFhv-5KdT0rSZ-pnJRSire341hw,10
219
- glaip_sdk-0.7.12.dist-info/RECORD,,
215
+ glaip_sdk-0.7.13.dist-info/METADATA,sha256=tcKELknQg-32vMVt0GdHxK7cyIWpE-QpCKUFlTtcJeY,8528
216
+ glaip_sdk-0.7.13.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
217
+ glaip_sdk-0.7.13.dist-info/entry_points.txt,sha256=NkhO6FfgX9Zrjn63GuKphf-dLw7KNJvucAcXc7P3aMk,54
218
+ glaip_sdk-0.7.13.dist-info/top_level.txt,sha256=td7yXttiYX2s94-4wFhv-5KdT0rSZ-pnJRSire341hw,10
219
+ glaip_sdk-0.7.13.dist-info/RECORD,,