llamactl 0.3.0a8__py3-none-any.whl → 0.3.0a9__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.
@@ -109,10 +109,12 @@ class ProjectClient(BaseClient):
109
109
  deployments_response = DeploymentsListResponse.model_validate(response.json())
110
110
  return [deployment for deployment in deployments_response.deployments]
111
111
 
112
- def get_deployment(self, deployment_id: str) -> DeploymentResponse:
112
+ def get_deployment(
113
+ self, deployment_id: str, include_events: bool = False
114
+ ) -> DeploymentResponse:
113
115
  response = self.client.get(
114
116
  f"/api/v1beta1/deployments/{deployment_id}",
115
- params={"project_id": self.project_id},
117
+ params={"project_id": self.project_id, "include_events": include_events},
116
118
  )
117
119
  return DeploymentResponse.model_validate(response.json())
118
120
 
@@ -16,6 +16,7 @@ from llama_deploy.core.schema.deployments import DeploymentResponse
16
16
  from rich.text import Text
17
17
  from textual.app import App, ComposeResult
18
18
  from textual.containers import Container, HorizontalGroup, Widget
19
+ from textual.content import Content
19
20
  from textual.message import Message
20
21
  from textual.reactive import reactive
21
22
  from textual.widgets import Button, RichLog, Static
@@ -58,6 +59,16 @@ class DeploymentMonitorWidget(Widget):
58
59
  margin-top: 1;
59
60
  }
60
61
 
62
+ .status-line .status-main {
63
+ width: auto;
64
+ }
65
+
66
+ .status-line .status-right {
67
+ width: 1fr;
68
+ text-align: right;
69
+ min-width: 12;
70
+ }
71
+
61
72
 
