glaip-sdk 0.7.27__py3-none-any.whl → 0.7.29__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.
@@ -9,6 +9,7 @@ from enum import Enum
9
9
  from typing import Any, cast
10
10
 
11
11
  from rich.text import Text
12
+ from textual.app import ComposeResult
12
13
  from textual.message import Message
13
14
  from textual.widget import Widget
14
15
  from textual.widgets import Static
@@ -55,13 +56,25 @@ class ToastBus:
55
56
  """Initialize the toast bus with optional change callback."""
56
57
  self._state: ToastState | None = None
57
58
  self._dismiss_task: asyncio.Task[None] | None = None
58
- self._on_change = on_change
59
+ self._subscribers: list[Callable[[ToastBus.Changed], None]] = []
60
+ if on_change is not None:
61
+ self._subscribers.append(on_change)
59
62
 
60
63
  @property
61
64
  def state(self) -> ToastState | None:
62
65
  """Return the current toast state, or None if no toast is shown."""
63
66
  return self._state
64
67
 
68
+ def subscribe(self, callback: Callable[[ToastBus.Changed], None]) -> None:
69
+ """Register a callback to be notified of toast state changes."""
70
+ if callback not in self._subscribers:
71
+ self._subscribers.append(callback)
72
+
73
+ def unsubscribe(self, callback: Callable[[ToastBus.Changed], None]) -> None:
74
+ """Unregister a toast callback."""
75
+ if callback in self._subscribers:
76
+ self._subscribers.remove(callback)
77
+
65
78
  def show(
66
79
  self,
67
80
  message: str,
@@ -146,8 +159,12 @@ class ToastBus:
146
159
  self._notify_changed()
147
160
 
148
161
  def _notify_changed(self) -> None:
149
- if self._on_change:
150
- self._on_change(ToastBus.Changed(self._state))
162
+ message = ToastBus.Changed(self._state)
163
+ for callback in tuple(self._subscribers):
164
+ try:
165
+ callback(message)
166
+ except Exception:
167
+ pass
151
168
 
152
169
 
153
170
  class ToastHandlerMixin:
@@ -303,6 +320,15 @@ class ToastContainer(Widget):
303
320
  yield ToastContainer(Toast(), id="toast-container")
304
321
  """
305
322
 
323
+ def __init__(self, toast: Toast, id: str | None = None) -> None:
324
+ """Initialize the toast container with a toast widget."""
325
+ super().__init__(id=id)
326
+ self._toast = toast
327
+
328
+ def compose(self) -> ComposeResult:
329
+ """Compose the container by yielding the toast widget."""
330
+ yield self._toast
331
+
306
332
 
307
333
  class Toast(Static):
308
334
  """A Textual widget that displays toast notifications at the top-right of the screen.
@@ -145,9 +145,31 @@ class ImportResolver:
145
145
  return self._is_local_package_import(node.module)
146
146
 
147
147
  # Handle simple module imports
148
+ # First, check if it's the package root (matched via project markers)
149
+ if self._is_package_root_import(node.module):
150
+ return True
151
+
152
+ # Then check for local file in tool_dir
148
153
  potential_file = self.tool_dir / f"{node.module}.py"
149
154
  return potential_file.exists()
150
155
 
156
+ def _is_package_root_import(self, module_name: str) -> bool:
157
+ """Check if a simple module name is a package root in the ancestor chain.
158
+
159
+ Args:
160
+ module_name: Simple module name (no dots).
161
+
162
+ Returns:
163
+ True if the module name matches any parent directory that could be a package.
164
+ """
165
+ # Check all ancestors for a matching directory name
166
+ current = self.tool_dir
167
+ while current != current.parent:
168
+ if module_name == current.name:
169
+ return True
170
+ current = current.parent
171
+ return False
172
+
151
173
  def _is_local_relative_import(self, node: ast.ImportFrom) -> bool:
152
174
  """Check if a relative import is local.
153
175
 
@@ -366,7 +388,22 @@ class ImportResolver:
366
388
  """
367
389
  if "." in module_name:
368
390
  return self._resolve_dotted_module_path(module_name)
369
- return self.tool_dir / f"{module_name}.py"
391
+
392
+ # For simple module names, check if it's a file in tool_dir or an ancestor package
393
+ potential_file = self.tool_dir / f"{module_name}.py"
394
+ if potential_file.exists():
395
+ return potential_file
396
+
397
+ # Check if it's an ancestor package (directory with __init__.py)
398
+ current = self.tool_dir
399
+ while current != current.parent:
400
+ potential_package_init = current / module_name / INIT_FILE
401
+ if potential_package_init.exists():
402
+ return potential_package_init
403
+ current = current.parent
404
+
405
+ # Fallback to the file path (will fail later if not found)
406
+ return potential_file
370
407
 
371
408
  def resolve_relative_import_path(self, node: ast.ImportFrom) -> Path:
372
409
  """Resolve relative import to file path.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: glaip-sdk
3
- Version: 0.7.27
3
+ Version: 0.7.29
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
@@ -81,18 +81,18 @@ glaip_sdk/cli/slash/agent_session.py,sha256=tuVOme-NbEyr6rwJvsBEKZYWQmsaRf4piJeR
81
81
  glaip_sdk/cli/slash/prompt.py,sha256=q4f1c2zr7ZMUeO6AgOBF2Nz4qgMOXrVPt6WzPRQMbAM,8501
82
82
  glaip_sdk/cli/slash/remote_runs_controller.py,sha256=iLl4a-mu9QU7dcedgEILewPtDIVtFUJkbKGtcx1F66U,21445
83
83
  glaip_sdk/cli/slash/session.py,sha256=lWK4iCb4HGnHZf251kP_1iyH8J0BaTlwSs3XJWfYOuI,76146
84
- glaip_sdk/cli/slash/tui/__init__.py,sha256=N0nRo_IGIQ3l5LikZTDrwbK5HX9nqYNzwpFeM9crJQg,1109
84
+ glaip_sdk/cli/slash/tui/__init__.py,sha256=mhX89VfkWFLCvSnu7ffIssbBgtqeTAJ3s90uf11HoFs,1107
85
85
  glaip_sdk/cli/slash/tui/accounts.tcss,sha256=5iVZZfS10CTJhnoZ9AFJejtj8nyQXH9xV7u9k8jSkGE,2411
86
- glaip_sdk/cli/slash/tui/accounts_app.py,sha256=CFjAHV0JbTSMoMoCQ0CIGa_8C8xypjHgV-VLDji-uzk,73590
86
+ glaip_sdk/cli/slash/tui/accounts_app.py,sha256=TXAs2VmXvBeK0r09InL1H5liean789r4iTii9kRLm7Q,75578
87
87
  glaip_sdk/cli/slash/tui/background_tasks.py,sha256=SAe1mV2vXB3mJcSGhelU950vf8Lifjhws9iomyIVFKw,2422
88
88
  glaip_sdk/cli/slash/tui/clipboard.py,sha256=Rb1n6nYsjTgMfSMTVo4HisW8ZM3na2REtd3OHEy-Lz0,11255
89
89
  glaip_sdk/cli/slash/tui/context.py,sha256=mzI4TDXnfZd42osACp5uo10d10y1_A0z6IxRK1KVoVk,3320
90
90
  glaip_sdk/cli/slash/tui/indicators.py,sha256=jV3fFvEVWQ0inWJJ-B1fMsdkF0Uq2zwX3xcl0YWPHSE,11768
91
91
  glaip_sdk/cli/slash/tui/keybind_registry.py,sha256=_rK05BxTxNudYc4iJ9gDxpgeUkjDAq8rarIT-9A-jyM,6739
92
92
  glaip_sdk/cli/slash/tui/loading.py,sha256=Ku7HyQ_h-r2dJQ5aIEaCOi5PUu5gSsYle8oiKHIxfKI,2336
93
- glaip_sdk/cli/slash/tui/remote_runs_app.py,sha256=HtjrSKC_mqrzVBmK3ycehaRtaBEK3HsqDDkDp16kbvc,30356
93
+ glaip_sdk/cli/slash/tui/remote_runs_app.py,sha256=Rm_Fo8WNyTHWNj2aGwTnYsV-QVUCCSbT380D8Cio3uM,40618
94
94
  glaip_sdk/cli/slash/tui/terminal.py,sha256=ZAC3sB17TGpl-GFeRVm_nI8DQTN3pyti3ynlZ41wT_A,12323
95
- glaip_sdk/cli/slash/tui/toast.py,sha256=3M7mtJAZfEWtMNhC8f1SpUCDZ_jlqhXRt_ll2Mohfg8,12435
95
+ glaip_sdk/cli/slash/tui/toast.py,sha256=UmP0_UAQcp0mOdX1iIS8W3gGDb14Z3kYGmbN_NvYDls,13494
96
96
  glaip_sdk/cli/slash/tui/layouts/__init__.py,sha256=KT77pZHa7Wz84QlHYT2mfhQ_AXUA-T0eHv_HtAvc1ac,473
97
97
  glaip_sdk/cli/slash/tui/layouts/harlequin.py,sha256=JOsaK18jTojzZ-Py-87foxfijuRDWwi8LIWmqM6qS0k,5644
98
98
  glaip_sdk/cli/slash/tui/theme/__init__.py,sha256=rtM2ik83YNCRcI1qh_Sf3rnxco2OvCNNT3NbHY6cLvw,432
@@ -179,7 +179,7 @@ glaip_sdk/utils/display.py,sha256=zu3SYqxj9hPyEN8G1vIXv_yXBkV8jLLCXEg2rs8NlzM,44
179
179
  glaip_sdk/utils/export.py,sha256=1NxxE3wGsA1auzecG5oJw5ELB4VmPljoeIkGhrGOh1I,5006
180
180
  glaip_sdk/utils/general.py,sha256=3HSVIopUsIymPaim-kP2lqLX75TkkdIVLe6g3UKabZ0,1507
181
181
  glaip_sdk/utils/import_export.py,sha256=RCvoydm_6_L7_J1igcE6IYDunqgS5mQUbWT4VGrytMw,5510
182
- glaip_sdk/utils/import_resolver.py,sha256=82kSV9eAlzBiwPI8rkeXVrNjlpXa5q9fvRoJxE6b-6U,27706
182
+ glaip_sdk/utils/import_resolver.py,sha256=Vwvg1FoODM15MiQ3A7d3fImSP13bYHOnD8WoxVL49L0,29131
183
183
  glaip_sdk/utils/instructions.py,sha256=MTk93lsq3I8aRnvnRMSXXNMzcpnaIM_Pm3Aiiiq3GBc,2997
184
184
  glaip_sdk/utils/resource_refs.py,sha256=vF34kyAtFBLnaKnQVrsr2st1JiSxVbIZ4yq0DelJvCI,5966
185
185
  glaip_sdk/utils/run_renderer.py,sha256=d_VMI6LbvHPUUeRmGqh5wK_lHqDEIAcym2iqpbtDad0,1365
@@ -220,8 +220,8 @@ glaip_sdk/utils/rendering/steps/format.py,sha256=Chnq7OBaj8XMeBntSBxrX5zSmrYeGcO
220
220
  glaip_sdk/utils/rendering/steps/manager.py,sha256=BiBmTeQMQhjRMykgICXsXNYh1hGsss-fH9BIGVMWFi0,13194
221
221
  glaip_sdk/utils/rendering/viewer/__init__.py,sha256=XrxmE2cMAozqrzo1jtDFm8HqNtvDcYi2mAhXLXn5CjI,457
222
222
  glaip_sdk/utils/rendering/viewer/presenter.py,sha256=mlLMTjnyeyPVtsyrAbz1BJu9lFGQSlS-voZ-_Cuugv0,5725
223
- glaip_sdk-0.7.27.dist-info/METADATA,sha256=HyJsU7u9HVgBLRBB98dFPY2oZOI0js_B8O00Ce-eSiE,8686
224
- glaip_sdk-0.7.27.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
225
- glaip_sdk-0.7.27.dist-info/entry_points.txt,sha256=NkhO6FfgX9Zrjn63GuKphf-dLw7KNJvucAcXc7P3aMk,54
226
- glaip_sdk-0.7.27.dist-info/top_level.txt,sha256=td7yXttiYX2s94-4wFhv-5KdT0rSZ-pnJRSire341hw,10
227
- glaip_sdk-0.7.27.dist-info/RECORD,,
223
+ glaip_sdk-0.7.29.dist-info/METADATA,sha256=2o46ltEDzkNONFYMdCfFR5x_qR1h77MiS3OJeuINYYY,8686
224
+ glaip_sdk-0.7.29.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
225
+ glaip_sdk-0.7.29.dist-info/entry_points.txt,sha256=NkhO6FfgX9Zrjn63GuKphf-dLw7KNJvucAcXc7P3aMk,54
226
+ glaip_sdk-0.7.29.dist-info/top_level.txt,sha256=td7yXttiYX2s94-4wFhv-5KdT0rSZ-pnJRSire341hw,10
227
+ glaip_sdk-0.7.29.dist-info/RECORD,,