qbraid-cli 0.16.4__tar.gz → 0.16.5__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.
- {qbraid_cli-0.16.4/qbraid_cli.egg-info → qbraid_cli-0.16.5}/PKG-INFO +4 -4
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/pyproject.toml +4 -4
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/agents/app.py +77 -33
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5/qbraid_cli.egg-info}/PKG-INFO +4 -4
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli.egg-info/requires.txt +3 -3
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/LICENSE +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/README.md +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/__init__.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/_build_info.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/_version.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/account/__init__.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/account/app.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/admin/__init__.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/admin/app.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/admin/headers.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/admin/validation.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/agents/__init__.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/agents/permission_response.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/ai/__init__.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/ai/app.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/ai/token.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/comms/__init__.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/comms/app.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/compute/__init__.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/compute/app.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/compute/instances.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/compute/profiles.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/compute/server.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/compute/ssh.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/configure/__init__.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/configure/actions.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/configure/app.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/devices/__init__.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/devices/app.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/devices/validation.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/envs/__init__.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/envs/activate.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/envs/app.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/envs/create.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/envs/data_handling.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/envs/groups.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/envs/publish.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/envs/registry.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/envs/share.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/exceptions.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/handlers.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/jobs/__init__.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/jobs/app.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/jobs/groups.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/kernels/__init__.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/kernels/app.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/lab/__init__.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/lab/app.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/main.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/pip/__init__.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/pip/app.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/pip/hooks.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/projects/__init__.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/projects/app.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/py.typed +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/skills/__init__.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/skills/app.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/troubleshoot/__init__.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli/troubleshoot/app.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli.egg-info/SOURCES.txt +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli.egg-info/dependency_links.txt +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli.egg-info/entry_points.txt +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/qbraid_cli.egg-info/top_level.txt +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/setup.cfg +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/tests/test_cli_e2e.py +0 -0
- {qbraid_cli-0.16.4 → qbraid_cli-0.16.5}/tests/test_version.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: qbraid-cli
|
|
3
|
-
Version: 0.16.
|
|
3
|
+
Version: 0.16.5
|
|
4
4
|
Summary: Command Line Interface for interacting with all parts of the qBraid platform.
|
|
5
5
|
Author-email: qBraid Development Team <contact@qbraid.com>
|
|
6
6
|
License-Expression: LicenseRef-Proprietary
|
|
@@ -30,11 +30,11 @@ Requires-Dist: typer>=0.12.1
|
|
|
30
30
|
Requires-Dist: rich>=10.11.0
|
|
31
31
|
Requires-Dist: click<=8.5.0
|
|
32
32
|
Requires-Dist: questionary>=2.0.0
|
|
33
|
-
Requires-Dist: qbraid-core>=0.6.
|
|
33
|
+
Requires-Dist: qbraid-core>=0.6.12
|
|
34
34
|
Provides-Extra: compute
|
|
35
|
-
Requires-Dist: qbraid-core[compute]>=0.6.
|
|
35
|
+
Requires-Dist: qbraid-core[compute]>=0.6.12; extra == "compute"
|
|
36
36
|
Provides-Extra: envs
|
|
37
|
-
Requires-Dist: qbraid-core[environments]>=0.6.
|
|
37
|
+
Requires-Dist: qbraid-core[environments]>=0.6.12; extra == "envs"
|
|
38
38
|
Provides-Extra: dev
|
|
39
39
|
Requires-Dist: isort; extra == "dev"
|
|
40
40
|
Requires-Dist: black; extra == "dev"
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "qbraid-cli"
|
|
7
|
-
version = "0.16.
|
|
7
|
+
version = "0.16.5"
|
|
8
8
|
description = "Command Line Interface for interacting with all parts of the qBraid platform."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
authors = [{ name = "qBraid Development Team", email = "contact@qbraid.com" }]
|
|
@@ -32,7 +32,7 @@ dependencies = [
|
|
|
32
32
|
"rich>=10.11.0",
|
|
33
33
|
"click<=8.5.0",
|
|
34
34
|
"questionary>=2.0.0",
|
|
35
|
-
"qbraid-core>=0.6.
|
|
35
|
+
"qbraid-core>=0.6.12",
|
|
36
36
|
]
|
|
37
37
|
requires-python = ">= 3.10"
|
|
38
38
|
|
|
@@ -43,8 +43,8 @@ Documentation = "https://docs.qbraid.com/v2/cli/api-reference/qbraid"
|
|
|
43
43
|
Discord = "https://discord.gg/KugF6Cnncm"
|
|
44
44
|
|
|
45
45
|
[project.optional-dependencies]
|
|
46
|
-
compute = ["qbraid-core[compute]>=0.6.
|
|
47
|
-
envs = ["qbraid-core[environments]>=0.6.
|
|
46
|
+
compute = ["qbraid-core[compute]>=0.6.12"]
|
|
47
|
+
envs = ["qbraid-core[environments]>=0.6.12"]
|
|
48
48
|
dev = ["isort", "black", "pytest", "pytest-cov", "pytest-asyncio"]
|
|
49
49
|
|
|
50
50
|
[project.scripts]
|
|
@@ -985,6 +985,13 @@ def agents_kill(
|
|
|
985
985
|
session = matches[0]
|
|
986
986
|
pid = session.pid
|
|
987
987
|
|
|
988
|
+
if session.metadata.get("terminal_backend") == "jupyter":
|
|
989
|
+
from qbraid_core.services.agents import AgentLauncher
|
|
990
|
+
|
|
991
|
+
AgentLauncher().kill_bound(session.session_id)
|
|
992
|
+
console.print("[green]Stopped native Lab agent.[/green]")
|
|
993
|
+
return
|
|
994
|
+
|
|
988
995
|
# For tmux-managed sessions, kill the tmux window
|
|
989
996
|
if session.tmux_session and session.tmux_window:
|
|
990
997
|
try:
|
|
@@ -1155,7 +1162,11 @@ def _interactive_attach(console_: Console) -> str:
|
|
|
1155
1162
|
sessions = registry.get_active_sessions()
|
|
1156
1163
|
|
|
1157
1164
|
# Only show sessions with tmux info (attachable)
|
|
1158
|
-
tmux_sessions = [
|
|
1165
|
+
tmux_sessions = [
|
|
1166
|
+
s
|
|
1167
|
+
for s in sessions
|
|
1168
|
+
if (s.tmux_session and s.tmux_window) or s.metadata.get("terminal_backend") == "jupyter"
|
|
1169
|
+
]
|
|
1159
1170
|
|
|
1160
1171
|
if not tmux_sessions:
|
|
1161
1172
|
non_tmux_count = len(sessions) - len(tmux_sessions)
|
|
@@ -1199,6 +1210,24 @@ class ApprovalMode(str, Enum):
|
|
|
1199
1210
|
AUTO = "auto"
|
|
1200
1211
|
|
|
1201
1212
|
|
|
1213
|
+
class TerminalBackend(str, Enum):
|
|
1214
|
+
"""Terminal transport used to host an agent session."""
|
|
1215
|
+
|
|
1216
|
+
AUTO = "auto"
|
|
1217
|
+
JUPYTER = "jupyter"
|
|
1218
|
+
TMUX = "tmux"
|
|
1219
|
+
|
|
1220
|
+
|
|
1221
|
+
def _backend_launcher(backend):
|
|
1222
|
+
from qbraid_core.services.agents import AgentLauncher, AgentLauncherError
|
|
1223
|
+
|
|
1224
|
+
if backend == TerminalBackend.AUTO:
|
|
1225
|
+
return AgentLauncher()
|
|
1226
|
+
if "backend" not in inspect.signature(AgentLauncher).parameters:
|
|
1227
|
+
raise AgentLauncherError("Explicit terminal backends require a newer qbraid-core.")
|
|
1228
|
+
return AgentLauncher(backend=backend.value)
|
|
1229
|
+
|
|
1230
|
+
|
|
1202
1231
|
class ExecutionMode(str, Enum):
|
|
1203
1232
|
"""Codex command isolation, independent of approval prompts."""
|
|
1204
1233
|
|
|
@@ -1399,6 +1428,11 @@ def agents_settings(
|
|
|
1399
1428
|
|
|
1400
1429
|
@agents_app.command("launch")
|
|
1401
1430
|
def agents_launch(
|
|
1431
|
+
backend: TerminalBackend = typer.Option(
|
|
1432
|
+
TerminalBackend.AUTO,
|
|
1433
|
+
"--backend",
|
|
1434
|
+
help="auto: prefer the owning Lab terminal; jupyter: require Lab; tmux: run independently.",
|
|
1435
|
+
),
|
|
1402
1436
|
tool: Optional[str] = typer.Option(
|
|
1403
1437
|
None, "--tool", "-t", help="Agent tool (claude, codeq, codex; claude-auto = claude --approval auto)"
|
|
1404
1438
|
),
|
|
@@ -1437,7 +1471,7 @@ def agents_launch(
|
|
|
1437
1471
|
):
|
|
1438
1472
|
"""Launch an AI coding agent.
|
|
1439
1473
|
|
|
1440
|
-
|
|
1474
|
+
Uses the owning Lab terminal when available; otherwise starts in tmux.
|
|
1441
1475
|
|
|
1442
1476
|
Detached agents may wait for approval until you open their terminal or dashboard.
|
|
1443
1477
|
Approval and execution mode are independent and remembered for resume.
|
|
@@ -1446,7 +1480,7 @@ def agents_launch(
|
|
|
1446
1480
|
Choose it only where you trust the surrounding machine/container isolation.
|
|
1447
1481
|
"""
|
|
1448
1482
|
try:
|
|
1449
|
-
from qbraid_core.services.agents import
|
|
1483
|
+
from qbraid_core.services.agents import AgentLauncherError
|
|
1450
1484
|
|
|
1451
1485
|
# Interactive mode if no tool specified
|
|
1452
1486
|
if tool is None:
|
|
@@ -1465,7 +1499,9 @@ def agents_launch(
|
|
|
1465
1499
|
if not compute or str(uuid.UUID(request_id)) != request_id:
|
|
1466
1500
|
raise AgentLauncherError("--request-id requires --compute and a canonical UUID.")
|
|
1467
1501
|
|
|
1468
|
-
|
|
1502
|
+
if compute and backend != TerminalBackend.AUTO:
|
|
1503
|
+
raise AgentLauncherError("Remote launches select the backend on the destination; omit --backend.")
|
|
1504
|
+
launcher = _backend_launcher(backend)
|
|
1469
1505
|
|
|
1470
1506
|
# Remote launch via SSH
|
|
1471
1507
|
if compute:
|
|
@@ -1511,6 +1547,8 @@ def agents_launch(
|
|
|
1511
1547
|
lines.append(f"[bold]Status:[/bold] [{style}]{status_val}[/{style}]")
|
|
1512
1548
|
if session.compute_id:
|
|
1513
1549
|
lines.append(f"[bold]Compute:[/bold] {session.compute_id}")
|
|
1550
|
+
if session.metadata.get("terminal_backend") == "jupyter":
|
|
1551
|
+
lines.append("[bold]Backend:[/bold] Jupyter (lifetime of the owning Lab server)")
|
|
1514
1552
|
lines.append(f"[bold]Tmux Session:[/bold] {session.tmux_session or '-'}")
|
|
1515
1553
|
lines.append(f"[bold]Tmux Window:[/bold] {session.tmux_window or '-'}")
|
|
1516
1554
|
lines.append(f"[bold]PID:[/bold] {session.pid or '-'}")
|
|
@@ -1525,8 +1563,8 @@ def agents_launch(
|
|
|
1525
1563
|
)
|
|
1526
1564
|
console.print(panel)
|
|
1527
1565
|
console.print()
|
|
1528
|
-
console.print("[dim]
|
|
1529
|
-
console.print(f"
|
|
1566
|
+
console.print("[dim]Open from the Agent Dashboard or attach with:[/dim]")
|
|
1567
|
+
console.print(f" qbraid agents attach {session.session_id}")
|
|
1530
1568
|
|
|
1531
1569
|
except AgentLauncherError as e:
|
|
1532
1570
|
console.print(
|
|
@@ -1614,6 +1652,11 @@ def _interactive_resume(console_: Console) -> str:
|
|
|
1614
1652
|
|
|
1615
1653
|
@agents_app.command("resume")
|
|
1616
1654
|
def agents_resume(
|
|
1655
|
+
backend: TerminalBackend = typer.Option(
|
|
1656
|
+
TerminalBackend.AUTO,
|
|
1657
|
+
"--backend",
|
|
1658
|
+
help="auto: prefer the owning Lab terminal; jupyter: require Lab; tmux: run independently.",
|
|
1659
|
+
),
|
|
1617
1660
|
session_id: Optional[str] = typer.Argument(
|
|
1618
1661
|
None, help="Session ID, prefix, or name. Omit for interactive picker."
|
|
1619
1662
|
),
|
|
@@ -1625,13 +1668,15 @@ def agents_resume(
|
|
|
1625
1668
|
):
|
|
1626
1669
|
"""Resume a previous agent session.
|
|
1627
1670
|
|
|
1628
|
-
Resumes
|
|
1671
|
+
Resumes with the selected terminal backend. With ``--compute`` the session is resumed
|
|
1629
1672
|
on that machine, and a session id is required -- the interactive picker
|
|
1630
1673
|
reads the local registry and cannot see another host's sessions.
|
|
1631
1674
|
"""
|
|
1632
1675
|
try:
|
|
1633
|
-
from qbraid_core.services.agents import
|
|
1676
|
+
from qbraid_core.services.agents import AgentLauncherError
|
|
1634
1677
|
|
|
1678
|
+
if compute and backend != TerminalBackend.AUTO:
|
|
1679
|
+
raise AgentLauncherError("Remote resumes select the backend on the destination; omit --backend.")
|
|
1635
1680
|
if compute:
|
|
1636
1681
|
if session_id is None:
|
|
1637
1682
|
console.print(
|
|
@@ -1658,7 +1703,7 @@ def agents_resume(
|
|
|
1658
1703
|
if session_id is None:
|
|
1659
1704
|
session_id = _interactive_resume(console)
|
|
1660
1705
|
|
|
1661
|
-
launcher =
|
|
1706
|
+
launcher = _backend_launcher(backend)
|
|
1662
1707
|
|
|
1663
1708
|
# Try resume — handle active session and ambiguous matches
|
|
1664
1709
|
try:
|
|
@@ -1792,6 +1837,8 @@ def agents_resume(
|
|
|
1792
1837
|
lines.append(f"[bold]Session ID:[/bold] {session.session_id}")
|
|
1793
1838
|
lines.append(f"[bold]Tool:[/bold] {session.tool.value if session.tool else '-'}")
|
|
1794
1839
|
lines.append(f"[bold]Status:[/bold] [{style}]{status_val}[/{style}]")
|
|
1840
|
+
if session.metadata.get("terminal_backend") == "jupyter":
|
|
1841
|
+
lines.append("[bold]Backend:[/bold] Jupyter (lifetime of the owning Lab server)")
|
|
1795
1842
|
lines.append(f"[bold]Tmux Session:[/bold] {session.tmux_session or '-'}")
|
|
1796
1843
|
lines.append(f"[bold]Tmux Window:[/bold] {session.tmux_window or '-'}")
|
|
1797
1844
|
lines.append(f"[bold]CWD:[/bold] {session.cwd or '-'}")
|
|
@@ -2485,29 +2532,14 @@ def agents_attach(
|
|
|
2485
2532
|
):
|
|
2486
2533
|
"""Attach to an agent's terminal.
|
|
2487
2534
|
|
|
2488
|
-
|
|
2535
|
+
Reconnects to its recorded native terminal or tmux window.
|
|
2489
2536
|
"""
|
|
2490
2537
|
try:
|
|
2491
|
-
# Remote attach: SSH + tmux attach
|
|
2492
2538
|
if compute:
|
|
2493
2539
|
import shlex
|
|
2494
2540
|
|
|
2495
|
-
if session_id
|
|
2496
|
-
|
|
2497
|
-
console.print(f"[dim]Attaching to {session_id} on {compute}... (Ctrl+b d to detach)[/dim]")
|
|
2498
|
-
os.execvp(
|
|
2499
|
-
"ssh",
|
|
2500
|
-
[
|
|
2501
|
-
"ssh",
|
|
2502
|
-
"-t",
|
|
2503
|
-
compute,
|
|
2504
|
-
f"tmux attach -t qbraid-agents:{shlex.quote(session_id)}",
|
|
2505
|
-
],
|
|
2506
|
-
)
|
|
2507
|
-
else:
|
|
2508
|
-
# Attach to the tmux session (user picks window)
|
|
2509
|
-
console.print(f"[dim]Attaching to qbraid-agents on {compute}... (Ctrl+b d to detach)[/dim]")
|
|
2510
|
-
os.execvp("ssh", ["ssh", "-t", compute, "tmux attach -t qbraid-agents"])
|
|
2541
|
+
command = "qbraid agents attach" + (" -- " + shlex.quote(session_id) if session_id else "")
|
|
2542
|
+
os.execvp("ssh", ["ssh", "-t", "--", compute, command])
|
|
2511
2543
|
return
|
|
2512
2544
|
|
|
2513
2545
|
# Interactive mode if no session_id provided
|
|
@@ -2522,6 +2554,23 @@ def agents_attach(
|
|
|
2522
2554
|
console.print("[dim]Use 'qbraid agents list' to see active sessions.[/dim]")
|
|
2523
2555
|
raise typer.Exit(code=1)
|
|
2524
2556
|
|
|
2557
|
+
if session.compute_id:
|
|
2558
|
+
import shlex
|
|
2559
|
+
|
|
2560
|
+
remote_id = session.metadata.get("remote_session_id") or session.session_id
|
|
2561
|
+
command = "qbraid agents attach -- " + shlex.quote(remote_id)
|
|
2562
|
+
os.execvp("ssh", ["ssh", "-t", "--", session.compute_id, command])
|
|
2563
|
+
return
|
|
2564
|
+
if session.machine_id:
|
|
2565
|
+
raise ValueError("Attach on the recorded machine; no SSH alias was recorded.")
|
|
2566
|
+
|
|
2567
|
+
if session.metadata.get("terminal_backend") == "jupyter":
|
|
2568
|
+
from qbraid_core.services.agents.jupyter_runtime import JupyterRuntimeClient
|
|
2569
|
+
|
|
2570
|
+
console.print("[dim]Attaching to native Lab terminal. Ctrl-] detaches.[/dim]")
|
|
2571
|
+
JupyterRuntimeClient(session.metadata["jupyter_server_id"]).attach(session)
|
|
2572
|
+
return
|
|
2573
|
+
|
|
2525
2574
|
tmux_session = session.tmux_session
|
|
2526
2575
|
tmux_window = session.tmux_window
|
|
2527
2576
|
|
|
@@ -2549,12 +2598,7 @@ def agents_attach(
|
|
|
2549
2598
|
|
|
2550
2599
|
console.print(f"[dim]Attaching to {target}... (Ctrl+b d to detach)[/dim]")
|
|
2551
2600
|
|
|
2552
|
-
|
|
2553
|
-
if session.compute_id:
|
|
2554
|
-
alias = session.compute_id
|
|
2555
|
-
os.execvp("ssh", ["ssh", "-t", alias, f"tmux attach -t {target}"])
|
|
2556
|
-
else:
|
|
2557
|
-
os.execvp("tmux", ["tmux", "attach", "-t", target])
|
|
2601
|
+
os.execvp("tmux", ["tmux", "attach", "-t", target])
|
|
2558
2602
|
|
|
2559
2603
|
except (typer.Exit, SystemExit):
|
|
2560
2604
|
raise
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: qbraid-cli
|
|
3
|
-
Version: 0.16.
|
|
3
|
+
Version: 0.16.5
|
|
4
4
|
Summary: Command Line Interface for interacting with all parts of the qBraid platform.
|
|
5
5
|
Author-email: qBraid Development Team <contact@qbraid.com>
|
|
6
6
|
License-Expression: LicenseRef-Proprietary
|
|
@@ -30,11 +30,11 @@ Requires-Dist: typer>=0.12.1
|
|
|
30
30
|
Requires-Dist: rich>=10.11.0
|
|
31
31
|
Requires-Dist: click<=8.5.0
|
|
32
32
|
Requires-Dist: questionary>=2.0.0
|
|
33
|
-
Requires-Dist: qbraid-core>=0.6.
|
|
33
|
+
Requires-Dist: qbraid-core>=0.6.12
|
|
34
34
|
Provides-Extra: compute
|
|
35
|
-
Requires-Dist: qbraid-core[compute]>=0.6.
|
|
35
|
+
Requires-Dist: qbraid-core[compute]>=0.6.12; extra == "compute"
|
|
36
36
|
Provides-Extra: envs
|
|
37
|
-
Requires-Dist: qbraid-core[environments]>=0.6.
|
|
37
|
+
Requires-Dist: qbraid-core[environments]>=0.6.12; extra == "envs"
|
|
38
38
|
Provides-Extra: dev
|
|
39
39
|
Requires-Dist: isort; extra == "dev"
|
|
40
40
|
Requires-Dist: black; extra == "dev"
|
|
@@ -2,10 +2,10 @@ typer>=0.12.1
|
|
|
2
2
|
rich>=10.11.0
|
|
3
3
|
click<=8.5.0
|
|
4
4
|
questionary>=2.0.0
|
|
5
|
-
qbraid-core>=0.6.
|
|
5
|
+
qbraid-core>=0.6.12
|
|
6
6
|
|
|
7
7
|
[compute]
|
|
8
|
-
qbraid-core[compute]>=0.6.
|
|
8
|
+
qbraid-core[compute]>=0.6.12
|
|
9
9
|
|
|
10
10
|
[dev]
|
|
11
11
|
isort
|
|
@@ -15,4 +15,4 @@ pytest-cov
|
|
|
15
15
|
pytest-asyncio
|
|
16
16
|
|
|
17
17
|
[envs]
|
|
18
|
-
qbraid-core[environments]>=0.6.
|
|
18
|
+
qbraid-core[environments]>=0.6.12
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|