uro-cli 0.4.0__tar.gz → 0.5.0__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.
- {uro_cli-0.4.0 → uro_cli-0.5.0}/PKG-INFO +3 -3
- {uro_cli-0.4.0 → uro_cli-0.5.0}/pyproject.toml +3 -3
- {uro_cli-0.4.0 → uro_cli-0.5.0}/uro_cli/main.py +66 -0
- {uro_cli-0.4.0 → uro_cli-0.5.0}/.gitignore +0 -0
- {uro_cli-0.4.0 → uro_cli-0.5.0}/LICENSE +0 -0
- {uro_cli-0.4.0 → uro_cli-0.5.0}/README.md +0 -0
- {uro_cli-0.4.0 → uro_cli-0.5.0}/tests/test_cli_scaffold.py +0 -0
- {uro_cli-0.4.0 → uro_cli-0.5.0}/tests/test_registry_router.py +0 -0
- {uro_cli-0.4.0 → uro_cli-0.5.0}/tests/test_wiring.py +0 -0
- {uro_cli-0.4.0 → uro_cli-0.5.0}/uro_cli/__init__.py +0 -0
- {uro_cli-0.4.0 → uro_cli-0.5.0}/uro_cli/py.typed +0 -0
- {uro_cli-0.4.0 → uro_cli-0.5.0}/uro_cli/wiring.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: uro-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: Uro Engine reference client — play, dry-run, and dev tools against the engine
|
|
5
5
|
Project-URL: Homepage, https://github.com/cupskeee/uro
|
|
6
6
|
Project-URL: Repository, https://github.com/cupskeee/uro
|
|
@@ -12,8 +12,8 @@ Requires-Python: >=3.12
|
|
|
12
12
|
Requires-Dist: python-dotenv>=1.0
|
|
13
13
|
Requires-Dist: rich>=13.9
|
|
14
14
|
Requires-Dist: typer>=0.27.2
|
|
15
|
-
Requires-Dist: uro-core[llm,postgres]==0.
|
|
16
|
-
Requires-Dist: uro-server==0.
|
|
15
|
+
Requires-Dist: uro-core[llm,postgres]==0.5.0
|
|
16
|
+
Requires-Dist: uro-server==0.5.0
|
|
17
17
|
Requires-Dist: websockets>=16.1
|
|
18
18
|
Description-Content-Type: text/markdown
|
|
19
19
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "uro-cli"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.5.0"
|
|
4
4
|
description = "Uro Engine reference client — play, dry-run, and dev tools against the engine"
|
|
5
5
|
license = "MIT"
|
|
6
6
|
license-files = ["LICENSE"]
|
|
@@ -13,8 +13,8 @@ requires-python = ">=3.12"
|
|
|
13
13
|
# pair a new uro-cli with an old uro-core; `just release` bumps all three together, and the
|
|
14
14
|
# `{workspace = true}` sources make a drifted pin fail `uv sync` locally.
|
|
15
15
|
dependencies = [
|
|
16
|
-
"uro-core[postgres,llm]==0.
|
|
17
|
-
"uro-server==0.
|
|
16
|
+
"uro-core[postgres,llm]==0.5.0",
|
|
17
|
+
"uro-server==0.5.0",
|
|
18
18
|
"typer>=0.27.2",
|
|
19
19
|
"rich>=13.9",
|
|
20
20
|
"websockets>=16.1",
|
|
@@ -53,6 +53,10 @@ provider_app = typer.Typer(
|
|
|
53
53
|
no_args_is_help=True,
|
|
54
54
|
help="Model connections — the DB-backed LLM provider registry (D-47, docs/20).",
|
|
55
55
|
)
|
|
56
|
+
outbox_app = typer.Typer(
|
|
57
|
+
no_args_is_help=True,
|
|
58
|
+
help="The transactional outbox — publish committed beats to other processes (D-57).",
|
|
59
|
+
)
|
|
56
60
|
app.add_typer(db_app, name="db")
|
|
57
61
|
app.add_typer(world_app, name="world")
|
|
58
62
|
app.add_typer(branch_app, name="branch")
|
|
@@ -60,6 +64,7 @@ app.add_typer(campaign_app, name="campaign")
|
|
|
60
64
|
app.add_typer(codex_app, name="codex")
|
|
61
65
|
app.add_typer(token_app, name="token")
|
|
62
66
|
app.add_typer(provider_app, name="provider")
|
|
67
|
+
app.add_typer(outbox_app, name="outbox")
|
|
63
68
|
|
|
64
69
|
# The engine roles a connection can back (resolved by the ProviderRouter) — shared with the server.
|
|
65
70
|
_ROLES = tuple(sorted(ROLES))
|
|
@@ -733,6 +738,67 @@ def _server_post(server: str, path: str, token: str, body: dict[str, Any]) -> di
|
|
|
733
738
|
raise typer.Exit(1) from exc
|
|
734
739
|
|
|
735
740
|
|
|
741
|
+
@outbox_app.command("status")
|
|
742
|
+
def outbox_status() -> None:
|
|
743
|
+
"""How many committed beats are waiting to be published."""
|
|
744
|
+
|
|
745
|
+
async def _run() -> None:
|
|
746
|
+
store = build_store()
|
|
747
|
+
await connect_store(store)
|
|
748
|
+
try:
|
|
749
|
+
typer.echo(f"pending: {await store.outbox_pending()}")
|
|
750
|
+
finally:
|
|
751
|
+
await store.close()
|
|
752
|
+
|
|
753
|
+
_run_async(_run)
|
|
754
|
+
|
|
755
|
+
|
|
756
|
+
@outbox_app.command("relay")
|
|
757
|
+
def outbox_relay(
|
|
758
|
+
nats_url: str = typer.Option(..., "--nats", help="NATS server URL, e.g. nats://localhost:4222"),
|
|
759
|
+
stream: str = typer.Option("URO", help="JetStream stream (created if missing)"),
|
|
760
|
+
subject_prefix: str = typer.Option("uro", help="subjects are <prefix>.<world>.<branch>"),
|
|
761
|
+
once: bool = typer.Option(False, "--once", help="drain what is pending, then exit"),
|
|
762
|
+
interval: float = typer.Option(1.0, help="seconds between polls (without --once)"),
|
|
763
|
+
batch: int = typer.Option(100, min=1, help="commits claimed per transaction"),
|
|
764
|
+
) -> None:
|
|
765
|
+
"""Publish committed beats to NATS JetStream (D-57). At-least-once from the outbox; JetStream
|
|
766
|
+
drops a re-sent commit (Nats-Msg-Id = commit id). Run ONE relay to keep each branch in commit
|
|
767
|
+
order (there is no global order across branches); several are safe — no row is published
|
|
768
|
+
twice — but may interleave a branch. A publish error is retried with backoff (`--once` exits
|
|
769
|
+
instead)."""
|
|
770
|
+
try:
|
|
771
|
+
from uro_core.adapters.nats import NatsJetStreamPublisher
|
|
772
|
+
except ImportError as exc:
|
|
773
|
+
typer.echo("the NATS relay needs `pip install 'uro-core[nats]'`", err=True)
|
|
774
|
+
raise typer.Exit(1) from exc
|
|
775
|
+
from uro_core.outbox import relay_forever, relay_outbox
|
|
776
|
+
|
|
777
|
+
async def _run() -> None:
|
|
778
|
+
store = build_store()
|
|
779
|
+
await connect_store(store)
|
|
780
|
+
publisher = NatsJetStreamPublisher(nats_url, stream=stream, subject_prefix=subject_prefix)
|
|
781
|
+
await publisher.connect()
|
|
782
|
+
try:
|
|
783
|
+
if once: # a one-shot drain: an error exits non-zero (right for scripts and cron)
|
|
784
|
+
sent = await relay_outbox(store, publisher, limit=batch)
|
|
785
|
+
typer.echo(f"published {sent} commit(s)")
|
|
786
|
+
return
|
|
787
|
+
# the daemon: a publish error is logged and retried with backoff, never fatal
|
|
788
|
+
await relay_forever(
|
|
789
|
+
store,
|
|
790
|
+
publisher,
|
|
791
|
+
interval=interval,
|
|
792
|
+
limit=batch,
|
|
793
|
+
on_published=lambda n: typer.echo(f"published {n} commit(s)"),
|
|
794
|
+
)
|
|
795
|
+
finally:
|
|
796
|
+
await publisher.close()
|
|
797
|
+
await store.close()
|
|
798
|
+
|
|
799
|
+
_run_async(_run)
|
|
800
|
+
|
|
801
|
+
|
|
736
802
|
@token_app.command("mint")
|
|
737
803
|
def token_mint(
|
|
738
804
|
campaign_id: str,
|
|
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
|