62
73
  """
63
74
 
@@ -87,10 +98,12 @@ class DeploymentMonitorWidget(Widget):
87
98
  yield Static("", classes="error-message", id="error_message")
88
99
 
89
100
  # Single-line status bar with colored icon and deployment ID
90
- with HorizontalGroup(classes="mb-1"):
101
+ with HorizontalGroup(classes="status-line"):
91
102
  yield Static(
92
- self._render_status_line(), classes="status-line", id="status_line"
103
+ self._render_status_line(), classes="status-main", id="status_line"
93
104
  )
105
+ yield Static("", classes="status-right", id="last_event_status")
106
+ yield Static("", classes="last-event mb-1", id="last_event_details")
94
107
 
95
108
  yield Static("Logs", classes="secondary-message log-header")
96
109
  yield RichLog(
@@ -128,7 +141,9 @@ class DeploymentMonitorWidget(Widget):
128
141
  async def _fetch_deployment(self) -> None:
129
142
  try:
130
143
  client = get_client()
131
- self.deployment = client.get_deployment(self.deployment_id)
144
+ self.deployment = client.get_deployment(
145
+ self.deployment_id, include_events=True
146
+ )
132
147
  # Clear any previous error on success
133
148
  self.error_message = ""
134
149
  except Exception as e: # pragma: no cover - network errors
@@ -271,7 +286,7 @@ class DeploymentMonitorWidget(Widget):
271
286
  return "●", gray
272
287
 
273
288
  def _render_status_line(self) -> Text:
274
- phase = self.deployment.status if self.deployment else "-"
289
+ phase = self.deployment.status if self.deployment else "Unknown"
275
290
  icon, style = self._status_icon_and_style(phase)
276
291
  line = Text()
277
292
  line.append(icon, style=style)
@@ -279,6 +294,34 @@ class DeploymentMonitorWidget(Widget):
279
294
  line.append(f"Status: {phase} — Deployment ID: {self.deployment_id or '-'}")
280
295
  return line
281
296
 
297
+ def _render_last_event_details(self) -> Content:
298
+ if not self.deployment or not self.deployment.events:
299
+ return Content()
300
+ latest = self.deployment.events[-1]
301
+ txt = Text(f" {latest.message}", style="dim")
302
+ return Content.from_rich_text(txt)
303
+
304
+ def _render_last_event_status(self) -> Content:
305
+ if not self.deployment or not self.deployment.events:
306
+ return Content()
307
+ txt = Text()
308
+ # Pick the most recent by last_timestamp
309
+ latest = self.deployment.events[-1]
310
+ ts = None
311
+ ts = (latest.last_timestamp or latest.first_timestamp).strftime(
312
+ "%Y-%m-%d %H:%M:%S"
313
+ )
314
+ parts: list[str] = []
315
+ if latest.type:
316
+ parts.append(latest.type)
317
+ if latest.reason:
318
+ parts.append(latest.reason)
319
+ kind = "/".join(parts) if parts else None
320
+ if kind:
321
+ txt.append(f"{kind} ", style="medium_purple3")
322
+ txt.append(f"{ts}", style="dim")
323
+ return Content.from_rich_text(txt)
324
+
282
325
  def on_unmount(self) -> None:
283
326
  # Attempt to stop the streaming loop
284
327
  self._stop_stream.set()
@@ -298,16 +341,16 @@ class DeploymentMonitorWidget(Widget):
298
341
  def watch_deployment(self, deployment: DeploymentResponse | None) -> None:
299
342
  if deployment is None:
300
343
  return
301
- phase = deployment.status or "-"
302
- last = getattr(self, "_last_phase", None)
303
- if last == phase:
304
- return
305
- self._last_phase = phase
306
- try:
307
- widget = self.query_one("#status_line", Static)
308
- except Exception:
309
- return
344
+
345
+ widget = self.query_one("#status_line", Static)
346
+ ev_widget = self.query_one("#last_event_status", Static)
347
+ ev_details_widget = self.query_one("#last_event_details", Static)
348
+
310
349
  widget.update(self._render_status_line())
350
+ # Update last event line
351
+ ev_widget.update(self._render_last_event_status())
352
+ ev_details_widget.update(self._render_last_event_details())
353
+ ev_details_widget.display = bool(self.deployment and self.deployment.events)
311
354
 
312
355
  def watch_wrap_enabled(self, enabled: bool) -> None:
313
356
  try:
@@ -342,7 +385,9 @@ class DeploymentMonitorWidget(Widget):
342
385
  client = get_client()
343
386
  while not self._stop_stream.is_set():
344
387
  try:
345
- self.deployment = client.get_deployment(self.deployment_id)
388
+ self.deployment = client.get_deployment(
389
+ self.deployment_id, include_events=True
390
+ )
346
391
  # Clear any previous error on success
347
392
  if self.error_message:
348
393
  self.error_message = ""
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: llamactl
3
- Version: 0.3.0a8
3
+ Version: 0.3.0a9
4
4
  Summary: A command-line interface for managing LlamaDeploy projects and deployments
5
5
  Author: Adrian Lyjak
6
6
  Author-email: Adrian Lyjak <adrianlyjak@gmail.com>
7
7
  License: MIT
8
- Requires-Dist: llama-deploy-core>=0.3.0a8,<0.4.0
9
- Requires-Dist: llama-deploy-appserver>=0.3.0a8,<0.4.0
8
+ Requires-Dist: llama-deploy-core>=0.3.0a9,<0.4.0
9
+ Requires-Dist: llama-deploy-appserver>=0.3.0a9,<0.4.0
10
10
  Requires-Dist: httpx>=0.24.0
11
11
  Requires-Dist: rich>=13.0.0
12
12
  Requires-Dist: questionary>=2.0.0
@@ -1,6 +1,6 @@
1
1
  llama_deploy/cli/__init__.py,sha256=274c45e48048bf60668ab564ae8e7c5e6daf1d7779005f87d07ce9fa7d04936c,422
2
2
  llama_deploy/cli/app.py,sha256=5200b4ac01b0ad0c405ce841fc01a12ed32f7b6474472f00a7d6c75fe274ea45,2324
3
- llama_deploy/cli/client.py,sha256=03d73191a2b89e33573b7df81b9d7586227e871451891f737d9f601d3aa47ffe,10032
3
+ llama_deploy/cli/client.py,sha256=a648bfcd07b1d4e9ad1e7d9e3ef591066ea5f45bb6fe4b8ad2c495347563794a,10110
4
4
  llama_deploy/cli/commands/aliased_group.py,sha256=6e2457cdea51de83bb7f02b37abb77cb9b5bff0a61bdddd66c43240b66b13f13,986
5
5
  llama_deploy/cli/commands/deployment.py,sha256=7874f4a499ce1bfd6ae14833410cc75c4c954463d96064cfd045421358479d4c,8810
6
6
  llama_deploy/cli/commands/init.py,sha256=da6aecb5ebc8e4cf15421227fcafd98f573f601c52f8849c00d243b572c9f56a,6285
@@ -13,14 +13,14 @@ llama_deploy/cli/interactive_prompts/utils.py,sha256=db78eba78bf347738feb89ac3ee
13
13
  llama_deploy/cli/options.py,sha256=38bb4a231ad0436d8b910c98ff659c0736f619efdf56c402d60bb3f755df38e0,598
14
14
  llama_deploy/cli/textual/deployment_form.py,sha256=5566e2545ef9548b14b7d3d2b0c1bda1dcd99aca814d34823da6b9da1903b8df,20890
15
15
  llama_deploy/cli/textual/deployment_help.py,sha256=d43e9ff29db71a842cf8b491545763d581ede3132b8af518c73af85a40950046,2464
16
- llama_deploy/cli/textual/deployment_monitor.py,sha256=1e1ea3381575d19e655a2a9eda8253c7e7fe9a02a2d637fd1fdce94500dde168,15044
16
+ llama_deploy/cli/textual/deployment_monitor.py,sha256=0c641d9d0e29cc3c1ae44d4325d8a181ba4defb24ac84ac91741812b0d0adca1,16728
17
17
  llama_deploy/cli/textual/git_validation.py,sha256=44e359d16aa879f4566a0077d025fdd799f500862a8462b5ed3586e528f7a273,13300
18
18
  llama_deploy/cli/textual/github_callback_server.py,sha256=dc74c510f8a98ef6ffaab0f6d11c7ea86ee77ca5adbc7725a2a29112bae24191,7556
19
19
  llama_deploy/cli/textual/llama_loader.py,sha256=468213a504057f21838b01f48d51f52e60aa622d6f0fe5bb800d76ced846cea9,1245
20
20
  llama_deploy/cli/textual/profile_form.py,sha256=4410678edbd59b014f937ce760bafa51ae86f6dd58bec88f048a9eda273446aa,5956
21
21
  llama_deploy/cli/textual/secrets_form.py,sha256=a43fbd81aad034d0d60906bfd917c107f9ace414648b0f63ac0b29eeba4050db,7061
22
22
  llama_deploy/cli/textual/styles.tcss,sha256=536cec7627d2a16dd03bf25bb9b6e4d53f1e0d18272b07ec0dc3bf76b0a7c2e0,3056
23
- llamactl-0.3.0a8.dist-info/WHEEL,sha256=66530aef82d5020ef5af27ae0123c71abb9261377c5bc519376c671346b12918,79
24
- llamactl-0.3.0a8.dist-info/entry_points.txt,sha256=b67e1eb64305058751a651a80f2d2268b5f7046732268421e796f64d4697f83c,52
25
- llamactl-0.3.0a8.dist-info/METADATA,sha256=f4d04dd44460d1065bbc21979f97b7194b05b6bee247ee2748a2704d857d5ea5,3166
26
- llamactl-0.3.0a8.dist-info/RECORD,,
23
+ llamactl-0.3.0a9.dist-info/WHEEL,sha256=66530aef82d5020ef5af27ae0123c71abb9261377c5bc519376c671346b12918,79
24
+ llamactl-0.3.0a9.dist-info/entry_points.txt,sha256=b67e1eb64305058751a651a80f2d2268b5f7046732268421e796f64d4697f83c,52
25
+ llamactl-0.3.0a9.dist-info/METADATA,sha256=251109a0de878a3e2599ca323c78039393c5cbfb4177aa3e8cf6331c9fc7d4c7,3166
26
+ llamactl-0.3.0a9.dist-info/RECORD,,