qbraid-cli 0.16.1__tar.gz → 0.16.3__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.1/qbraid_cli.egg-info → qbraid_cli-0.16.3}/PKG-INFO +1 -1
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/pyproject.toml +1 -1
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/agents/app.py +157 -9
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3/qbraid_cli.egg-info}/PKG-INFO +1 -1
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/LICENSE +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/README.md +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/__init__.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/_build_info.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/_version.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/account/__init__.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/account/app.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/admin/__init__.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/admin/app.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/admin/headers.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/admin/validation.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/agents/__init__.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/agents/permission_response.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/ai/__init__.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/ai/app.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/ai/token.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/compute/__init__.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/compute/app.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/compute/instances.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/compute/profiles.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/compute/server.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/compute/ssh.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/configure/__init__.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/configure/actions.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/configure/app.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/devices/__init__.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/devices/app.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/devices/validation.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/envs/__init__.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/envs/activate.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/envs/app.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/envs/create.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/envs/data_handling.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/envs/groups.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/envs/publish.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/envs/registry.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/envs/share.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/exceptions.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/handlers.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/jobs/__init__.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/jobs/app.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/jobs/groups.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/kernels/__init__.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/kernels/app.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/lab/__init__.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/lab/app.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/main.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/pip/__init__.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/pip/app.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/pip/hooks.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/projects/__init__.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/projects/app.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/py.typed +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/skills/__init__.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/skills/app.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/troubleshoot/__init__.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli/troubleshoot/app.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli.egg-info/SOURCES.txt +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli.egg-info/dependency_links.txt +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli.egg-info/entry_points.txt +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli.egg-info/requires.txt +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/qbraid_cli.egg-info/top_level.txt +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/setup.cfg +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/tests/test_cli_e2e.py +0 -0
- {qbraid_cli-0.16.1 → qbraid_cli-0.16.3}/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.3
|
|
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
|
|
@@ -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.3"
|
|
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" }]
|
|
@@ -89,13 +89,43 @@ def _ssh_cmd(ssh_alias: str, remote_cmd: str, timeout: int = 30) -> str:
|
|
|
89
89
|
text=True,
|
|
90
90
|
check=False,
|
|
91
91
|
timeout=timeout,
|
|
92
|
+
# ssh reads stdin unless told otherwise, so inside a script or a
|
|
93
|
+
# `while read` loop it swallowed the caller's remaining input.
|
|
94
|
+
stdin=_sp.DEVNULL,
|
|
92
95
|
)
|
|
93
96
|
if result.returncode != 0:
|
|
94
|
-
console.print(
|
|
97
|
+
console.print(
|
|
98
|
+
f"[red]Remote command failed: {_remote_failure(result.stdout, result.stderr)}[/red]",
|
|
99
|
+
markup=True,
|
|
100
|
+
)
|
|
95
101
|
raise typer.Exit(code=1)
|
|
96
102
|
return result.stdout
|
|
97
103
|
|
|
98
104
|
|
|
105
|
+
# ssh's own chatter, which says nothing about why the remote command failed.
|
|
106
|
+
_SSH_NOISE = ("Warning: Permanently added", "Connection to ", "Shared connection to ")
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def _remote_failure(stdout: str, stderr: str) -> str:
|
|
110
|
+
"""Say why a remote qbraid command failed.
|
|
111
|
+
|
|
112
|
+
The remote CLI prints its errors through Rich on *stdout*; stderr usually
|
|
113
|
+
holds only ssh's known-hosts warning. Reporting stderr alone turned
|
|
114
|
+
"Session not found" into "Warning: Permanently added ... to the list of
|
|
115
|
+
known hosts", which names the one thing that went right.
|
|
116
|
+
"""
|
|
117
|
+
from rich.markup import escape
|
|
118
|
+
|
|
119
|
+
def useful(text: str) -> list[str]:
|
|
120
|
+
# The remote's Rich error panel arrives as box-drawing borders around
|
|
121
|
+
# the message; keep the message, drop the frame.
|
|
122
|
+
lines = [line.strip().strip("│╭╮╰╯─ ") for line in (text or "").splitlines()]
|
|
123
|
+
return [line for line in lines if line and not line.startswith(_SSH_NOISE)]
|
|
124
|
+
|
|
125
|
+
lines = useful(stdout)[-3:] or useful(stderr)[-3:]
|
|
126
|
+
return escape(" / ".join(lines)) if lines else "no output from the remote command"
|
|
127
|
+
|
|
128
|
+
|
|
99
129
|
def _status_style(status_value: str) -> str:
|
|
100
130
|
"""Return a rich style string for a given agent status."""
|
|
101
131
|
styles = {
|
|
@@ -339,6 +369,7 @@ def agents_list(
|
|
|
339
369
|
text=True,
|
|
340
370
|
check=False,
|
|
341
371
|
timeout=30,
|
|
372
|
+
stdin=subprocess.DEVNULL,
|
|
342
373
|
)
|
|
343
374
|
if result.returncode == 0:
|
|
344
375
|
if json_output:
|
|
@@ -357,12 +388,18 @@ def agents_list(
|
|
|
357
388
|
raise typer.Exit(code=1)
|
|
358
389
|
print(payload)
|
|
359
390
|
else:
|
|
360
|
-
|
|
391
|
+
# markup=False -- see agents_status. Pre-existing on this
|
|
392
|
+
# branch; the --json path above already bypasses Rich.
|
|
393
|
+
console.print(result.stdout, markup=False)
|
|
361
394
|
else:
|
|
395
|
+
reason = _remote_failure(result.stdout, result.stderr)
|
|
362
396
|
if json_output:
|
|
363
|
-
typer.echo(f"Failed: {
|
|
364
|
-
|
|
365
|
-
|
|
397
|
+
typer.echo(f"Failed: {reason}", err=True)
|
|
398
|
+
else:
|
|
399
|
+
console.print(f"[red]Failed: {reason}[/red]")
|
|
400
|
+
# Both branches fail. The human-readable one used to print
|
|
401
|
+
# "Failed" and exit 0, so a script could not tell.
|
|
402
|
+
raise typer.Exit(code=1)
|
|
366
403
|
return
|
|
367
404
|
|
|
368
405
|
registry = _get_registry()
|
|
@@ -614,11 +651,28 @@ def agents_discover(
|
|
|
614
651
|
@agents_app.command("status")
|
|
615
652
|
def agents_status(
|
|
616
653
|
session_id: str = typer.Argument(..., help="Session ID (full or prefix)"),
|
|
654
|
+
compute: Optional[str] = typer.Option(None, "--compute", "-c", help="SSH alias for remote compute"),
|
|
617
655
|
):
|
|
618
|
-
"""Show detailed status for an agent session.
|
|
656
|
+
"""Show detailed status for an agent session.
|
|
657
|
+
|
|
658
|
+
Without ``--compute`` this reads the local registry, which is per-host: an
|
|
659
|
+
agent on another machine is simply absent and reports as not found.
|
|
660
|
+
"""
|
|
619
661
|
try:
|
|
620
662
|
from qbraid_core.services.agents import AgentSessionRegistryManager
|
|
621
663
|
|
|
664
|
+
if compute:
|
|
665
|
+
import shlex
|
|
666
|
+
|
|
667
|
+
# markup=False: remote output is already rendered, and Rich would
|
|
668
|
+
# read square brackets in it -- a branch name, a path -- as markup
|
|
669
|
+
# and silently drop them.
|
|
670
|
+
console.print(
|
|
671
|
+
_ssh_cmd(compute, f"qbraid agents status {shlex.quote(session_id)}"),
|
|
672
|
+
markup=False,
|
|
673
|
+
)
|
|
674
|
+
return
|
|
675
|
+
|
|
622
676
|
registry = AgentSessionRegistryManager()
|
|
623
677
|
|
|
624
678
|
# Support prefix and name matching
|
|
@@ -1567,14 +1621,39 @@ def agents_resume(
|
|
|
1567
1621
|
execution_mode: Optional[ExecutionMode] = typer.Option(
|
|
1568
1622
|
None, "--execution-mode", help="Override the recorded Codex execution mode for this resume."
|
|
1569
1623
|
),
|
|
1624
|
+
compute: Optional[str] = typer.Option(None, "--compute", "-c", help="SSH alias for remote compute"),
|
|
1570
1625
|
):
|
|
1571
1626
|
"""Resume a previous agent session.
|
|
1572
1627
|
|
|
1573
|
-
Resumes in a managed tmux window.
|
|
1628
|
+
Resumes in a managed tmux window. With ``--compute`` the session is resumed
|
|
1629
|
+
on that machine, and a session id is required -- the interactive picker
|
|
1630
|
+
reads the local registry and cannot see another host's sessions.
|
|
1574
1631
|
"""
|
|
1575
1632
|
try:
|
|
1576
1633
|
from qbraid_core.services.agents import AgentLauncher, AgentLauncherError
|
|
1577
1634
|
|
|
1635
|
+
if compute:
|
|
1636
|
+
if session_id is None:
|
|
1637
|
+
console.print(
|
|
1638
|
+
"[red]--compute needs an explicit session id.[/red] The picker "
|
|
1639
|
+
"lists this host's sessions only; use 'qbraid agents list "
|
|
1640
|
+
f"--compute {compute}' to find one."
|
|
1641
|
+
)
|
|
1642
|
+
raise typer.Exit(code=2)
|
|
1643
|
+
import shlex
|
|
1644
|
+
|
|
1645
|
+
flags = ""
|
|
1646
|
+
if name:
|
|
1647
|
+
flags += f" --name {shlex.quote(name)}"
|
|
1648
|
+
if execution_mode:
|
|
1649
|
+
flags += f" --execution-mode {shlex.quote(execution_mode.value)}"
|
|
1650
|
+
# markup=False -- see agents_status.
|
|
1651
|
+
console.print(
|
|
1652
|
+
_ssh_cmd(compute, f"qbraid agents resume {shlex.quote(session_id)}{flags}"),
|
|
1653
|
+
markup=False,
|
|
1654
|
+
)
|
|
1655
|
+
return
|
|
1656
|
+
|
|
1578
1657
|
# Interactive mode if no session_id provided
|
|
1579
1658
|
if session_id is None:
|
|
1580
1659
|
session_id = _interactive_resume(console)
|
|
@@ -1800,7 +1879,9 @@ def agents_read(
|
|
|
1800
1879
|
import shlex
|
|
1801
1880
|
|
|
1802
1881
|
output = _ssh_cmd(compute, f"qbraid agents read {shlex.quote(session_id)} --lines {lines}")
|
|
1803
|
-
|
|
1882
|
+
# markup=False -- see agents_status. Terminal output is exactly
|
|
1883
|
+
# where square brackets are most likely, and this was dropping them.
|
|
1884
|
+
console.print(output, markup=False)
|
|
1804
1885
|
return
|
|
1805
1886
|
|
|
1806
1887
|
launcher = AgentLauncher()
|
|
@@ -1822,17 +1903,66 @@ def agents_read(
|
|
|
1822
1903
|
# =============================================================================
|
|
1823
1904
|
|
|
1824
1905
|
|
|
1906
|
+
@agents_app.command("notifier")
|
|
1907
|
+
def agents_notifier(
|
|
1908
|
+
interval: float = typer.Option(4.0, "--interval", "-i", min=1.0, help="Seconds between checks"),
|
|
1909
|
+
once: bool = typer.Option(False, "--once", help="Check once, print who was nudged, and exit"),
|
|
1910
|
+
):
|
|
1911
|
+
"""Wake idle agents when inbox mail arrives.
|
|
1912
|
+
|
|
1913
|
+
Inbox delivery is passive: an agent parked at its prompt never notices a
|
|
1914
|
+
message. This watches the inboxes of this machine's managed agents and
|
|
1915
|
+
types a one-line nudge into an idle agent's pane. Busy agents are left
|
|
1916
|
+
alone until they go idle, and a burst of messages is one nudge.
|
|
1917
|
+
|
|
1918
|
+
qBraid Lab runs this for you. Use it on a machine reached only over SSH.
|
|
1919
|
+
Same-host: it watches the inboxes on the machine it runs on.
|
|
1920
|
+
"""
|
|
1921
|
+
try:
|
|
1922
|
+
try:
|
|
1923
|
+
from qbraid_core.services.agents.inbox_watcher import InboxWatcher, watch
|
|
1924
|
+
except ImportError:
|
|
1925
|
+
console.print("[red]This needs a newer qbraid-core.[/red] Run: pip install -U qbraid-core")
|
|
1926
|
+
raise typer.Exit(code=1) # pylint: disable=raise-missing-from
|
|
1927
|
+
|
|
1928
|
+
watcher = InboxWatcher()
|
|
1929
|
+
if once:
|
|
1930
|
+
nudged = watcher.poll_once()
|
|
1931
|
+
console.print(f"Nudged: {', '.join(nudged) if nudged else 'nobody'}", markup=False)
|
|
1932
|
+
return
|
|
1933
|
+
console.print(f"[dim]Watching inboxes every {interval:g}s... (Ctrl+C to stop)[/dim]")
|
|
1934
|
+
watch(interval=interval, watcher=watcher)
|
|
1935
|
+
except KeyboardInterrupt:
|
|
1936
|
+
console.print("[dim]Stopped.[/dim]")
|
|
1937
|
+
except (typer.Exit, SystemExit):
|
|
1938
|
+
raise
|
|
1939
|
+
except Exception as e: # pylint: disable=broad-exception-caught
|
|
1940
|
+
handle_error(message=str(e))
|
|
1941
|
+
raise typer.Exit(code=1)
|
|
1942
|
+
|
|
1943
|
+
|
|
1825
1944
|
@agents_app.command("approve")
|
|
1826
1945
|
def agents_approve(
|
|
1827
1946
|
session_id: str = typer.Argument(..., help="Session ID (prefix match)"),
|
|
1947
|
+
compute: Optional[str] = typer.Option(None, "--compute", "-c", help="SSH alias for remote compute"),
|
|
1828
1948
|
):
|
|
1829
1949
|
"""Approve a tool-use prompt.
|
|
1830
1950
|
|
|
1831
|
-
Sends 'y' + Enter to the agent's terminal.
|
|
1951
|
+
Sends 'y' + Enter to the agent's terminal. With ``--compute`` the approval
|
|
1952
|
+
is sent on that machine.
|
|
1832
1953
|
"""
|
|
1833
1954
|
try:
|
|
1955
|
+
# Bound before the --compute branch below, which can raise: evaluating
|
|
1956
|
+
# the `except AgentLauncherError` clause needs the name.
|
|
1834
1957
|
from qbraid_core.services.agents import AgentLauncher, AgentLauncherError
|
|
1835
1958
|
|
|
1959
|
+
if compute:
|
|
1960
|
+
import shlex
|
|
1961
|
+
|
|
1962
|
+
_ssh_cmd(compute, f"qbraid agents approve {shlex.quote(session_id)}")
|
|
1963
|
+
console.print(f"[green]Approval sent to session {session_id} on {compute}.[/green]")
|
|
1964
|
+
return
|
|
1965
|
+
|
|
1836
1966
|
launcher = AgentLauncher()
|
|
1837
1967
|
launcher.approve(session_id)
|
|
1838
1968
|
console.print(f"[green]Approval sent to session {session_id}.[/green]")
|
|
@@ -1957,6 +2087,7 @@ def agents_watch(
|
|
|
1957
2087
|
["ssh", "-o", "ConnectTimeout=10", compute, remote_flags],
|
|
1958
2088
|
stdout=_sp.PIPE,
|
|
1959
2089
|
stderr=_sp.PIPE,
|
|
2090
|
+
stdin=_sp.DEVNULL,
|
|
1960
2091
|
text=True,
|
|
1961
2092
|
)
|
|
1962
2093
|
try:
|
|
@@ -2837,6 +2968,11 @@ def agents_send_to(
|
|
|
2837
2968
|
|
|
2838
2969
|
For multi-recipient / team broadcast, use ``qbraid agents broadcast``.
|
|
2839
2970
|
|
|
2971
|
+
Same-host only: an inbox is a JSONL file under ``~/.qbraid/inboxes/`` on
|
|
2972
|
+
the machine that owns it, so there is no ``--compute``. Cross-host
|
|
2973
|
+
messaging needs a transport, tracked in qBraid-CLI#328 / qbraid-core#307.
|
|
2974
|
+
|
|
2975
|
+
|
|
2840
2976
|
Delivery is a JSONL append at ~/.qbraid/inboxes/<to-session-id>.jsonl
|
|
2841
2977
|
(local host only — cross-host messaging isn't yet supported and will raise
|
|
2842
2978
|
a clear error). Permission rules (leader/worker/observer/reviewer) are
|
|
@@ -2904,6 +3040,10 @@ def agents_broadcast(
|
|
|
2904
3040
|
) -> None:
|
|
2905
3041
|
"""Broadcast to multiple agent inboxes.
|
|
2906
3042
|
|
|
3043
|
+
Same-host only: an inbox is a JSONL file under ``~/.qbraid/inboxes/`` on
|
|
3044
|
+
the machine that owns it, so there is no ``--compute``. Cross-host
|
|
3045
|
+
messaging needs a transport, tracked in qBraid-CLI#328 / qbraid-core#307.
|
|
3046
|
+
|
|
2907
3047
|
Two selectors — pick exactly one:
|
|
2908
3048
|
* ``--team <team_id>`` — every session with that team_id (except sender)
|
|
2909
3049
|
* ``--to A,B,C`` — explicit id/prefix/name list
|
|
@@ -3031,6 +3171,10 @@ def inbox_default( # pylint: disable=too-many-arguments
|
|
|
3031
3171
|
|
|
3032
3172
|
Without a subcommand this reads the inbox (optionally streams with
|
|
3033
3173
|
--follow). Use ``qbraid agents inbox mark-read`` to mark manually.
|
|
3174
|
+
|
|
3175
|
+
Same-host only: an inbox is a JSONL file under ``~/.qbraid/inboxes/`` on
|
|
3176
|
+
the machine that owns it, so there is no ``--compute``. Cross-host
|
|
3177
|
+
messaging needs a transport, tracked in qBraid-CLI#328 / qbraid-core#307.
|
|
3034
3178
|
"""
|
|
3035
3179
|
if ctx.invoked_subcommand is not None:
|
|
3036
3180
|
return
|
|
@@ -3138,6 +3282,10 @@ def agents_team(
|
|
|
3138
3282
|
) -> None:
|
|
3139
3283
|
"""Show a team roster with unread counts.
|
|
3140
3284
|
|
|
3285
|
+
Same-host only: an inbox is a JSONL file under ``~/.qbraid/inboxes/`` on
|
|
3286
|
+
the machine that owns it, so there is no ``--compute``. Cross-host
|
|
3287
|
+
messaging needs a transport, tracked in qBraid-CLI#328 / qbraid-core#307.
|
|
3288
|
+
|
|
3141
3289
|
Answers the leader-orchestrator question "who is on my team, how many
|
|
3142
3290
|
unread messages do they have, and what was the last thing they heard from
|
|
3143
3291
|
anyone?" — which today requires peeking each worker's inbox individually.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: qbraid-cli
|
|
3
|
-
Version: 0.16.
|
|
3
|
+
Version: 0.16.3
|
|
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
|
|
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
|