llamactl 0.3.0a8__tar.gz → 0.3.0a9__tar.gz
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.
- {llamactl-0.3.0a8 → llamactl-0.3.0a9}/PKG-INFO +3 -3
- {llamactl-0.3.0a8 → llamactl-0.3.0a9}/pyproject.toml +3 -3
- {llamactl-0.3.0a8 → llamactl-0.3.0a9}/src/llama_deploy/cli/client.py +4 -2
- {llamactl-0.3.0a8 → llamactl-0.3.0a9}/src/llama_deploy/cli/textual/deployment_monitor.py +59 -14
- {llamactl-0.3.0a8 → llamactl-0.3.0a9}/README.md +0 -0
- {llamactl-0.3.0a8 → llamactl-0.3.0a9}/src/llama_deploy/cli/__init__.py +0 -0
- {llamactl-0.3.0a8 → llamactl-0.3.0a9}/src/llama_deploy/cli/app.py +0 -0
- {llamactl-0.3.0a8 → llamactl-0.3.0a9}/src/llama_deploy/cli/commands/aliased_group.py +0 -0
- {llamactl-0.3.0a8 → llamactl-0.3.0a9}/src/llama_deploy/cli/commands/deployment.py +0 -0
- {llamactl-0.3.0a8 → llamactl-0.3.0a9}/src/llama_deploy/cli/commands/init.py +0 -0
- {llamactl-0.3.0a8 → llamactl-0.3.0a9}/src/llama_deploy/cli/commands/profile.py +0 -0
- {llamactl-0.3.0a8 → llamactl-0.3.0a9}/src/llama_deploy/cli/commands/serve.py +0 -0
- {llamactl-0.3.0a8 → llamactl-0.3.0a9}/src/llama_deploy/cli/config.py +0 -0
- {llamactl-0.3.0a8 → llamactl-0.3.0a9}/src/llama_deploy/cli/debug.py +0 -0
- {llamactl-0.3.0a8 → llamactl-0.3.0a9}/src/llama_deploy/cli/env.py +0 -0
- {llamactl-0.3.0a8 → llamactl-0.3.0a9}/src/llama_deploy/cli/interactive_prompts/utils.py +0 -0
- {llamactl-0.3.0a8 → llamactl-0.3.0a9}/src/llama_deploy/cli/options.py +0 -0
- {llamactl-0.3.0a8 → llamactl-0.3.0a9}/src/llama_deploy/cli/textual/deployment_form.py +0 -0
- {llamactl-0.3.0a8 → llamactl-0.3.0a9}/src/llama_deploy/cli/textual/deployment_help.py +0 -0
- {llamactl-0.3.0a8 → llamactl-0.3.0a9}/src/llama_deploy/cli/textual/git_validation.py +0 -0
- {llamactl-0.3.0a8 → llamactl-0.3.0a9}/src/llama_deploy/cli/textual/github_callback_server.py +0 -0
- {llamactl-0.3.0a8 → llamactl-0.3.0a9}/src/llama_deploy/cli/textual/llama_loader.py +0 -0
- {llamactl-0.3.0a8 → llamactl-0.3.0a9}/src/llama_deploy/cli/textual/profile_form.py +0 -0
- {llamactl-0.3.0a8 → llamactl-0.3.0a9}/src/llama_deploy/cli/textual/secrets_form.py +0 -0
- {llamactl-0.3.0a8 → llamactl-0.3.0a9}/src/llama_deploy/cli/textual/styles.tcss +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: llamactl
|
|
3
|
-
Version: 0.3.
|
|
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.
|
|
9
|
-
Requires-Dist: llama-deploy-appserver>=0.3.
|
|
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
|
[project]
|
|
2
2
|
name = "llamactl"
|
|
3
|
-
version = "0.3.
|
|
3
|
+
version = "0.3.0a9"
|
|
4
4
|
description = "A command-line interface for managing LlamaDeploy projects and deployments"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = { text = "MIT" }
|
|
@@ -9,8 +9,8 @@ authors = [
|
|
|
9
9
|
]
|
|
10
10
|
requires-python = ">=3.12, <4"
|
|
11
11
|
dependencies = [
|
|
12
|
-
"llama-deploy-core>=0.3.
|
|
13
|
-
"llama-deploy-appserver>=0.3.
|
|
12
|
+
"llama-deploy-core>=0.3.0a9,<0.4.0",
|
|
13
|
+
"llama-deploy-appserver>=0.3.0a9,<0.4.0",
|
|
14
14
|
"httpx>=0.24.0",
|
|
15
15
|
"rich>=13.0.0",
|
|
16
16
|
"questionary>=2.0.0",
|
|
@@ -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(
|
|
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="
|
|
101
|
+
with HorizontalGroup(classes="status-line"):
|
|
91
102
|
yield Static(
|
|
92
|
-
self._render_status_line(), classes="status-
|
|
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(
|
|
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
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
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(
|
|
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 = ""
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{llamactl-0.3.0a8 → llamactl-0.3.0a9}/src/llama_deploy/cli/textual/github_callback_server.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|