From d2dc153103c103e86c01ffdbac4373fa4158f23e Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 22 Mar 2026 01:42:39 +0000 Subject: [PATCH 01/18] fix(cli): strip OpenRTC flags before LiveKit run_app parses argv openrtc start/dev forwarded --agents-dir, --dashboard, and other OpenRTC-only options in sys.argv to livekit.agents.cli.run_app, which uses a separate Typer app. That produced "No such option: --agents-dir" and immediate exit. Strip those flags while preserving forwarded LiveKit options (e.g. --reload). Co-authored-by: Mahimai Raja J --- src/openrtc/cli_app.py | 62 ++++++++++++++++++++++++++++++++++++++++-- tests/test_cli.py | 35 ++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 2 deletions(-) diff --git a/src/openrtc/cli_app.py b/src/openrtc/cli_app.py index ffc6c1a..2f0f20e 100644 --- a/src/openrtc/cli_app.py +++ b/src/openrtc/cli_app.py @@ -251,15 +251,73 @@ def _pool_kwargs( } +_OPENRTC_ONLY_FLAGS_WITH_VALUE: frozenset[str] = frozenset( + { + "--agents-dir", + "--default-stt", + "--default-llm", + "--default-tts", + "--default-greeting", + "--dashboard-refresh", + "--metrics-json-file", + } +) +_OPENRTC_ONLY_BOOL_FLAGS: frozenset[str] = frozenset({"--dashboard"}) + + +def _strip_openrtc_only_flags_for_livekit(argv_tail: list[str]) -> list[str]: + """Drop OpenRTC-only CLI flags; LiveKit's ``run_app`` parses ``sys.argv`` itself. + + ``openrtc start`` / ``openrtc dev`` are implemented with Typer, then delegate to + :func:`livekit.agents.cli.run_app`, which builds a separate Typer application + that does not recognize OpenRTC options such as ``--agents-dir``. Those must + be removed before the handoff while preserving any forwarded LiveKit flags + (e.g. ``--reload``, ``--url``) when we add pass-through options later. + """ + out: list[str] = [] + i = 0 + while i < len(argv_tail): + arg = argv_tail[i] + if arg == "--": + out.extend(argv_tail[i:]) + break + if "=" in arg: + name = arg.split("=", 1)[0] + if ( + name in _OPENRTC_ONLY_FLAGS_WITH_VALUE + or name in _OPENRTC_ONLY_BOOL_FLAGS + ): + i += 1 + continue + out.append(arg) + i += 1 + continue + if arg in _OPENRTC_ONLY_BOOL_FLAGS: + i += 1 + continue + if arg in _OPENRTC_ONLY_FLAGS_WITH_VALUE: + i += 1 + if i < len(argv_tail) and not argv_tail[i].startswith("--"): + i += 1 + continue + out.append(arg) + i += 1 + return out + + def _livekit_sys_argv(subcommand: str) -> None: - """Set ``sys.argv`` for ``livekit.agents.cli.run_app`` without dropping user flags. + """Set ``sys.argv`` for ``livekit.agents.cli.run_app``. + + OpenRTC-specific options are stripped because the LiveKit CLI re-parses + ``sys.argv`` and only accepts its own flags per subcommand. When the process was not started as ``openrtc ...`` (e.g. tests that patch ``sys.argv``), only ``[argv0, subcommand]`` is used. """ prog = sys.argv[0] if len(sys.argv) >= 2 and sys.argv[1] == subcommand: - sys.argv = [prog, subcommand, *sys.argv[2:]] + rest = _strip_openrtc_only_flags_for_livekit(list(sys.argv[2:])) + sys.argv = [prog, subcommand, *rest] else: sys.argv = [prog, subcommand] diff --git a/tests/test_cli.py b/tests/test_cli.py index c2eee16..c2710f1 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -228,6 +228,41 @@ def test_list_exits_cleanly_when_agents_dir_does_not_exist( assert "does not exist" in caplog.text +def test_strip_openrtc_only_flags_for_livekit_removes_openrtc_options() -> None: + """LiveKit ``run_app`` must not see OpenRTC-only flags (see ``_livekit_sys_argv``).""" + from openrtc.cli_app import _strip_openrtc_only_flags_for_livekit + + tail = [ + "--agents-dir", + "./agents", + "--dashboard", + "--dashboard-refresh", + "2.0", + "--metrics-json-file", + "/tmp/m.json", + "--default-stt", + "x", + "--default-llm", + "y", + "--default-tts", + "z", + "--default-greeting", + "hi", + "--reload", + "--log-level", + "DEBUG", + ] + assert _strip_openrtc_only_flags_for_livekit(tail) == [ + "--reload", + "--log-level", + "DEBUG", + ] + assert _strip_openrtc_only_flags_for_livekit(["--agents-dir=./a", "--reload"]) == [ + "--reload" + ] + assert _strip_openrtc_only_flags_for_livekit([]) == [] + + def test_cli_entrypoint_documents_optional_extra() -> None: from openrtc.cli import CLI_EXTRA_INSTALL_HINT From 9b9f2cb1c101291e8d48bd465fd36552f71239eb Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 22 Mar 2026 02:10:24 +0000 Subject: [PATCH 02/18] feat(cli): align OpenRTC commands with LiveKit Agents CLI Add console, connect, and download-files subcommands that delegate to the same LiveKit Typer app as python agent.py. Group help into OpenRTC vs Connection panels; expose --url, --api-key, --api-secret, and --log-level with the same env vars as LiveKit. Extend worker command tests accordingly. Co-authored-by: Mahimai Raja J --- src/openrtc/cli_app.py | 323 ++++++++++++++++++++++++++++++++++++++--- tests/test_cli.py | 14 +- 2 files changed, 318 insertions(+), 19 deletions(-) diff --git a/src/openrtc/cli_app.py b/src/openrtc/cli_app.py index 2f0f20e..7947fa8 100644 --- a/src/openrtc/cli_app.py +++ b/src/openrtc/cli_app.py @@ -2,6 +2,7 @@ import json import logging +import os import sys import threading from pathlib import Path @@ -27,9 +28,20 @@ logger = logging.getLogger("openrtc") +PANEL_OPENRTC = "OpenRTC" +PANEL_LIVEKIT = "Connection" + app = typer.Typer( name="openrtc", - help="Discover and run multiple LiveKit agents in one worker.", + help=( + "Run multiple LiveKit voice agents from one shared worker. Subcommands mirror " + "the LiveKit Agents CLI ([code]dev[/code], [code]start[/code], [code]console[/code], " + "[code]connect[/code], [code]download-files[/code]) as in " + "[code]python agent.py [/code]. " + "Add [code]--agents-dir[/code] so OpenRTC discovers and registers agents; use " + "[code]--url[/code] / [code]--api-key[/code] / [code]--api-secret[/code] or " + "the usual [code]LIVEKIT_*[/code] environment variables for the server." + ), pretty_exceptions_show_locals=False, rich_markup_mode="rich", no_args_is_help=True, @@ -322,6 +334,100 @@ def _livekit_sys_argv(subcommand: str) -> None: sys.argv = [prog, subcommand] +def _apply_optional_livekit_connection_env( + *, + url: str | None, + api_key: str | None, + api_secret: str | None, +) -> None: + """Mirror LiveKit CLI env vars when the user passes connection flags on OpenRTC.""" + if url is not None: + os.environ["LIVEKIT_URL"] = url + if api_key is not None: + os.environ["LIVEKIT_API_KEY"] = api_key + if api_secret is not None: + os.environ["LIVEKIT_API_SECRET"] = api_secret + + +def _apply_optional_livekit_log_level(log_level: str | None) -> None: + if log_level is not None: + os.environ["LIVEKIT_LOG_LEVEL"] = log_level + + +def _delegate_discovered_pool_to_livekit( + *, + agents_dir: Path, + subcommand: str, + default_stt: str | None, + default_llm: str | None, + default_tts: str | None, + default_greeting: str | None, + dashboard: bool, + dashboard_refresh: float, + metrics_json_file: Path | None, + url: str | None, + api_key: str | None, + api_secret: str | None, + log_level: str | None, +) -> None: + """Discover agents, optionally set connection env, then run a LiveKit CLI subcommand.""" + pool = AgentPool( + **_pool_kwargs(default_stt, default_llm, default_tts, default_greeting) + ) + _discover_or_exit(agents_dir, pool) + _apply_optional_livekit_connection_env( + url=url, api_key=api_key, api_secret=api_secret + ) + _apply_optional_livekit_log_level(log_level) + _livekit_sys_argv(subcommand) + _run_pool_with_reporting( + pool, + dashboard=dashboard, + dashboard_refresh=dashboard_refresh, + metrics_json_file=metrics_json_file, + ) + + +def _run_connect_handoff( + *, + agents_dir: Path, + default_stt: str | None, + default_llm: str | None, + default_tts: str | None, + default_greeting: str | None, + room: str, + participant_identity: str | None, + log_level: str | None, + url: str | None, + api_key: str | None, + api_secret: str | None, + dashboard: bool, + dashboard_refresh: float, + metrics_json_file: Path | None, +) -> None: + """Hand off to LiveKit ``connect`` with explicit argv (Typer consumes flags first).""" + pool = AgentPool( + **_pool_kwargs(default_stt, default_llm, default_tts, default_greeting) + ) + _discover_or_exit(agents_dir, pool) + _apply_optional_livekit_connection_env( + url=url, api_key=api_key, api_secret=api_secret + ) + prog = sys.argv[0] + tail: list[str] = ["connect", "--room", room] + if participant_identity is not None: + tail.extend(["--participant-identity", participant_identity]) + if log_level is not None: + tail.extend(["--log-level", log_level]) + sys.argv = [prog, *tail] + _run_pool_with_reporting( + pool, + dashboard=dashboard, + dashboard_refresh=dashboard_refresh, + metrics_json_file=metrics_json_file, + ) + + def _discover_or_exit(agents_dir: Path, pool: AgentPool) -> list[AgentConfig]: try: discovered = pool.discover(agents_dir) @@ -364,6 +470,7 @@ def _truncate_cell(text: str, max_len: int = 36) -> str: exists=False, resolve_path=True, path_type=Path, + rich_help_panel=PANEL_OPENRTC, ), ] @@ -375,6 +482,7 @@ def _truncate_cell(text: str, max_len: int = 36) -> str: "Default STT provider used when a discovered agent does not " "override STT via @agent_config(...)." ), + rich_help_panel=PANEL_OPENRTC, ), ] @@ -386,6 +494,7 @@ def _truncate_cell(text: str, max_len: int = 36) -> str: "Default LLM provider used when a discovered agent does not " "override LLM via @agent_config(...)." ), + rich_help_panel=PANEL_OPENRTC, ), ] @@ -397,6 +506,7 @@ def _truncate_cell(text: str, max_len: int = 36) -> str: "Default TTS provider used when a discovered agent does not " "override TTS via @agent_config(...)." ), + rich_help_panel=PANEL_OPENRTC, ), ] @@ -408,6 +518,7 @@ def _truncate_cell(text: str, max_len: int = 36) -> str: "Default greeting used when a discovered agent does not " "override greeting via @agent_config(...)." ), + rich_help_panel=PANEL_OPENRTC, ), ] @@ -416,6 +527,7 @@ def _truncate_cell(text: str, max_len: int = 36) -> str: typer.Option( "--dashboard", help="Show a live Rich dashboard with worker memory and active sessions.", + rich_help_panel=PANEL_OPENRTC, ), ] @@ -425,6 +537,7 @@ def _truncate_cell(text: str, max_len: int = 36) -> str: "--dashboard-refresh", min=0.25, help="Refresh interval in seconds for the runtime dashboard and metrics file.", + rich_help_panel=PANEL_OPENRTC, ), ] @@ -435,6 +548,66 @@ def _truncate_cell(text: str, max_len: int = 36) -> str: help="Write live runtime metrics snapshots to this JSON file for automation.", resolve_path=True, path_type=Path, + rich_help_panel=PANEL_OPENRTC, + ), +] + +LiveKitUrlArg = Annotated[ + str | None, + typer.Option( + "--url", + help="WebSocket URL of the LiveKit server or Cloud project.", + envvar="LIVEKIT_URL", + rich_help_panel=PANEL_LIVEKIT, + ), +] + +LiveKitApiKeyArg = Annotated[ + str | None, + typer.Option( + "--api-key", + help="API key for the LiveKit server or Cloud project.", + envvar="LIVEKIT_API_KEY", + rich_help_panel=PANEL_LIVEKIT, + ), +] + +LiveKitApiSecretArg = Annotated[ + str | None, + typer.Option( + "--api-secret", + help="API secret for the LiveKit server or Cloud project.", + envvar="LIVEKIT_API_SECRET", + rich_help_panel=PANEL_LIVEKIT, + ), +] + +ConnectRoomArg = Annotated[ + str, + typer.Option( + "--room", + help="Room name to connect to (same as LiveKit Agents [code]connect[/code]).", + rich_help_panel=PANEL_LIVEKIT, + ), +] + +ConnectParticipantArg = Annotated[ + str | None, + typer.Option( + "--participant-identity", + help="Agent participant identity when connecting to the room.", + rich_help_panel=PANEL_LIVEKIT, + ), +] + +LiveKitLogLevelArg = Annotated[ + str | None, + typer.Option( + "--log-level", + help="Log level (e.g. DEBUG, INFO, WARN, ERROR).", + envvar="LIVEKIT_LOG_LEVEL", + case_sensitive=False, + rich_help_panel=PANEL_LIVEKIT, ), ] @@ -630,21 +803,29 @@ def start_command( default_llm: DefaultLlmArg = None, default_tts: DefaultTtsArg = None, default_greeting: DefaultGreetingArg = None, + url: LiveKitUrlArg = None, + api_key: LiveKitApiKeyArg = None, + api_secret: LiveKitApiSecretArg = None, + log_level: LiveKitLogLevelArg = None, dashboard: DashboardArg = False, dashboard_refresh: DashboardRefreshArg = 1.0, metrics_json_file: MetricsJsonFileArg = None, ) -> None: - """Run the LiveKit worker (production-style entrypoint).""" - pool = AgentPool( - **_pool_kwargs(default_stt, default_llm, default_tts, default_greeting) - ) - _discover_or_exit(agents_dir, pool) - _livekit_sys_argv("start") - _run_pool_with_reporting( - pool, + """Run the worker (same role as [code]python agent.py start[/code] with LiveKit).""" + _delegate_discovered_pool_to_livekit( + agents_dir=agents_dir, + subcommand="start", + default_stt=default_stt, + default_llm=default_llm, + default_tts=default_tts, + default_greeting=default_greeting, dashboard=dashboard, dashboard_refresh=dashboard_refresh, metrics_json_file=metrics_json_file, + url=url, + api_key=api_key, + api_secret=api_secret, + log_level=log_level, ) @@ -655,24 +836,131 @@ def dev_command( default_llm: DefaultLlmArg = None, default_tts: DefaultTtsArg = None, default_greeting: DefaultGreetingArg = None, + url: LiveKitUrlArg = None, + api_key: LiveKitApiKeyArg = None, + api_secret: LiveKitApiSecretArg = None, + log_level: LiveKitLogLevelArg = None, dashboard: DashboardArg = False, dashboard_refresh: DashboardRefreshArg = 1.0, metrics_json_file: MetricsJsonFileArg = None, ) -> None: - """Run the LiveKit worker in development mode.""" - pool = AgentPool( - **_pool_kwargs(default_stt, default_llm, default_tts, default_greeting) + """Development worker with reload (same role as [code]python agent.py dev[/code]).""" + _delegate_discovered_pool_to_livekit( + agents_dir=agents_dir, + subcommand="dev", + default_stt=default_stt, + default_llm=default_llm, + default_tts=default_tts, + default_greeting=default_greeting, + dashboard=dashboard, + dashboard_refresh=dashboard_refresh, + metrics_json_file=metrics_json_file, + url=url, + api_key=api_key, + api_secret=api_secret, + log_level=log_level, ) - _discover_or_exit(agents_dir, pool) - _livekit_sys_argv("dev") - _run_pool_with_reporting( - pool, + + +@app.command("console") +def console_command( + agents_dir: AgentsDirArg, + default_stt: DefaultSttArg = None, + default_llm: DefaultLlmArg = None, + default_tts: DefaultTtsArg = None, + default_greeting: DefaultGreetingArg = None, + url: LiveKitUrlArg = None, + api_key: LiveKitApiKeyArg = None, + api_secret: LiveKitApiSecretArg = None, + log_level: LiveKitLogLevelArg = None, + dashboard: DashboardArg = False, + dashboard_refresh: DashboardRefreshArg = 1.0, + metrics_json_file: MetricsJsonFileArg = None, +) -> None: + """Local console session (same role as [code]python agent.py console[/code]).""" + _delegate_discovered_pool_to_livekit( + agents_dir=agents_dir, + subcommand="console", + default_stt=default_stt, + default_llm=default_llm, + default_tts=default_tts, + default_greeting=default_greeting, + dashboard=dashboard, + dashboard_refresh=dashboard_refresh, + metrics_json_file=metrics_json_file, + url=url, + api_key=api_key, + api_secret=api_secret, + log_level=log_level, + ) + + +@app.command("connect") +def connect_command( + agents_dir: AgentsDirArg, + room: ConnectRoomArg, + default_stt: DefaultSttArg = None, + default_llm: DefaultLlmArg = None, + default_tts: DefaultTtsArg = None, + default_greeting: DefaultGreetingArg = None, + participant_identity: ConnectParticipantArg = None, + log_level: LiveKitLogLevelArg = None, + url: LiveKitUrlArg = None, + api_key: LiveKitApiKeyArg = None, + api_secret: LiveKitApiSecretArg = None, + dashboard: DashboardArg = False, + dashboard_refresh: DashboardRefreshArg = 1.0, + metrics_json_file: MetricsJsonFileArg = None, +) -> None: + """Connect the worker to an existing room (LiveKit [code]connect[/code]).""" + _run_connect_handoff( + agents_dir=agents_dir, + default_stt=default_stt, + default_llm=default_llm, + default_tts=default_tts, + default_greeting=default_greeting, + room=room, + participant_identity=participant_identity, + log_level=log_level, + url=url, + api_key=api_key, + api_secret=api_secret, dashboard=dashboard, dashboard_refresh=dashboard_refresh, metrics_json_file=metrics_json_file, ) +@app.command("download-files") +def download_files_command( + agents_dir: AgentsDirArg, + default_stt: DefaultSttArg = None, + default_llm: DefaultLlmArg = None, + default_tts: DefaultTtsArg = None, + default_greeting: DefaultGreetingArg = None, + url: LiveKitUrlArg = None, + api_key: LiveKitApiKeyArg = None, + api_secret: LiveKitApiSecretArg = None, + log_level: LiveKitLogLevelArg = None, +) -> None: + """Download plugin assets (LiveKit [code]download-files[/code]).""" + _delegate_discovered_pool_to_livekit( + agents_dir=agents_dir, + subcommand="download-files", + default_stt=default_stt, + default_llm=default_llm, + default_tts=default_tts, + default_greeting=default_greeting, + dashboard=False, + dashboard_refresh=1.0, + metrics_json_file=None, + url=url, + api_key=api_key, + api_secret=api_secret, + log_level=log_level, + ) + + def _run_pool_with_reporting( pool: AgentPool, *, @@ -799,7 +1087,8 @@ def main(argv: list[str] | None = None) -> int: still use CliRunner). Pass ``args`` without the program name when invoking programmatically; ``prog_name`` matches the ``openrtc`` console script. - ``start`` / ``dev`` mutate :data:`sys.argv` before ``pool.run()``; we restore + Worker subcommands (``start``, ``dev``, ``console``, ``connect``, + ``download-files``) mutate :data:`sys.argv` before ``pool.run()``; we restore the previous argv list after the command finishes so programmatic callers are not polluted. """ diff --git a/tests/test_cli.py b/tests/test_cli.py index c2710f1..7db954c 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -185,10 +185,20 @@ def build_pool(**kwargs: Any) -> StubPool: assert created_pools[0].default_greeting == "Hello from OpenRTC." -@pytest.mark.parametrize("command", ["start", "dev"]) +@pytest.mark.parametrize( + ("command", "extra_args"), + [ + ("start", ["--agents-dir", "./agents"]), + ("dev", ["--agents-dir", "./agents"]), + ("console", ["--agents-dir", "./agents"]), + ("download-files", ["--agents-dir", "./agents"]), + ("connect", ["--agents-dir", "./agents", "--room", "demo-room"]), + ], +) def test_run_commands_inject_livekit_mode_and_run_pool( monkeypatch: pytest.MonkeyPatch, command: str, + extra_args: list[str], original_argv: list[str], ) -> None: stub_pool = StubPool( @@ -197,7 +207,7 @@ def test_run_commands_inject_livekit_mode_and_run_pool( monkeypatch.setattr("openrtc.cli_app.AgentPool", lambda **kwargs: stub_pool) monkeypatch.setattr(sys, "argv", original_argv.copy()) - exit_code = main([command, "--agents-dir", "./agents"]) + exit_code = main([command, *extra_args]) assert exit_code == 0 assert stub_pool.run_called is True From 25a51935bca7843476870d8b90bd5206324b7927 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 22 Mar 2026 02:52:13 +0000 Subject: [PATCH 03/18] feat(metrics): JSONL stream for sidecar TUI (phase 1) Add versioned JSON Lines export (--metrics-jsonl) with optional interval, JsonlMetricsSink, and RuntimeReporter integration. Truncate file on worker start. Co-authored-by: Mahimai Raja J --- src/openrtc/cli_app.py | 136 ++++++++++++++++++++++++++++++++-- src/openrtc/metrics_stream.py | 74 ++++++++++++++++++ tests/test_cli.py | 4 + tests/test_metrics_stream.py | 118 +++++++++++++++++++++++++++++ 4 files changed, 325 insertions(+), 7 deletions(-) create mode 100644 src/openrtc/metrics_stream.py create mode 100644 tests/test_metrics_stream.py diff --git a/src/openrtc/cli_app.py b/src/openrtc/cli_app.py index 7947fa8..ee64a9b 100644 --- a/src/openrtc/cli_app.py +++ b/src/openrtc/cli_app.py @@ -5,6 +5,7 @@ import os import sys import threading +import time from pathlib import Path from typing import Annotated, Any @@ -16,6 +17,7 @@ from rich.table import Table from rich.text import Text +from openrtc.metrics_stream import JsonlMetricsSink from openrtc.pool import AgentConfig, AgentPool from openrtc.resources import ( PoolRuntimeSnapshot, @@ -51,7 +53,7 @@ class RuntimeReporter: - """Background reporter that renders a Rich dashboard and/or JSON snapshots.""" + """Background reporter: Rich dashboard, static JSON file, and/or JSONL stream.""" def __init__( self, @@ -60,17 +62,33 @@ def __init__( dashboard: bool, refresh_seconds: float, json_output_path: Path | None, + metrics_jsonl_path: Path | None = None, + metrics_jsonl_interval: float | None = None, ) -> None: self._pool = pool self._dashboard = dashboard self._refresh_seconds = max(refresh_seconds, 0.25) self._json_output_path = json_output_path + self._jsonl_interval = ( + max(metrics_jsonl_interval, 0.25) + if metrics_jsonl_interval is not None + else self._refresh_seconds + ) + self._jsonl_sink: JsonlMetricsSink | None = None + if metrics_jsonl_path is not None: + self._jsonl_sink = JsonlMetricsSink(metrics_jsonl_path) + self._jsonl_sink.open() self._stop_event = threading.Event() self._thread: threading.Thread | None = None + self._needs_periodic_file_or_ui = dashboard or json_output_path is not None def start(self) -> None: """Start the background reporter when at least one output is enabled.""" - if not self._dashboard and self._json_output_path is None: + if ( + not self._dashboard + and self._json_output_path is None + and self._jsonl_sink is None + ): return self._thread = threading.Thread( target=self._run, @@ -85,8 +103,17 @@ def stop(self) -> None: if self._thread is not None: self._thread.join(timeout=max(self._refresh_seconds * 2, 1.0)) self._write_json_snapshot() + self._write_jsonl_snapshot() + if self._jsonl_sink is not None: + self._jsonl_sink.close() def _run(self) -> None: + now = time.monotonic() + next_periodic = ( + now + self._refresh_seconds if self._needs_periodic_file_or_ui else float("inf") + ) + next_jsonl = now + self._jsonl_interval if self._jsonl_sink else float("inf") + if self._dashboard: with Live( self._build_dashboard_renderable(), @@ -94,14 +121,46 @@ def _run(self) -> None: refresh_per_second=max(int(round(1 / self._refresh_seconds)), 1), transient=True, ) as live: - while not self._stop_event.wait(self._refresh_seconds): - live.update(self._build_dashboard_renderable()) - self._write_json_snapshot() + while True: + now = time.monotonic() + wait_periodic = max(0.0, next_periodic - now) + wait_jsonl = ( + max(0.0, next_jsonl - now) + if self._jsonl_sink is not None + else float("inf") + ) + timeout = min(wait_periodic, wait_jsonl, 3600.0) + if self._stop_event.wait(timeout): + break + now = time.monotonic() + if self._needs_periodic_file_or_ui and now >= next_periodic: + live.update(self._build_dashboard_renderable()) + self._write_json_snapshot() + next_periodic += self._refresh_seconds + if self._jsonl_sink is not None and now >= next_jsonl: + self._write_jsonl_snapshot() + next_jsonl += self._jsonl_interval live.update(self._build_dashboard_renderable()) return - while not self._stop_event.wait(self._refresh_seconds): - self._write_json_snapshot() + while True: + now = time.monotonic() + wait_periodic = max(0.0, next_periodic - now) + wait_jsonl = ( + max(0.0, next_jsonl - now) + if self._jsonl_sink is not None + else float("inf") + ) + timeout = min(wait_periodic, wait_jsonl, 3600.0) + if self._stop_event.wait(timeout): + break + now = time.monotonic() + if self._needs_periodic_file_or_ui and now >= next_periodic: + self._write_json_snapshot() + next_periodic += self._refresh_seconds + if self._jsonl_sink is not None and now >= next_jsonl: + self._write_jsonl_snapshot() + next_jsonl += self._jsonl_interval def _build_dashboard_renderable(self) -> Panel: snapshot = self._pool.runtime_snapshot() @@ -117,6 +176,11 @@ def _write_json_snapshot(self) -> None: encoding="utf-8", ) + def _write_jsonl_snapshot(self) -> None: + if self._jsonl_sink is None: + return + self._jsonl_sink.write_snapshot(self._pool.runtime_snapshot()) + def _format_percent(saved_bytes: int | None, baseline_bytes: int | None) -> str: if saved_bytes is None or baseline_bytes in (None, 0): @@ -272,6 +336,8 @@ def _pool_kwargs( "--default-greeting", "--dashboard-refresh", "--metrics-json-file", + "--metrics-jsonl", + "--metrics-jsonl-interval", } ) _OPENRTC_ONLY_BOOL_FLAGS: frozenset[str] = frozenset({"--dashboard"}) @@ -365,6 +431,8 @@ def _delegate_discovered_pool_to_livekit( dashboard: bool, dashboard_refresh: float, metrics_json_file: Path | None, + metrics_jsonl: Path | None, + metrics_jsonl_interval: float | None, url: str | None, api_key: str | None, api_secret: str | None, @@ -385,6 +453,8 @@ def _delegate_discovered_pool_to_livekit( dashboard=dashboard, dashboard_refresh=dashboard_refresh, metrics_json_file=metrics_json_file, + metrics_jsonl=metrics_jsonl, + metrics_jsonl_interval=metrics_jsonl_interval, ) @@ -404,6 +474,8 @@ def _run_connect_handoff( dashboard: bool, dashboard_refresh: float, metrics_json_file: Path | None, + metrics_jsonl: Path | None, + metrics_jsonl_interval: float | None, ) -> None: """Hand off to LiveKit ``connect`` with explicit argv (Typer consumes flags first).""" pool = AgentPool( @@ -425,6 +497,8 @@ def _run_connect_handoff( dashboard=dashboard, dashboard_refresh=dashboard_refresh, metrics_json_file=metrics_json_file, + metrics_jsonl=metrics_jsonl, + metrics_jsonl_interval=metrics_jsonl_interval, ) @@ -552,6 +626,32 @@ def _truncate_cell(text: str, max_len: int = 36) -> str: ), ] +MetricsJsonlArg = Annotated[ + Path | None, + typer.Option( + "--metrics-jsonl", + help=( + "Append versioned metrics snapshots as JSON Lines for ``openrtc tui --watch`` " + "(truncates the file when the worker starts)." + ), + resolve_path=True, + path_type=Path, + rich_help_panel=PANEL_OPENRTC, + ), +] + +MetricsJsonlIntervalArg = Annotated[ + float | None, + typer.Option( + "--metrics-jsonl-interval", + min=0.25, + help=( + "Seconds between JSONL records (default: same as --dashboard-refresh)." + ), + rich_help_panel=PANEL_OPENRTC, + ), +] + LiveKitUrlArg = Annotated[ str | None, typer.Option( @@ -810,6 +910,8 @@ def start_command( dashboard: DashboardArg = False, dashboard_refresh: DashboardRefreshArg = 1.0, metrics_json_file: MetricsJsonFileArg = None, + metrics_jsonl: MetricsJsonlArg = None, + metrics_jsonl_interval: MetricsJsonlIntervalArg = None, ) -> None: """Run the worker (same role as [code]python agent.py start[/code] with LiveKit).""" _delegate_discovered_pool_to_livekit( @@ -822,6 +924,8 @@ def start_command( dashboard=dashboard, dashboard_refresh=dashboard_refresh, metrics_json_file=metrics_json_file, + metrics_jsonl=metrics_jsonl, + metrics_jsonl_interval=metrics_jsonl_interval, url=url, api_key=api_key, api_secret=api_secret, @@ -843,6 +947,8 @@ def dev_command( dashboard: DashboardArg = False, dashboard_refresh: DashboardRefreshArg = 1.0, metrics_json_file: MetricsJsonFileArg = None, + metrics_jsonl: MetricsJsonlArg = None, + metrics_jsonl_interval: MetricsJsonlIntervalArg = None, ) -> None: """Development worker with reload (same role as [code]python agent.py dev[/code]).""" _delegate_discovered_pool_to_livekit( @@ -855,6 +961,8 @@ def dev_command( dashboard=dashboard, dashboard_refresh=dashboard_refresh, metrics_json_file=metrics_json_file, + metrics_jsonl=metrics_jsonl, + metrics_jsonl_interval=metrics_jsonl_interval, url=url, api_key=api_key, api_secret=api_secret, @@ -876,6 +984,8 @@ def console_command( dashboard: DashboardArg = False, dashboard_refresh: DashboardRefreshArg = 1.0, metrics_json_file: MetricsJsonFileArg = None, + metrics_jsonl: MetricsJsonlArg = None, + metrics_jsonl_interval: MetricsJsonlIntervalArg = None, ) -> None: """Local console session (same role as [code]python agent.py console[/code]).""" _delegate_discovered_pool_to_livekit( @@ -888,6 +998,8 @@ def console_command( dashboard=dashboard, dashboard_refresh=dashboard_refresh, metrics_json_file=metrics_json_file, + metrics_jsonl=metrics_jsonl, + metrics_jsonl_interval=metrics_jsonl_interval, url=url, api_key=api_key, api_secret=api_secret, @@ -911,6 +1023,8 @@ def connect_command( dashboard: DashboardArg = False, dashboard_refresh: DashboardRefreshArg = 1.0, metrics_json_file: MetricsJsonFileArg = None, + metrics_jsonl: MetricsJsonlArg = None, + metrics_jsonl_interval: MetricsJsonlIntervalArg = None, ) -> None: """Connect the worker to an existing room (LiveKit [code]connect[/code]).""" _run_connect_handoff( @@ -928,6 +1042,8 @@ def connect_command( dashboard=dashboard, dashboard_refresh=dashboard_refresh, metrics_json_file=metrics_json_file, + metrics_jsonl=metrics_jsonl, + metrics_jsonl_interval=metrics_jsonl_interval, ) @@ -954,6 +1070,8 @@ def download_files_command( dashboard=False, dashboard_refresh=1.0, metrics_json_file=None, + metrics_jsonl=None, + metrics_jsonl_interval=None, url=url, api_key=api_key, api_secret=api_secret, @@ -967,12 +1085,16 @@ def _run_pool_with_reporting( dashboard: bool, dashboard_refresh: float, metrics_json_file: Path | None, + metrics_jsonl: Path | None = None, + metrics_jsonl_interval: float | None = None, ) -> None: reporter = RuntimeReporter( pool, dashboard=dashboard, refresh_seconds=dashboard_refresh, json_output_path=metrics_json_file, + metrics_jsonl_path=metrics_jsonl, + metrics_jsonl_interval=metrics_jsonl_interval, ) reporter.start() try: diff --git a/src/openrtc/metrics_stream.py b/src/openrtc/metrics_stream.py new file mode 100644 index 0000000..52cd2a0 --- /dev/null +++ b/src/openrtc/metrics_stream.py @@ -0,0 +1,74 @@ +"""Sidecar metrics stream for workers (JSON Lines over a file or socket). + +Each line is one JSON object (envelope) so a separate TUI or script can tail the +file. This is the contract for ``openrtc tui --watch``. + +**Envelope (schema version 1)** + +* ``schema_version`` (int): bump on breaking payload changes. +* ``kind`` (str): ``"snapshot"`` for full pool state; future kinds may add events. +* ``seq`` (int): monotonically increasing counter for this worker process. +* ``wall_time_unix`` (float): ``time.time()`` when the record was emitted. +* ``payload`` (dict): for ``kind == "snapshot"``, same shape as + :meth:`PoolRuntimeSnapshot.to_dict`. +""" + +from __future__ import annotations + +import json +import time +from pathlib import Path +from threading import Lock +from typing import Any + +from openrtc.resources import PoolRuntimeSnapshot + +METRICS_STREAM_SCHEMA_VERSION = 1 +KIND_SNAPSHOT = "snapshot" + + +def snapshot_envelope(*, seq: int, snapshot: PoolRuntimeSnapshot) -> dict[str, Any]: + """Build a versioned JSON object for one line of the metrics stream.""" + return { + "schema_version": METRICS_STREAM_SCHEMA_VERSION, + "kind": KIND_SNAPSHOT, + "seq": seq, + "wall_time_unix": time.time(), + "payload": snapshot.to_dict(), + } + + +class JsonlMetricsSink: + """Append-only JSONL writer; truncates the file when opened (new worker run).""" + + def __init__(self, path: Path) -> None: + self._path = path + self._file: Any = None + self._seq = 0 + self._lock = Lock() + + def open(self) -> None: + """Create parent dirs, truncate file, open for append.""" + self._path.parent.mkdir(parents=True, exist_ok=True) + self._file = self._path.open("w", encoding="utf-8") + + def write_snapshot(self, snapshot: PoolRuntimeSnapshot) -> None: + """Serialize one snapshot line and flush (thread-safe).""" + with self._lock: + if self._file is None: + raise RuntimeError("JsonlMetricsSink.open() was not called") + self._seq += 1 + record = snapshot_envelope(seq=self._seq, snapshot=snapshot) + self._file.write(json.dumps(record, sort_keys=True) + "\n") + self._file.flush() + + def close(self) -> None: + with self._lock: + if self._file is not None: + self._file.close() + self._file = None + + @property + def seq(self) -> int: + with self._lock: + return self._seq diff --git a/tests/test_cli.py b/tests/test_cli.py index 7db954c..260549a 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -258,6 +258,10 @@ def test_strip_openrtc_only_flags_for_livekit_removes_openrtc_options() -> None: "z", "--default-greeting", "hi", + "--metrics-jsonl", + "/tmp/x.jsonl", + "--metrics-jsonl-interval", + "0.5", "--reload", "--log-level", "DEBUG", diff --git a/tests/test_metrics_stream.py b/tests/test_metrics_stream.py new file mode 100644 index 0000000..3353e4d --- /dev/null +++ b/tests/test_metrics_stream.py @@ -0,0 +1,118 @@ +from __future__ import annotations + +import json +import time +from pathlib import Path + +from openrtc.cli_app import RuntimeReporter +from openrtc.metrics_stream import ( + KIND_SNAPSHOT, + METRICS_STREAM_SCHEMA_VERSION, + JsonlMetricsSink, + snapshot_envelope, +) +from openrtc.resources import ( + PoolRuntimeSnapshot, + ProcessResidentSetInfo, + SavingsEstimate, +) + + +def _minimal_snapshot() -> PoolRuntimeSnapshot: + return PoolRuntimeSnapshot( + timestamp=1.0, + uptime_seconds=0.5, + registered_agents=1, + active_sessions=0, + total_sessions_started=0, + total_session_failures=0, + last_routed_agent=None, + last_error=None, + sessions_by_agent={}, + resident_set=ProcessResidentSetInfo( + bytes_value=1024, + metric="test", + description="test", + ), + savings_estimate=SavingsEstimate( + agent_count=1, + shared_worker_bytes=1024, + estimated_separate_workers_bytes=1024, + estimated_saved_bytes=0, + assumptions=(), + ), + ) + + +class _StubPool: + def __init__(self) -> None: + self._snap = _minimal_snapshot() + + def runtime_snapshot(self) -> PoolRuntimeSnapshot: + return self._snap + + +def test_snapshot_envelope_shape() -> None: + snap = _minimal_snapshot() + env = snapshot_envelope(seq=7, snapshot=snap) + assert env["schema_version"] == METRICS_STREAM_SCHEMA_VERSION + assert env["kind"] == KIND_SNAPSHOT + assert env["seq"] == 7 + assert isinstance(env["wall_time_unix"], float) + assert env["payload"] == snap.to_dict() + + +def test_jsonl_sink_truncates_on_open_and_increments_seq(tmp_path: Path) -> None: + path = tmp_path / "stream.jsonl" + sink = JsonlMetricsSink(path) + sink.open() + snap = _minimal_snapshot() + sink.write_snapshot(snap) + sink.write_snapshot(snap) + sink.close() + + lines = path.read_text(encoding="utf-8").strip().split("\n") + assert len(lines) == 2 + a, b = (json.loads(line) for line in lines) + assert a["seq"] == 1 + assert b["seq"] == 2 + + +def test_jsonl_sink_new_open_truncates_previous_file(tmp_path: Path) -> None: + path = tmp_path / "stream.jsonl" + sink1 = JsonlMetricsSink(path) + sink1.open() + sink1.write_snapshot(_minimal_snapshot()) + sink1.close() + + sink2 = JsonlMetricsSink(path) + sink2.open() + sink2.write_snapshot(_minimal_snapshot()) + sink2.close() + + lines = path.read_text(encoding="utf-8").strip().split("\n") + assert len(lines) == 1 + assert json.loads(lines[0])["seq"] == 1 + + +def test_runtime_reporter_emits_jsonl_periodically(tmp_path: Path) -> None: + path = tmp_path / "live.jsonl" + pool = _StubPool() + reporter = RuntimeReporter( + pool, + dashboard=False, + refresh_seconds=0.25, + json_output_path=None, + metrics_jsonl_path=path, + metrics_jsonl_interval=0.25, + ) + reporter.start() + time.sleep(0.85) + reporter.stop() + + lines = [ln for ln in path.read_text(encoding="utf-8").split("\n") if ln.strip()] + assert len(lines) >= 2 + first = json.loads(lines[0]) + last = json.loads(lines[-1]) + assert first["schema_version"] == METRICS_STREAM_SCHEMA_VERSION + assert last["seq"] > first["seq"] From 3013d7c282bb9fd922e430162210e29b0176bc95 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 22 Mar 2026 02:59:28 +0000 Subject: [PATCH 04/18] feat(tui): Textual sidecar openrtc tui --watch (phase 2) Add optional tui extra and dev dependency on Textual. New command tails --metrics-jsonl with a small live layout. Add parse_metrics_jsonl_line for consumers and tests. Co-authored-by: Mahimai Raja J --- pyproject.toml | 4 ++ src/openrtc/cli_app.py | 49 ++++++++++++++-- src/openrtc/metrics_stream.py | 16 ++++++ src/openrtc/tui_app.py | 104 ++++++++++++++++++++++++++++++++++ tests/test_metrics_stream.py | 19 +++++++ tests/test_tui_app.py | 59 +++++++++++++++++++ uv.lock | 64 ++++++++++++++++++++- 7 files changed, 309 insertions(+), 6 deletions(-) create mode 100644 src/openrtc/tui_app.py create mode 100644 tests/test_tui_app.py diff --git a/pyproject.toml b/pyproject.toml index 8cd0b6a..9b28c57 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,6 +30,9 @@ cli = [ "rich>=13", "typer>=0.12", ] +tui = [ + "textual>=0.47,<2", +] [project.urls] Homepage = "https://github.com/mahimailabs/openrtc" @@ -95,6 +98,7 @@ dev = [ "python-dotenv>=1.2.2", "rich>=13", "ruff>=0.15.6", + "textual>=0.47,<2", "typer>=0.12", ] diff --git a/src/openrtc/cli_app.py b/src/openrtc/cli_app.py index ee64a9b..8e3b52f 100644 --- a/src/openrtc/cli_app.py +++ b/src/openrtc/cli_app.py @@ -42,7 +42,9 @@ "[code]python agent.py [/code]. " "Add [code]--agents-dir[/code] so OpenRTC discovers and registers agents; use " "[code]--url[/code] / [code]--api-key[/code] / [code]--api-secret[/code] or " - "the usual [code]LIVEKIT_*[/code] environment variables for the server." + "the usual [code]LIVEKIT_*[/code] environment variables for the server. " + "Use [code]openrtc tui --watch FILE[/code] (with the [code]tui[/code] extra) to " + "tail [code]--metrics-jsonl[/code] in a separate terminal." ), pretty_exceptions_show_locals=False, rich_markup_mode="rich", @@ -110,7 +112,9 @@ def stop(self) -> None: def _run(self) -> None: now = time.monotonic() next_periodic = ( - now + self._refresh_seconds if self._needs_periodic_file_or_ui else float("inf") + now + self._refresh_seconds + if self._needs_periodic_file_or_ui + else float("inf") ) next_jsonl = now + self._jsonl_interval if self._jsonl_sink else float("inf") @@ -645,9 +649,27 @@ def _truncate_cell(text: str, max_len: int = 36) -> str: typer.Option( "--metrics-jsonl-interval", min=0.25, - help=( - "Seconds between JSONL records (default: same as --dashboard-refresh)." - ), + help=("Seconds between JSONL records (default: same as --dashboard-refresh)."), + rich_help_panel=PANEL_OPENRTC, + ), +] + +TuiWatchPathArg = Annotated[ + Path, + typer.Option( + "--watch", + help="JSONL file written by the worker's --metrics-jsonl.", + resolve_path=True, + path_type=Path, + rich_help_panel=PANEL_OPENRTC, + ), +] + +TuiFromStartArg = Annotated[ + bool, + typer.Option( + "--from-start", + help="Read the file from the beginning instead of tailing from EOF.", rich_help_panel=PANEL_OPENRTC, ), ] @@ -1079,6 +1101,23 @@ def download_files_command( ) +@app.command("tui") +def tui_command( + watch: TuiWatchPathArg, + from_start: TuiFromStartArg = False, +) -> None: + """Sidecar Textual UI for a --metrics-jsonl stream (requires the ``tui`` extra).""" + try: + from openrtc.tui_app import run_metrics_tui + except ImportError as exc: + logger.error( + "The TUI requires Textual. Install with: pip install 'openrtc[tui]' " + "(the cli extra is required for the openrtc command)." + ) + raise typer.Exit(code=1) from exc + run_metrics_tui(watch, from_start=from_start) + + def _run_pool_with_reporting( pool: AgentPool, *, diff --git a/src/openrtc/metrics_stream.py b/src/openrtc/metrics_stream.py index 52cd2a0..e320b0b 100644 --- a/src/openrtc/metrics_stream.py +++ b/src/openrtc/metrics_stream.py @@ -38,6 +38,22 @@ def snapshot_envelope(*, seq: int, snapshot: PoolRuntimeSnapshot) -> dict[str, A } +def parse_metrics_jsonl_line(line: str) -> dict[str, Any] | None: + """Return a parsed snapshot record, or ``None`` if the line is not a snapshot.""" + stripped = line.strip() + if not stripped: + return None + try: + record: dict[str, Any] = json.loads(stripped) + except json.JSONDecodeError: + return None + if record.get("schema_version") != METRICS_STREAM_SCHEMA_VERSION: + return None + if record.get("kind") != KIND_SNAPSHOT: + return None + return record + + class JsonlMetricsSink: """Append-only JSONL writer; truncates the file when opened (new worker run).""" diff --git a/src/openrtc/tui_app.py b/src/openrtc/tui_app.py new file mode 100644 index 0000000..ef64cd7 --- /dev/null +++ b/src/openrtc/tui_app.py @@ -0,0 +1,104 @@ +"""Textual sidecar UI for tailing :mod:`openrtc.metrics_stream` JSONL output.""" + +from __future__ import annotations + +from pathlib import Path +from typing import Any + +from textual.app import App, ComposeResult +from textual.widgets import Footer, Header, Static + +from openrtc.metrics_stream import parse_metrics_jsonl_line + + +class MetricsTuiApp(App[None]): + """Tail ``--metrics-jsonl`` and show live pool metrics.""" + + TITLE = "OpenRTC metrics" + BINDINGS = [("q", "quit", "Quit")] + + def __init__(self, watch_path: Path, *, from_start: bool = False) -> None: + super().__init__() + self._path = watch_path.resolve() + self._from_start = from_start + self._fh: Any = None + self._buf = "" + self._latest: dict[str, Any] | None = None + + def compose(self) -> ComposeResult: + yield Header(show_clock=True) + yield Static( + "Waiting for JSONL metrics (run the worker with --metrics-jsonl)…", + id="status", + ) + yield Static("", id="agents") + yield Static("", id="detail") + yield Footer() + + def on_mount(self) -> None: + self._path.parent.mkdir(parents=True, exist_ok=True) + if not self._path.exists(): + self._path.touch() + self._fh = self._path.open("r", encoding="utf-8") + if not self._from_start: + self._fh.seek(0, 2) + self.set_interval(0.25, self._poll_file) + + def on_unmount(self) -> None: + if self._fh is not None: + self._fh.close() + self._fh = None + + def _poll_file(self) -> None: + if self._fh is None: + return + chunk = self._fh.read() + if not chunk: + return + self._buf += chunk + while "\n" in self._buf: + line, self._buf = self._buf.split("\n", 1) + rec = parse_metrics_jsonl_line(line) + if rec is not None: + self._latest = rec + self._refresh_view() + + def _refresh_view(self) -> None: + if self._latest is None: + return + payload = self._latest.get("payload") + if not isinstance(payload, dict): + return + seq = self._latest.get("seq") + wall = self._latest.get("wall_time_unix") + status = self.query_one("#status", Static) + status.update( + f"seq={seq} wall={float(wall):.3f} registered={payload.get('registered_agents')} " + f"active={payload.get('active_sessions')} " + f"uptime={float(payload.get('uptime_seconds', 0)):.1f}s" + ) + sba = payload.get("sessions_by_agent") or {} + if isinstance(sba, dict): + lines = [f" {name}: {c}" for name, c in sorted(sba.items())] + body = "\n".join(lines) if lines else " (no per-agent sessions yet)" + else: + body = " (invalid payload)" + agents = self.query_one("#agents", Static) + agents.update("[bold]Sessions by agent[/bold]\n" + body) + route = payload.get("last_routed_agent") + err = payload.get("last_error") + detail = self.query_one("#detail", Static) + detail.update( + f"[bold]Last route[/bold] {route or '—'}\n" + f"[bold]Last error[/bold] {err or '—'}\n" + f"[bold]Totals[/bold] started={payload.get('total_sessions_started')} " + f"failures={payload.get('total_session_failures')}" + ) + + def action_quit(self) -> None: + self.exit() + + +def run_metrics_tui(watch_path: Path, *, from_start: bool = False) -> None: + """Run the Textual app until the user quits.""" + MetricsTuiApp(watch_path, from_start=from_start).run() diff --git a/tests/test_metrics_stream.py b/tests/test_metrics_stream.py index 3353e4d..5a2f593 100644 --- a/tests/test_metrics_stream.py +++ b/tests/test_metrics_stream.py @@ -9,6 +9,7 @@ KIND_SNAPSHOT, METRICS_STREAM_SCHEMA_VERSION, JsonlMetricsSink, + parse_metrics_jsonl_line, snapshot_envelope, ) from openrtc.resources import ( @@ -52,6 +53,24 @@ def runtime_snapshot(self) -> PoolRuntimeSnapshot: return self._snap +def test_parse_metrics_jsonl_line() -> None: + good = json.dumps( + { + "schema_version": METRICS_STREAM_SCHEMA_VERSION, + "kind": KIND_SNAPSHOT, + "seq": 9, + "wall_time_unix": 12.0, + "payload": {"registered_agents": 0}, + } + ) + parsed = parse_metrics_jsonl_line(good) + assert parsed is not None + assert parsed["seq"] == 9 + assert parse_metrics_jsonl_line("") is None + assert parse_metrics_jsonl_line("not-json") is None + assert parse_metrics_jsonl_line('{"schema_version": 999}') is None + + def test_snapshot_envelope_shape() -> None: snap = _minimal_snapshot() env = snapshot_envelope(seq=7, snapshot=snap) diff --git a/tests/test_tui_app.py b/tests/test_tui_app.py new file mode 100644 index 0000000..e38c040 --- /dev/null +++ b/tests/test_tui_app.py @@ -0,0 +1,59 @@ +from __future__ import annotations + +import json + +import pytest + +from openrtc.metrics_stream import snapshot_envelope +from openrtc.resources import ( + PoolRuntimeSnapshot, + ProcessResidentSetInfo, + SavingsEstimate, +) + +pytest.importorskip("textual") + + +def _minimal_snapshot() -> PoolRuntimeSnapshot: + return PoolRuntimeSnapshot( + timestamp=1.0, + uptime_seconds=0.5, + registered_agents=1, + active_sessions=0, + total_sessions_started=0, + total_session_failures=0, + last_routed_agent=None, + last_error=None, + sessions_by_agent={}, + resident_set=ProcessResidentSetInfo( + bytes_value=1024, + metric="test", + description="test", + ), + savings_estimate=SavingsEstimate( + agent_count=1, + shared_worker_bytes=1024, + estimated_separate_workers_bytes=1024, + estimated_saved_bytes=0, + assumptions=(), + ), + ) + + +@pytest.mark.asyncio +async def test_metrics_tui_displays_snapshot_line(tmp_path) -> None: + from openrtc.tui_app import MetricsTuiApp + + path = tmp_path / "stream.jsonl" + snap = _minimal_snapshot() + line = json.dumps(snapshot_envelope(seq=1, snapshot=snap), sort_keys=True) + path.write_text(line + "\n", encoding="utf-8") + + app = MetricsTuiApp(path, from_start=True) + async with app.run_test() as pilot: + app._poll_file() + await pilot.pause() + status = app.query_one("#status") + text = str(status.renderable) + assert "seq=1" in text + assert "registered=1" in text diff --git a/uv.lock b/uv.lock index 42a32eb..341d7cd 100644 --- a/uv.lock +++ b/uv.lock @@ -954,6 +954,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d3/97/68f80ca3ac4924f250cdfa6e20142a803e5e50fca96ef5148c52ee8c10ea/librt-0.8.1-cp313-cp313-win_arm64.whl", hash = "sha256:924817ab3141aca17893386ee13261f1d100d1ef410d70afe4389f2359fea4f0", size = 52495, upload-time = "2026-02-17T16:12:11.633Z" }, ] +[[package]] +name = "linkify-it-py" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "uc-micro-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2e/c9/06ea13676ef354f0af6169587ae292d3e2406e212876a413bf9eece4eb23/linkify_it_py-2.1.0.tar.gz", hash = "sha256:43360231720999c10e9328dc3691160e27a718e280673d444c38d7d3aaa3b98b", size = 29158, upload-time = "2026-03-01T07:48:47.683Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b4/de/88b3be5c31b22333b3ca2f6ff1de4e863d8fe45aaea7485f591970ec1d3e/linkify_it_py-2.1.0-py3-none-any.whl", hash = "sha256:0d252c1594ecba2ecedc444053db5d3a9b7ec1b0dd929c8f1d74dce89f86c05e", size = 19878, upload-time = "2026-03-01T07:48:46.098Z" }, +] + [[package]] name = "livekit" version = "1.0.25" @@ -1147,6 +1159,14 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, ] +[package.optional-dependencies] +linkify = [ + { name = "linkify-it-py" }, +] +plugins = [ + { name = "mdit-py-plugins" }, +] + [[package]] name = "markupsafe" version = "3.0.3" @@ -1210,6 +1230,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, ] +[[package]] +name = "mdit-py-plugins" +version = "0.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b2/fd/a756d36c0bfba5f6e39a1cdbdbfdd448dc02692467d83816dff4592a1ebc/mdit_py_plugins-0.5.0.tar.gz", hash = "sha256:f4918cb50119f50446560513a8e311d574ff6aaed72606ddae6d35716fe809c6", size = 44655, upload-time = "2025-08-11T07:25:49.083Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl", hash = "sha256:07a08422fc1936a5d26d146759e9155ea466e842f5ab2f7d2266dd084c8dab1f", size = 57205, upload-time = "2025-08-11T07:25:47.597Z" }, +] + [[package]] name = "mdurl" version = "0.1.2" @@ -1629,6 +1661,9 @@ cli = [ { name = "rich" }, { name = "typer" }, ] +tui = [ + { name = "textual" }, +] [package.dev-dependencies] dev = [ @@ -1640,6 +1675,7 @@ dev = [ { name = "python-dotenv" }, { name = "rich" }, { name = "ruff" }, + { name = "textual" }, { name = "typer" }, ] @@ -1647,9 +1683,10 @@ dev = [ requires-dist = [ { name = "livekit-agents", extras = ["openai", "silero", "turn-detector"], specifier = "~=1.4" }, { name = "rich", marker = "extra == 'cli'", specifier = ">=13" }, + { name = "textual", marker = "extra == 'tui'", specifier = ">=0.47,<2" }, { name = "typer", marker = "extra == 'cli'", specifier = ">=0.12" }, ] -provides-extras = ["cli"] +provides-extras = ["cli", "tui"] [package.metadata.requires-dev] dev = [ @@ -1661,6 +1698,7 @@ dev = [ { name = "python-dotenv", specifier = ">=1.2.2" }, { name = "rich", specifier = ">=13" }, { name = "ruff", specifier = ">=0.15.6" }, + { name = "textual", specifier = ">=0.47,<2" }, { name = "typer", specifier = ">=0.12" }, ] @@ -2495,6 +2533,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl", hash = "sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5", size = 6299353, upload-time = "2025-04-27T18:04:59.103Z" }, ] +[[package]] +name = "textual" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py", extra = ["linkify", "plugins"] }, + { name = "platformdirs" }, + { name = "rich" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1f/b6/59b1de04bb4dca0f21ed7ba0b19309ed7f3f5de4396edf20cc2855e53085/textual-1.0.0.tar.gz", hash = "sha256:bec9fe63547c1c552569d1b75d309038b7d456c03f86dfa3706ddb099b151399", size = 1532733, upload-time = "2024-12-12T10:42:03.286Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ac/bb/5fb6656c625019cd653d5215237d7cd6e0b12e7eae4195c3d1c91b2136fc/textual-1.0.0-py3-none-any.whl", hash = "sha256:2d4a701781c05104925e463ae370c630567c70c2880e92ab838052e3e23c986f", size = 660456, upload-time = "2024-12-12T10:42:00.375Z" }, +] + [[package]] name = "tokenizers" version = "0.22.2" @@ -2640,6 +2693,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, ] +[[package]] +name = "uc-micro-py" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/78/67/9a363818028526e2d4579334460df777115bdec1bb77c08f9db88f6389f2/uc_micro_py-2.0.0.tar.gz", hash = "sha256:c53691e495c8db60e16ffc4861a35469b0ba0821fe409a8a7a0a71864d33a811", size = 6611, upload-time = "2026-03-01T06:31:27.526Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/61/73/d21edf5b204d1467e06500080a50f79d49ef2b997c79123a536d4a17d97c/uc_micro_py-2.0.0-py3-none-any.whl", hash = "sha256:3603a3859af53e5a39bc7677713c78ea6589ff188d70f4fee165db88e22b242c", size = 6383, upload-time = "2026-03-01T06:31:26.257Z" }, +] + [[package]] name = "urllib3" version = "2.6.3" From 6720d67697dfd28dc8b363a0b44deea38df4dd8a Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 22 Mar 2026 03:02:26 +0000 Subject: [PATCH 05/18] feat(metrics): JSONL event lines for session lifecycle (phase 3) Queue session_started/finished/failed in RuntimeMetricsStore, drain into the JSONL stream after each snapshot. Extend parse_metrics_jsonl_line and the Textual TUI to show the last event. StubPool gains drain_metrics_stream_events. Co-authored-by: Mahimai Raja J --- src/openrtc/cli_app.py | 11 +++++---- src/openrtc/metrics_stream.py | 30 +++++++++++++++++++++--- src/openrtc/pool.py | 4 ++++ src/openrtc/resources.py | 39 ++++++++++++++++++++++++++++++- src/openrtc/tui_app.py | 22 ++++++++++++++++-- tests/test_cli.py | 3 +++ tests/test_metrics_stream.py | 44 +++++++++++++++++++++++++++++++++++ 7 files changed, 143 insertions(+), 10 deletions(-) diff --git a/src/openrtc/cli_app.py b/src/openrtc/cli_app.py index 8e3b52f..25c341c 100644 --- a/src/openrtc/cli_app.py +++ b/src/openrtc/cli_app.py @@ -105,7 +105,7 @@ def stop(self) -> None: if self._thread is not None: self._thread.join(timeout=max(self._refresh_seconds * 2, 1.0)) self._write_json_snapshot() - self._write_jsonl_snapshot() + self._emit_jsonl() if self._jsonl_sink is not None: self._jsonl_sink.close() @@ -142,7 +142,7 @@ def _run(self) -> None: self._write_json_snapshot() next_periodic += self._refresh_seconds if self._jsonl_sink is not None and now >= next_jsonl: - self._write_jsonl_snapshot() + self._emit_jsonl() next_jsonl += self._jsonl_interval live.update(self._build_dashboard_renderable()) return @@ -163,7 +163,7 @@ def _run(self) -> None: self._write_json_snapshot() next_periodic += self._refresh_seconds if self._jsonl_sink is not None and now >= next_jsonl: - self._write_jsonl_snapshot() + self._emit_jsonl() next_jsonl += self._jsonl_interval def _build_dashboard_renderable(self) -> Panel: @@ -180,10 +180,13 @@ def _write_json_snapshot(self) -> None: encoding="utf-8", ) - def _write_jsonl_snapshot(self) -> None: + def _emit_jsonl(self) -> None: + """Write one snapshot line then any queued session events (same tick).""" if self._jsonl_sink is None: return self._jsonl_sink.write_snapshot(self._pool.runtime_snapshot()) + for ev in self._pool.drain_metrics_stream_events(): + self._jsonl_sink.write_event(ev) def _format_percent(saved_bytes: int | None, baseline_bytes: int | None) -> str: diff --git a/src/openrtc/metrics_stream.py b/src/openrtc/metrics_stream.py index e320b0b..347ecfc 100644 --- a/src/openrtc/metrics_stream.py +++ b/src/openrtc/metrics_stream.py @@ -10,7 +10,8 @@ * ``seq`` (int): monotonically increasing counter for this worker process. * ``wall_time_unix`` (float): ``time.time()`` when the record was emitted. * ``payload`` (dict): for ``kind == "snapshot"``, same shape as - :meth:`PoolRuntimeSnapshot.to_dict`. + :meth:`PoolRuntimeSnapshot.to_dict`; for ``kind == "event"``, small dicts such + as ``{"event": "session_started", "agent": "..."}``. """ from __future__ import annotations @@ -25,6 +26,7 @@ METRICS_STREAM_SCHEMA_VERSION = 1 KIND_SNAPSHOT = "snapshot" +KIND_EVENT = "event" def snapshot_envelope(*, seq: int, snapshot: PoolRuntimeSnapshot) -> dict[str, Any]: @@ -39,7 +41,7 @@ def snapshot_envelope(*, seq: int, snapshot: PoolRuntimeSnapshot) -> dict[str, A def parse_metrics_jsonl_line(line: str) -> dict[str, Any] | None: - """Return a parsed snapshot record, or ``None`` if the line is not a snapshot.""" + """Return a parsed stream record (snapshot or event), or ``None`` if invalid.""" stripped = line.strip() if not stripped: return None @@ -49,11 +51,23 @@ def parse_metrics_jsonl_line(line: str) -> dict[str, Any] | None: return None if record.get("schema_version") != METRICS_STREAM_SCHEMA_VERSION: return None - if record.get("kind") != KIND_SNAPSHOT: + kind = record.get("kind") + if kind not in (KIND_SNAPSHOT, KIND_EVENT): return None return record +def event_envelope(*, seq: int, payload: dict[str, Any]) -> dict[str, Any]: + """Build a JSON object for one session lifecycle (or similar) event line.""" + return { + "schema_version": METRICS_STREAM_SCHEMA_VERSION, + "kind": KIND_EVENT, + "seq": seq, + "wall_time_unix": time.time(), + "payload": dict(payload), + } + + class JsonlMetricsSink: """Append-only JSONL writer; truncates the file when opened (new worker run).""" @@ -78,6 +92,16 @@ def write_snapshot(self, snapshot: PoolRuntimeSnapshot) -> None: self._file.write(json.dumps(record, sort_keys=True) + "\n") self._file.flush() + def write_event(self, payload: dict[str, Any]) -> None: + """Append one event line after the current ``seq`` (thread-safe).""" + with self._lock: + if self._file is None: + raise RuntimeError("JsonlMetricsSink.open() was not called") + self._seq += 1 + record = event_envelope(seq=self._seq, payload=payload) + self._file.write(json.dumps(record, sort_keys=True) + "\n") + self._file.flush() + def close(self) -> None: with self._lock: if self._file is not None: diff --git a/src/openrtc/pool.py b/src/openrtc/pool.py index 5984ef0..794236f 100644 --- a/src/openrtc/pool.py +++ b/src/openrtc/pool.py @@ -270,6 +270,10 @@ def runtime_snapshot(self) -> PoolRuntimeSnapshot: """Return a live snapshot of worker metrics for dashboards and automation.""" return self._runtime_state.metrics.snapshot(registered_agents=len(self._agents)) + def drain_metrics_stream_events(self) -> list[dict[str, Any]]: + """Drain pending session lifecycle events for JSONL sidecar export.""" + return self._runtime_state.metrics.drain_stream_events() + def add( self, name: str, diff --git a/src/openrtc/resources.py b/src/openrtc/resources.py index acb1c6e..6fea476 100644 --- a/src/openrtc/resources.py +++ b/src/openrtc/resources.py @@ -3,17 +3,20 @@ import logging import sys import time +from collections import deque from collections.abc import Mapping, Sequence from dataclasses import dataclass, field from pathlib import Path from threading import Lock -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Any if TYPE_CHECKING: from openrtc.pool import AgentConfig logger = logging.getLogger("openrtc") +_STREAM_EVENTS_MAXLEN = 256 + @dataclass(frozen=True, slots=True) class AgentDiskFootprint: @@ -109,8 +112,16 @@ class RuntimeMetricsStore: last_error: str | None = None sessions_by_agent: dict[str, int] = field(default_factory=dict) _lock: Lock = field(default_factory=Lock, init=False, repr=False, compare=False) + _stream_events: deque[dict[str, Any]] = field( + default_factory=lambda: deque(maxlen=_STREAM_EVENTS_MAXLEN), + init=False, + repr=False, + compare=False, + ) def __getstate__(self) -> dict[str, object]: + with self._lock: + stream_events = list(self._stream_events) return { "started_at": self.started_at, "total_sessions_started": self.total_sessions_started, @@ -118,6 +129,7 @@ def __getstate__(self) -> dict[str, object]: "last_routed_agent": self.last_routed_agent, "last_error": self.last_error, "sessions_by_agent": dict(self.sessions_by_agent), + "_stream_events": stream_events, } def __setstate__(self, state: Mapping[str, object]) -> None: @@ -130,6 +142,11 @@ def __setstate__(self, state: Mapping[str, object]) -> None: str(key): int(value) for key, value in dict(state["sessions_by_agent"]).items() } + raw_events = state.get("_stream_events", []) + self._stream_events = deque( + list(raw_events), + maxlen=_STREAM_EVENTS_MAXLEN, + ) self._lock = Lock() def record_session_started(self, agent_name: str) -> None: @@ -140,6 +157,9 @@ def record_session_started(self, agent_name: str) -> None: self.sessions_by_agent[agent_name] = ( self.sessions_by_agent.get(agent_name, 0) + 1 ) + self._stream_events.append( + {"event": "session_started", "agent": agent_name}, + ) def record_session_finished(self, agent_name: str) -> None: """Decrement active counters once a session exits.""" @@ -150,6 +170,9 @@ def record_session_finished(self, agent_name: str) -> None: self.sessions_by_agent[agent_name] = next_value else: self.sessions_by_agent.pop(agent_name, None) + self._stream_events.append( + {"event": "session_finished", "agent": agent_name}, + ) def record_session_failure(self, agent_name: str, exc: BaseException) -> None: """Track a failed session attempt with the most recent error.""" @@ -157,6 +180,20 @@ def record_session_failure(self, agent_name: str, exc: BaseException) -> None: self.last_routed_agent = agent_name self.total_session_failures += 1 self.last_error = f"{exc.__class__.__name__}: {exc}" + self._stream_events.append( + { + "event": "session_failed", + "agent": agent_name, + "error": f"{exc.__class__.__name__}: {exc}"[:500], + }, + ) + + def drain_stream_events(self) -> list[dict[str, Any]]: + """Remove and return pending stream events for JSONL export (order preserved).""" + with self._lock: + out = list(self._stream_events) + self._stream_events.clear() + return out def snapshot(self, *, registered_agents: int) -> PoolRuntimeSnapshot: """Return a typed snapshot for dashboards and automation.""" diff --git a/src/openrtc/tui_app.py b/src/openrtc/tui_app.py index ef64cd7..b4841cf 100644 --- a/src/openrtc/tui_app.py +++ b/src/openrtc/tui_app.py @@ -8,7 +8,7 @@ from textual.app import App, ComposeResult from textual.widgets import Footer, Header, Static -from openrtc.metrics_stream import parse_metrics_jsonl_line +from openrtc.metrics_stream import KIND_EVENT, KIND_SNAPSHOT, parse_metrics_jsonl_line class MetricsTuiApp(App[None]): @@ -24,6 +24,7 @@ def __init__(self, watch_path: Path, *, from_start: bool = False) -> None: self._fh: Any = None self._buf = "" self._latest: dict[str, Any] | None = None + self._last_event: dict[str, Any] | None = None def compose(self) -> ComposeResult: yield Header(show_clock=True) @@ -31,6 +32,7 @@ def compose(self) -> ComposeResult: "Waiting for JSONL metrics (run the worker with --metrics-jsonl)…", id="status", ) + yield Static("", id="event") yield Static("", id="agents") yield Static("", id="detail") yield Footer() @@ -59,9 +61,25 @@ def _poll_file(self) -> None: while "\n" in self._buf: line, self._buf = self._buf.split("\n", 1) rec = parse_metrics_jsonl_line(line) - if rec is not None: + if rec is None: + continue + if rec.get("kind") == KIND_SNAPSHOT: self._latest = rec self._refresh_view() + elif rec.get("kind") == KIND_EVENT: + pl = rec.get("payload") + if isinstance(pl, dict): + self._last_event = pl + self._refresh_event_line() + + def _refresh_event_line(self) -> None: + if self._last_event is None: + return + ev = self.query_one("#event", Static) + ev.update( + "[bold]Last event[/bold] " + + " ".join(f"{k}={v!r}" for k, v in sorted(self._last_event.items())) + ) def _refresh_view(self) -> None: if self._latest is None: diff --git a/tests/test_cli.py b/tests/test_cli.py index 260549a..f47e686 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -60,6 +60,9 @@ def discover(self, agents_dir: Path) -> list[StubConfig]: def run(self) -> None: self.run_called = True + def drain_metrics_stream_events(self) -> list[dict[str, Any]]: + return [] + def runtime_snapshot(self) -> PoolRuntimeSnapshot: self.runtime_snapshot_calls += 1 return PoolRuntimeSnapshot( diff --git a/tests/test_metrics_stream.py b/tests/test_metrics_stream.py index 5a2f593..b3c21f9 100644 --- a/tests/test_metrics_stream.py +++ b/tests/test_metrics_stream.py @@ -49,6 +49,9 @@ class _StubPool: def __init__(self) -> None: self._snap = _minimal_snapshot() + def drain_metrics_stream_events(self) -> list[dict[str, object]]: + return [] + def runtime_snapshot(self) -> PoolRuntimeSnapshot: return self._snap @@ -71,6 +74,47 @@ def test_parse_metrics_jsonl_line() -> None: assert parse_metrics_jsonl_line('{"schema_version": 999}') is None +def test_parse_metrics_jsonl_line_accepts_event() -> None: + line = json.dumps( + { + "schema_version": METRICS_STREAM_SCHEMA_VERSION, + "kind": "event", + "seq": 2, + "wall_time_unix": 3.0, + "payload": {"event": "session_started", "agent": "x"}, + }, + sort_keys=True, + ) + rec = parse_metrics_jsonl_line(line) + assert rec is not None + assert rec["kind"] == "event" + assert rec["payload"]["agent"] == "x" + + +def test_jsonl_sink_writes_snapshot_then_event(tmp_path: Path) -> None: + path = tmp_path / "e.jsonl" + sink = JsonlMetricsSink(path) + sink.open() + sink.write_snapshot(_minimal_snapshot()) + sink.write_event({"event": "session_finished", "agent": "a"}) + sink.close() + lines = path.read_text(encoding="utf-8").strip().split("\n") + assert len(lines) == 2 + assert json.loads(lines[0])["kind"] == KIND_SNAPSHOT + assert json.loads(lines[1])["kind"] == "event" + assert json.loads(lines[1])["seq"] == 2 + + +def test_runtime_metrics_store_drains_stream_events() -> None: + from openrtc.resources import RuntimeMetricsStore + + store = RuntimeMetricsStore() + store.record_session_started("dental") + drained = store.drain_stream_events() + assert drained == [{"event": "session_started", "agent": "dental"}] + assert store.drain_stream_events() == [] + + def test_snapshot_envelope_shape() -> None: snap = _minimal_snapshot() env = snapshot_envelope(seq=7, snapshot=snap) From 6447e1d8c692d0c9a446e9c5a27c32fb2072f26b Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 22 Mar 2026 03:08:27 +0000 Subject: [PATCH 06/18] test: broaden coverage for metrics JSONL, TUI, and CLI integration - CLI: start with --metrics-jsonl writes valid snapshot records; tui import guard asserted via caplog when openrtc.tui_app fails to import. - metrics_stream: reject unknown kind; JsonlMetricsSink requires open(); reporter ordering snapshot then drained events. - tui_app: event line rendering; malformed JSON line skipped before valid. Co-authored-by: Mahimai Raja J --- tests/test_cli.py | 62 ++++++++++++++++++++++++++++++++ tests/test_metrics_stream.py | 70 ++++++++++++++++++++++++++++++++++++ tests/test_tui_app.py | 42 ++++++++++++++++++++++ 3 files changed, 174 insertions(+) diff --git a/tests/test_cli.py b/tests/test_cli.py index f47e686..6a75b29 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1,5 +1,6 @@ from __future__ import annotations +import builtins import importlib import json import logging @@ -456,3 +457,64 @@ def test_start_command_can_write_runtime_metrics_json( assert data["active_sessions"] == 1 assert data["registered_agents"] == 1 assert data["sessions_by_agent"]["restaurant"] == 1 + + +def test_start_command_metrics_jsonl_writes_snapshot_records( + monkeypatch: pytest.MonkeyPatch, + tmp_path: Path, +) -> None: + """``--metrics-jsonl`` produces JSON Lines the sidecar TUI can tail.""" + jsonl = tmp_path / "sidecar.jsonl" + stub_pool = StubPool( + discovered=[StubConfig(name="restaurant", agent_cls=StubAgent)] + ) + monkeypatch.setattr("openrtc.cli_app.AgentPool", lambda **kwargs: stub_pool) + + runner = CliRunner() + result = runner.invoke( + app, + [ + "start", + "--agents-dir", + "./agents", + "--metrics-jsonl", + str(jsonl), + "--metrics-jsonl-interval", + "0.3", + ], + ) + + assert result.exit_code == 0 + assert stub_pool.run_called is True + lines = [ln for ln in jsonl.read_text(encoding="utf-8").split("\n") if ln.strip()] + assert len(lines) >= 1 + first = json.loads(lines[0]) + assert first["schema_version"] == 1 + assert first["kind"] == "snapshot" + assert "payload" in first + assert first["payload"]["registered_agents"] == 1 + + +def test_tui_command_exits_when_textual_is_not_importable( + monkeypatch: pytest.MonkeyPatch, + caplog: pytest.LogCaptureFixture, +) -> None: + """``openrtc tui`` fails fast with a clear message if the TUI extra is absent.""" + real_import = builtins.__import__ + + def guard(name: str, *args: object, **kwargs: object) -> object: + if name == "openrtc.tui_app": + raise ImportError("simulated missing textual") + return real_import(name, *args, **kwargs) + + monkeypatch.setattr(builtins, "__import__", guard) + runner = CliRunner() + with caplog.at_level(logging.ERROR, logger="openrtc"): + result = runner.invoke( + app, + ["tui", "--watch", "./metrics.jsonl"], + catch_exceptions=False, + ) + assert result.exit_code == 1 + assert "Textual" in caplog.text + assert "openrtc[tui]" in caplog.text diff --git a/tests/test_metrics_stream.py b/tests/test_metrics_stream.py index b3c21f9..2c93cf7 100644 --- a/tests/test_metrics_stream.py +++ b/tests/test_metrics_stream.py @@ -1,11 +1,16 @@ +"""Tests for JSONL metrics stream, sink, and RuntimeReporter export.""" + from __future__ import annotations import json import time from pathlib import Path +import pytest + from openrtc.cli_app import RuntimeReporter from openrtc.metrics_stream import ( + KIND_EVENT, KIND_SNAPSHOT, METRICS_STREAM_SCHEMA_VERSION, JsonlMetricsSink, @@ -74,6 +79,28 @@ def test_parse_metrics_jsonl_line() -> None: assert parse_metrics_jsonl_line('{"schema_version": 999}') is None +def test_parse_metrics_jsonl_line_rejects_unknown_kind() -> None: + bad = json.dumps( + { + "schema_version": METRICS_STREAM_SCHEMA_VERSION, + "kind": "future-kind", + "seq": 1, + "wall_time_unix": 0.0, + "payload": {}, + } + ) + assert parse_metrics_jsonl_line(bad) is None + + +def test_jsonl_metrics_sink_requires_open_before_write(tmp_path: Path) -> None: + sink = JsonlMetricsSink(tmp_path / "unopened.jsonl") + snap = _minimal_snapshot() + with pytest.raises(RuntimeError, match="open"): + sink.write_snapshot(snap) + with pytest.raises(RuntimeError, match="open"): + sink.write_event({"event": "x"}) + + def test_parse_metrics_jsonl_line_accepts_event() -> None: line = json.dumps( { @@ -158,6 +185,49 @@ def test_jsonl_sink_new_open_truncates_previous_file(tmp_path: Path) -> None: assert json.loads(lines[0])["seq"] == 1 +def test_runtime_reporter_emits_snapshot_then_drained_events_in_order( + tmp_path: Path, +) -> None: + """Each tick writes one snapshot line, then any events from the pool (order).""" + + class _PoolWithOneEvent: + def __init__(self) -> None: + self._sent = False + + def runtime_snapshot(self) -> PoolRuntimeSnapshot: + return _minimal_snapshot() + + def drain_metrics_stream_events(self) -> list[dict[str, object]]: + if self._sent: + return [] + self._sent = True + return [{"event": "session_started", "agent": "demo"}] + + path = tmp_path / "ordered.jsonl" + pool = _PoolWithOneEvent() + reporter = RuntimeReporter( + pool, + dashboard=False, + refresh_seconds=0.25, + json_output_path=None, + metrics_jsonl_path=path, + metrics_jsonl_interval=0.25, + ) + reporter.start() + time.sleep(0.6) + reporter.stop() + + lines = [ln for ln in path.read_text(encoding="utf-8").split("\n") if ln.strip()] + assert len(lines) >= 1 + first = json.loads(lines[0]) + assert first["kind"] == KIND_SNAPSHOT + assert first["seq"] >= 1 + if len(lines) >= 2: + second = json.loads(lines[1]) + assert second["kind"] == KIND_EVENT + assert second["payload"]["event"] == "session_started" + + def test_runtime_reporter_emits_jsonl_periodically(tmp_path: Path) -> None: path = tmp_path / "live.jsonl" pool = _StubPool() diff --git a/tests/test_tui_app.py b/tests/test_tui_app.py index e38c040..5ed0572 100644 --- a/tests/test_tui_app.py +++ b/tests/test_tui_app.py @@ -1,3 +1,5 @@ +"""Tests for the Textual sidecar ``openrtc tui --watch`` (requires Textual).""" + from __future__ import annotations import json @@ -40,6 +42,46 @@ def _minimal_snapshot() -> PoolRuntimeSnapshot: ) +@pytest.mark.asyncio +async def test_metrics_tui_displays_event_line(tmp_path) -> None: + from openrtc.metrics_stream import event_envelope + from openrtc.tui_app import MetricsTuiApp + + path = tmp_path / "ev.jsonl" + ev = json.dumps( + event_envelope(seq=2, payload={"event": "session_started", "agent": "a"}), + sort_keys=True, + ) + path.write_text(ev + "\n", encoding="utf-8") + + app = MetricsTuiApp(path, from_start=True) + async with app.run_test() as pilot: + app._poll_file() + await pilot.pause() + event_w = app.query_one("#event") + text = str(event_w.renderable) + assert "session_started" in text + assert "agent" in text + assert "a" in text + + +@pytest.mark.asyncio +async def test_metrics_tui_skips_malformed_line_then_parses_valid(tmp_path) -> None: + from openrtc.tui_app import MetricsTuiApp + + path = tmp_path / "mix.jsonl" + snap = _minimal_snapshot() + good = json.dumps(snapshot_envelope(seq=1, snapshot=snap), sort_keys=True) + path.write_text("not-valid-json\n" + good + "\n", encoding="utf-8") + + app = MetricsTuiApp(path, from_start=True) + async with app.run_test() as pilot: + app._poll_file() + await pilot.pause() + status = app.query_one("#status") + assert "seq=1" in str(status.renderable) + + @pytest.mark.asyncio async def test_metrics_tui_displays_snapshot_line(tmp_path) -> None: from openrtc.tui_app import MetricsTuiApp From 8bfdcddf4efe5f37163335b7259dfccc6958e47a Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 22 Mar 2026 03:11:29 +0000 Subject: [PATCH 07/18] refactor(cli): emphasize minimal defaults and Advanced option group - Root help + epilog: typical path is dev/start with only --agents-dir and LIVEKIT_* env; note conservative defaults and Advanced panel in subcommand help. - Group tuning flags under Rich panel "Advanced" (refresh interval, JSONL interval, default greeting, participant identity, log level, metrics JSON file, list --resources). - Slim download-files to agents-dir + connection only; provider defaults unused. - Test that download-files rejects --default-stt. Co-authored-by: Mahimai Raja J --- src/openrtc/cli_app.py | 69 +++++++++++++++++++++++------------------- tests/test_cli.py | 20 ++++++++++++ 2 files changed, 58 insertions(+), 31 deletions(-) diff --git a/src/openrtc/cli_app.py b/src/openrtc/cli_app.py index 25c341c..b3c77b7 100644 --- a/src/openrtc/cli_app.py +++ b/src/openrtc/cli_app.py @@ -32,20 +32,26 @@ PANEL_OPENRTC = "OpenRTC" PANEL_LIVEKIT = "Connection" +PANEL_ADVANCED = "Advanced" + +_QUICKSTART_EPILOG = ( + "[bold]Typical usage[/bold]: set [code]LIVEKIT_URL[/code], [code]LIVEKIT_API_KEY[/code], " + "and [code]LIVEKIT_API_SECRET[/code], then run " + "[code]openrtc dev --agents-dir PATH[/code] (or [code]start[/code] in production). " + "Defaults are conservative (e.g. no dashboard, 1s refresh); tuning flags are under " + "the [bold]Advanced[/bold] group in each command's [code]--help[/code]." +) app = typer.Typer( name="openrtc", help=( - "Run multiple LiveKit voice agents from one shared worker. Subcommands mirror " - "the LiveKit Agents CLI ([code]dev[/code], [code]start[/code], [code]console[/code], " - "[code]connect[/code], [code]download-files[/code]) as in " - "[code]python agent.py [/code]. " - "Add [code]--agents-dir[/code] so OpenRTC discovers and registers agents; use " - "[code]--url[/code] / [code]--api-key[/code] / [code]--api-secret[/code] or " - "the usual [code]LIVEKIT_*[/code] environment variables for the server. " - "Use [code]openrtc tui --watch FILE[/code] (with the [code]tui[/code] extra) to " - "tail [code]--metrics-jsonl[/code] in a separate terminal." + "Run multiple LiveKit voice agents from one shared worker. Commands match " + "LiveKit Agents ([code]dev[/code], [code]start[/code], [code]console[/code], " + "[code]connect[/code], [code]download-files[/code]) plus [code]list[/code] and " + "[code]tui[/code]. Only [code]--agents-dir[/code] is required for worker commands; " + "credentials use [code]LIVEKIT_*[/code] env vars by default (CLI flags optional)." ), + epilog=_QUICKSTART_EPILOG, pretty_exceptions_show_locals=False, rich_markup_mode="rich", no_args_is_help=True, @@ -547,7 +553,7 @@ def _truncate_cell(text: str, max_len: int = 36) -> str: Path, typer.Option( "--agents-dir", - help="Directory containing discoverable agent modules.", + help="Directory of agent modules to load (only required flag for most workflows).", exists=False, resolve_path=True, path_type=Path, @@ -599,7 +605,7 @@ def _truncate_cell(text: str, max_len: int = 36) -> str: "Default greeting used when a discovered agent does not " "override greeting via @agent_config(...)." ), - rich_help_panel=PANEL_OPENRTC, + rich_help_panel=PANEL_ADVANCED, ), ] @@ -607,7 +613,7 @@ def _truncate_cell(text: str, max_len: int = 36) -> str: bool, typer.Option( "--dashboard", - help="Show a live Rich dashboard with worker memory and active sessions.", + help="Show a live Rich dashboard (off by default; use for local debugging).", rich_help_panel=PANEL_OPENRTC, ), ] @@ -617,8 +623,8 @@ def _truncate_cell(text: str, max_len: int = 36) -> str: typer.Option( "--dashboard-refresh", min=0.25, - help="Refresh interval in seconds for the runtime dashboard and metrics file.", - rich_help_panel=PANEL_OPENRTC, + help="Refresh interval in seconds for dashboard / metrics file / JSONL (default 1s).", + rich_help_panel=PANEL_ADVANCED, ), ] @@ -626,10 +632,10 @@ def _truncate_cell(text: str, max_len: int = 36) -> str: Path | None, typer.Option( "--metrics-json-file", - help="Write live runtime metrics snapshots to this JSON file for automation.", + help="Overwrite a JSON file each tick with the latest snapshot (automation / CI).", resolve_path=True, path_type=Path, - rich_help_panel=PANEL_OPENRTC, + rich_help_panel=PANEL_ADVANCED, ), ] @@ -638,8 +644,8 @@ def _truncate_cell(text: str, max_len: int = 36) -> str: typer.Option( "--metrics-jsonl", help=( - "Append versioned metrics snapshots as JSON Lines for ``openrtc tui --watch`` " - "(truncates the file when the worker starts)." + "Append JSON Lines for ``openrtc tui --watch`` (off by default; " + "truncates when the worker starts)." ), resolve_path=True, path_type=Path, @@ -653,7 +659,7 @@ def _truncate_cell(text: str, max_len: int = 36) -> str: "--metrics-jsonl-interval", min=0.25, help=("Seconds between JSONL records (default: same as --dashboard-refresh)."), - rich_help_panel=PANEL_OPENRTC, + rich_help_panel=PANEL_ADVANCED, ), ] @@ -673,7 +679,7 @@ def _truncate_cell(text: str, max_len: int = 36) -> str: typer.Option( "--from-start", help="Read the file from the beginning instead of tailing from EOF.", - rich_help_panel=PANEL_OPENRTC, + rich_help_panel=PANEL_ADVANCED, ), ] @@ -721,7 +727,7 @@ def _truncate_cell(text: str, max_len: int = 36) -> str: typer.Option( "--participant-identity", help="Agent participant identity when connecting to the room.", - rich_help_panel=PANEL_LIVEKIT, + rich_help_panel=PANEL_ADVANCED, ), ] @@ -732,7 +738,7 @@ def _truncate_cell(text: str, max_len: int = 36) -> str: help="Log level (e.g. DEBUG, INFO, WARN, ERROR).", envvar="LIVEKIT_LOG_LEVEL", case_sensitive=False, - rich_help_panel=PANEL_LIVEKIT, + rich_help_panel=PANEL_ADVANCED, ), ] @@ -750,6 +756,7 @@ def list_command( "Memory line is OS-specific (Linux: current VmRSS; macOS: peak " "ru_maxrss, not live RSS—see JSON description)." ), + rich_help_panel=PANEL_ADVANCED, ), ] = False, json_output: Annotated[ @@ -1075,23 +1082,23 @@ def connect_command( @app.command("download-files") def download_files_command( agents_dir: AgentsDirArg, - default_stt: DefaultSttArg = None, - default_llm: DefaultLlmArg = None, - default_tts: DefaultTtsArg = None, - default_greeting: DefaultGreetingArg = None, url: LiveKitUrlArg = None, api_key: LiveKitApiKeyArg = None, api_secret: LiveKitApiSecretArg = None, log_level: LiveKitLogLevelArg = None, ) -> None: - """Download plugin assets (LiveKit [code]download-files[/code]).""" + """Download plugin assets (LiveKit [code]download-files[/code]). + + Uses the same discovery path as other commands so the worker entrypoint is + valid; provider defaults are not needed for this subcommand. + """ _delegate_discovered_pool_to_livekit( agents_dir=agents_dir, subcommand="download-files", - default_stt=default_stt, - default_llm=default_llm, - default_tts=default_tts, - default_greeting=default_greeting, + default_stt=None, + default_llm=None, + default_tts=None, + default_greeting=None, dashboard=False, dashboard_refresh=1.0, metrics_json_file=None, diff --git a/tests/test_cli.py b/tests/test_cli.py index 6a75b29..2490a1b 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -230,6 +230,26 @@ def test_cli_returns_non_zero_when_no_agents_are_discovered( assert exit_code == 1 +def test_download_files_has_minimal_options_no_provider_defaults( + tmp_path: Path, +) -> None: + """download-files only needs agents dir + connection; no --default-* flags.""" + runner = CliRunner() + result = runner.invoke( + app, + [ + "download-files", + "--agents-dir", + str(tmp_path), + "--default-stt", + "deepgram/x", + ], + ) + assert result.exit_code != 0 + out = (result.stdout or "") + (result.stderr or "") + assert "No such option" in out and "default-stt" in out + + def test_list_exits_cleanly_when_agents_dir_does_not_exist( tmp_path: Path, caplog: pytest.LogCaptureFixture, From 2a21856bb10fb5667295e08200a9f91310c77dcf Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 22 Mar 2026 03:17:34 +0000 Subject: [PATCH 08/18] docs: update documentation for CLI, metrics stream, and TUI features Update user-facing documentation to reflect the new `openrtc[tui]` extra, `openrtc tui`, `--metrics-jsonl`, console/connect/download-files commands, CLI ergonomics (help panels, flag stripping), and `drain_metrics_stream_events()`. Co-authored-by: Mahimai Raja J --- .agents/skills/openrtc-python/SKILL.md | 14 +- AGENTS.md | 4 +- CONTRIBUTING.md | 6 +- README.md | 78 ++++++++--- docs/api/pool.md | 13 +- docs/cli.md | 185 ++++++++++++++++++------- docs/getting-started.md | 28 +++- docs/index.md | 8 +- 8 files changed, 253 insertions(+), 83 deletions(-) diff --git a/.agents/skills/openrtc-python/SKILL.md b/.agents/skills/openrtc-python/SKILL.md index c0eaad6..a703d75 100644 --- a/.agents/skills/openrtc-python/SKILL.md +++ b/.agents/skills/openrtc-python/SKILL.md @@ -111,12 +111,20 @@ exactly one `Agent` subclass at module scope, and the filename doesn't start with `_`. Fix and re-run `openrtc list` until all agents appear. ```bash -# Development mode (auto-reload) +# Development mode (auto-reload) — set LIVEKIT_* env vars first openrtc dev --agents-dir ./agents # Production mode openrtc start --agents-dir ./agents +# Same LiveKit subcommands as python agent.py: console, connect, download-files +# openrtc console --agents-dir ./agents +# openrtc connect --agents-dir ./agents --room my-room + +# Optional: JSON Lines metrics + sidecar TUI (pip install 'openrtc[cli,tui]') +# openrtc dev --agents-dir ./agents --metrics-jsonl ./metrics.jsonl +# openrtc tui --watch ./metrics.jsonl + # Or run the entrypoint directly python main.py dev ``` @@ -144,6 +152,10 @@ Unknown metadata names raise `ValueError` — no silent fallback. - **`pool.run()` delegates to `livekit.agents.cli.run_app()`.** The first CLI argument must be `dev` or `start` (e.g. `python main.py dev`). Without it, the process exits immediately with a usage error. +- **`openrtc dev|start|…` sets up discovery then calls the same LiveKit CLI.** + OpenRTC-only flags (`--agents-dir`, `--dashboard`, `--metrics-jsonl`, …) are + stripped from `sys.argv` before LiveKit parses arguments—do not expect LiveKit + to understand them. - **Provider objects must be pickleable.** OpenRTC has built-in serialization for `livekit.plugins.openai` STT, TTS, and LLM. Other providers: use string identifiers or ensure the object is natively pickleable. diff --git a/AGENTS.md b/AGENTS.md index 1627a71..a13daab 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -403,7 +403,7 @@ When in doubt: All commands are documented in `CONTRIBUTING.md`. Quick reference: - **Install deps:** `uv sync --group dev` -- **Tests:** `uv run pytest` (36 tests, all self-contained) +- **Tests:** `uv run pytest` (self-contained; no LiveKit server required) - **Lint:** `uv run ruff check .` - **Format check:** `uv run ruff format --check .` - **Type check:** `uv run mypy src/` (3 pre-existing errors as of this writing) @@ -414,6 +414,6 @@ All commands are documented in `CONTRIBUTING.md`. Quick reference: - The `tests/conftest.py` creates a fake `livekit.agents` module when the real one isn't importable. This allows tests to run without the full LiveKit SDK. The real SDK *is* installed by `uv sync`, but if you see import weirdness in tests, this shim is the reason. - Version is derived from git tags via `hatch-vcs`. In a dev checkout the version will be something like `0.0.9.dev0+g`. - `mypy` has 3 pre-existing errors in `pool.py` — these are not regressions from your changes. -- Running `openrtc start` or `openrtc dev` requires a running LiveKit server and provider API keys. For development validation, use `openrtc list` which exercises discovery and routing without network dependencies. +- Running `openrtc start` or `openrtc dev` requires a running LiveKit server and provider API keys. For development validation, use `openrtc list` which exercises discovery and routing without network dependencies. The optional sidecar metrics TUI (`openrtc tui --watch`, requires `openrtc[tui]` / dev deps) tails `--metrics-jsonl` from a worker in another terminal. - `pytest-cov` is in the dev dependency group; CI uses `--cov-fail-under=80`; run `uv run pytest --cov=openrtc --cov-report=xml --cov-fail-under=80` to match. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 25a521b..1c0824b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,8 +15,10 @@ This repository uses `uv` for local development. uv sync --group dev ``` -The dev group includes Typer and Rich so `uv run openrtc …` works without -`--extra cli`. End users install the CLI with `pip install 'openrtc[cli]'`. +The dev group includes Typer, Rich, and Textual so `uv run openrtc …` and +`uv run openrtc tui …` work without extra install flags. End users install the +CLI with `pip install 'openrtc[cli]'` and the sidecar TUI with +`pip install 'openrtc[tui]'` (or `openrtc[cli,tui]` together). If you prefer, you can also install the package and dev dependencies with pip, but `uv` is the preferred workflow for contributors. diff --git a/README.md b/README.md index 4bd4ac8..1bf3216 100644 --- a/README.md +++ b/README.md @@ -101,12 +101,19 @@ pip install openrtc The base package pulls in `livekit-agents[openai,silero,turn-detector]`, so the runtime plugins required by shared prewarm are installed without extra flags. -Install the Typer/Rich CLI (`openrtc list`, `openrtc start`, `openrtc dev`) with: +Install the Typer/Rich CLI (`openrtc list`, `openrtc start`, `openrtc dev`, …) +with: ```bash pip install 'openrtc[cli]' ``` +Install the optional **Textual sidecar TUI** (`openrtc tui --watch`) with: + +```bash +pip install 'openrtc[cli,tui]' +``` + If you are developing locally, the repository uses `uv` for environment and command management. @@ -274,7 +281,26 @@ deployments. ## CLI usage -OpenRTC includes a CLI for discovery-based workflows. +OpenRTC includes a CLI for discovery-based workflows. Subcommands mirror the +LiveKit Agents CLI (`dev`, `start`, `console`, `connect`, `download-files`, as +in `python agent.py `), plus `list` and `tui`. + +**Typical path:** set `LIVEKIT_URL`, `LIVEKIT_API_KEY`, and `LIVEKIT_API_SECRET`, +then run the worker with only `--agents-dir` (plus any `--default-*` strings +your agents need). + +```bash +export LIVEKIT_URL=ws://localhost:7880 +export LIVEKIT_API_KEY=devkey +export LIVEKIT_API_SECRET=secret + +openrtc dev --agents-dir ./agents +# or +openrtc start --agents-dir ./agents +``` + +Defaults are conservative (no dashboard, 1s refresh where applicable). Tuning +flags are grouped under **Advanced** in each command’s `--help`. ### List discovered agents @@ -299,35 +325,34 @@ Stable output for scripts and CI: current **VmRSS**; on **macOS** it is **peak** `ru_maxrss` (bytes), not instantaneous live RSS—compare runs only on the same OS. -### Run in production mode +### Run workers (production and development) ```bash openrtc start --agents-dir ./agents -openrtc start --agents-dir ./agents --dashboard -``` - -### Run in development mode - -```bash openrtc dev --agents-dir ./agents -openrtc dev --agents-dir ./examples/agents --dashboard --metrics-json-file ./runtime.json ``` -Both `start` and `dev` discover agents first and then hand off to the underlying -LiveKit worker runtime. +Optional runtime visibility: + +- **`--dashboard`** — Rich summary (worker RSS, sessions, routing, savings + estimate). Off by default. +- **`--metrics-json-file ./runtime.json`** — Overwrites a JSON file each tick with + the latest snapshot (automation / CI). See **Advanced** in `--help`. +- **`--metrics-jsonl ./openrtc-metrics.jsonl`** — Append **JSON Lines** (truncates + when the worker starts): versioned `snapshot` rows plus optional `event` + rows for session lifecycle. Use with a second terminal: -The optional runtime dashboard shows: + ```bash + pip install 'openrtc[cli,tui]' + openrtc tui --watch ./openrtc-metrics.jsonl + ``` -- current worker RSS -- active sessions and total handled sessions -- per-agent load -- the last routed agent and latest failure -- an estimated memory-savings comparison between one shared worker and one - worker per registered agent +Other worker subcommands match LiveKit: `openrtc console`, `openrtc connect +--room …`, and `openrtc download-files` (minimal options: agents dir + connection +only). See [docs/cli.md](docs/cli.md) for full detail. -For automation, `--metrics-json-file` writes the same runtime snapshot as JSON -while the worker is running. See [docs/cli.md](docs/cli.md) for a step-by-step -"prove the value" workflow. +Worker commands discover agents first, then delegate to the LiveKit CLI; +OpenRTC-only flags are not forwarded to LiveKit’s parser. ## Public API at a glance @@ -347,6 +372,8 @@ On `AgentPool`, the primary public methods and properties are: - `remove(name)` - `run()` - `runtime_snapshot()` +- `drain_metrics_stream_events()` — drain queued session lifecycle events for JSONL + export (used by the CLI; rarely needed in application code) - `server` ## Project structure @@ -355,11 +382,16 @@ On `AgentPool`, the primary public methods and properties are: src/openrtc/ ├── __init__.py ├── cli.py +├── cli_app.py +├── metrics_stream.py +├── tui_app.py └── pool.py ``` - `pool.py` contains the core `AgentPool` implementation and discovery helpers -- `cli.py` provides discovery and worker startup commands +- `cli.py` / `cli_app.py` provide the Typer/Rich CLI (`openrtc[cli]`) +- `metrics_stream.py` defines the JSONL metrics stream format +- `tui_app.py` implements the optional Textual sidecar (`openrtc[tui]`) - `__init__.py` exposes the public package API ## Contributing diff --git a/docs/api/pool.md b/docs/api/pool.md index 24c3f41..8bf1e6f 100644 --- a/docs/api/pool.md +++ b/docs/api/pool.md @@ -211,7 +211,8 @@ snapshot = pool.runtime_snapshot() ``` Returns a typed runtime snapshot for the current shared worker. The snapshot is -used by the CLI dashboard and `--metrics-json-file` output and includes: +used by the CLI dashboard, `--metrics-json-file`, and `kind: "snapshot"` lines +in `--metrics-jsonl` output. It includes: - resident memory metadata - registered and active session counts @@ -221,6 +222,16 @@ used by the CLI dashboard and `--metrics-json-file` output and includes: - last routed agent - a best-effort shared-worker savings estimate +## `drain_metrics_stream_events()` + +```python +events = pool.drain_metrics_stream_events() +``` + +Removes and returns queued **session lifecycle** records for JSONL export +(`session_started`, `session_finished`, `session_failed`). The OpenRTC CLI calls +this when writing `--metrics-jsonl`; most applications can ignore it. + ## Routing behavior `AgentPool` resolves the active agent in this order: diff --git a/docs/cli.md b/docs/cli.md index 92ba1c1..5698260 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -7,22 +7,68 @@ programmatic entry is `typer.main.get_command(app).main(...)` (Click’s ## Installation -The **library** ( `AgentPool`, discovery, routing ) installs with: +The **library** (`AgentPool`, discovery, routing) installs with: ```bash pip install openrtc ``` -The **CLI stack** (Typer, Rich) is declared as the optional extra `cli`: +The **CLI stack** (Typer, Rich) is the optional extra `cli`: ```bash pip install 'openrtc[cli]' ``` +The **sidecar TUI** (Textual) is a separate optional extra: + +```bash +pip install 'openrtc[cli,tui]' +``` + If Typer/Rich are not importable, `openrtc.cli:main` exits with `1` and prints -an install hint. In practice, `livekit-agents` may pull Typer transitively, so -the hint path is mainly covered by tests and edge environments—see -`tests/test_cli_optional_extra_integration.py` in the repo. +an install hint. If Textual is missing, `openrtc tui` logs an error and exits +with `1`. + +## Typical usage + +1. Set the same variables as a standard LiveKit worker: + + ```bash + export LIVEKIT_URL=ws://localhost:7880 + export LIVEKIT_API_KEY=devkey + export LIVEKIT_API_SECRET=secret + ``` + +2. Run a worker subcommand with **only** `--agents-dir` (plus any provider + defaults your agents need): + + ```bash + openrtc dev --agents-dir ./agents + # or + openrtc start --agents-dir ./agents + ``` + +Defaults are conservative: **no** Rich dashboard unless you pass `--dashboard`, +and **no** metrics files unless you pass `--metrics-json-file` or +`--metrics-jsonl`. Refresh intervals default to **1 second** where applicable. + +Subcommands mirror the LiveKit Agents CLI (`python agent.py dev`, `start`, +`console`, `connect`, `download-files`). OpenRTC adds **`--agents-dir`** for +discovery, then delegates to `livekit.agents.cli.run_app`. OpenRTC-only flags are +stripped from `sys.argv` before that handoff so LiveKit does not see options +like `--agents-dir`. + +## Connection overrides + +You can override `LIVEKIT_*` per invocation: + +- `--url` +- `--api-key` +- `--api-secret` +- `--log-level` (also `LIVEKIT_LOG_LEVEL`) + +These appear under **Connection** or **Advanced** in `--help` depending on the +flag. ## Commands @@ -37,6 +83,8 @@ Discovers agent modules and prints each agent’s resolved settings. when the shape changes) and `command: "list"`. Combine with `--resources` for `resource_summary`. - **`--plain` and `--json` together** are rejected (non-zero exit). +- **`--resources`** — Footprint and memory hints (grouped under **Advanced** in + `--help`). ```bash openrtc list --agents-dir ./agents @@ -46,40 +94,88 @@ openrtc list --agents-dir ./agents --json ### `openrtc start` -Discovers agent modules and starts the LiveKit worker in production mode. +Production-style worker (same role as `python agent.py start`). ```bash openrtc start --agents-dir ./agents ``` -Optional runtime visibility: - -- **`--dashboard`** — Show a live Rich dashboard with worker RSS, active - sessions, failures, and an estimated “separate workers vs shared worker” - savings comparison. -- **`--dashboard-refresh 1.0`** — Control how often the dashboard refreshes. -- **`--metrics-json-file ./openrtc-runtime.json`** — Write a live JSON snapshot - for automation and host-side tooling. - ### `openrtc dev` -Discovers agent modules and starts the LiveKit worker in development mode. +Development worker with reload (same role as `python agent.py dev`). ```bash openrtc dev --agents-dir ./agents -openrtc dev --agents-dir ./examples/agents --dashboard -openrtc dev --agents-dir ./examples/agents --dashboard --metrics-json-file ./runtime.json ``` -## Shared default options +### `openrtc console` + +Local console session (same role as `python agent.py console`). + +```bash +openrtc console --agents-dir ./agents +``` + +### `openrtc connect` + +Connect the worker to an existing room (LiveKit `connect`). Requires +`--room`. -Each command accepts these optional defaults, which are applied when a +```bash +openrtc connect --agents-dir ./agents --room my-room +``` + +### `openrtc download-files` + +Download plugin assets (LiveKit `download-files`). Only needs the agents +directory (for a valid worker entrypoint) plus connection settings—**no** +`--default-stt` / `--default-llm` / `--default-tts` / `--default-greeting`. + +```bash +openrtc download-files --agents-dir ./agents +``` + +### `openrtc tui` + +Sidecar Textual UI that tails a **JSON Lines** metrics file written by the +worker (`--metrics-jsonl`). Requires `openrtc[tui]`. + +```bash +# Terminal 1 +openrtc dev --agents-dir ./agents --metrics-jsonl ./openrtc-metrics.jsonl + +# Terminal 2 +openrtc tui --watch ./openrtc-metrics.jsonl +``` + +Use **`--from-start`** (under **Advanced**) to read the file from the beginning +instead of tailing from EOF. + +## Runtime visibility and automation + +- **`--dashboard`** — Live Rich summary (RSS, sessions, routing, savings + estimate). Off by default. +- **`--metrics-json-file PATH`** — Overwrites a JSON file each tick with the + latest `PoolRuntimeSnapshot` (good for scripts). Grouped under **Advanced**. +- **`--metrics-jsonl PATH`** — Appends **versioned JSON Lines** (truncates when + the worker starts). Each line is one record: `schema_version`, `kind` + (`snapshot` or `event`), `seq`, `wall_time_unix`, `payload`. Snapshots match + `PoolRuntimeSnapshot.to_dict()`; events carry session lifecycle hints + (`session_started`, `session_finished`, `session_failed`). Intended for + `openrtc tui --watch` and other tail consumers. +- **`--dashboard-refresh`** — Interval in seconds for dashboard, metrics file, + and JSONL when `--metrics-jsonl-interval` is not set (**Advanced**). +- **`--metrics-jsonl-interval`** — Override JSONL cadence only (**Advanced**). + +## Shared default options (discovery) + +Worker commands that load agents accept optional defaults applied when a discovered agent does not override them via `@agent_config(...)`: - `--default-stt` - `--default-llm` - `--default-tts` -- `--default-greeting` +- `--default-greeting` (**Advanced**) Example: @@ -88,12 +184,11 @@ openrtc list \ --agents-dir ./examples/agents \ --default-stt openai/gpt-4o-mini-transcribe \ --default-llm openai/gpt-4.1-mini \ - --default-tts openai/gpt-4o-mini-tts \ - --default-greeting "Hello from OpenRTC." + --default-tts openai/gpt-4o-mini-tts ``` -These defaults are passed through to `livekit-agents` as raw strings. If you -need provider-native plugin objects, configure them in Python with `AgentPool` +These defaults are passed through to `livekit-agents` as raw strings. For +provider-native plugin objects, configure them in Python with `AgentPool` instead of through the CLI flags. ## `list --resources` (footprint) @@ -106,12 +201,7 @@ With **`--resources`**, `list` adds: from `openrtc.resources` (Linux: current VmRSS; macOS: peak `ru_maxrss`, not live RSS—see `resident_set.description` in `--json` output). - **Savings estimate** — a transparent estimate of the memory saved by one - shared worker versus one worker per registered agent. The estimate is based on - the current shared-worker baseline and is meant as an explanatory comparison, - not an orchestrator-level billing metric. - -Use this for **rough** local comparisons (single worker vs many images). For -production, rely on host or container metrics. + shared worker versus one worker per registered agent. ```bash openrtc list --agents-dir ./examples/agents --resources @@ -122,23 +212,20 @@ openrtc list --agents-dir ./examples/agents --resources --json - `--agents-dir` is required for every command. - `list` returns a non-zero exit code when no discoverable agents are found. -- `start` and `dev` both discover agents before handing off to the underlying - LiveKit worker runtime. -- The live dashboard and `--metrics-json-file` use runtime snapshots from the - running shared worker, unlike `list --resources`, which reports only on the +- Worker commands discover agents before handing off to the LiveKit CLI. +- The live dashboard, `--metrics-json-file`, and `--metrics-jsonl` reflect the + **running** shared worker, unlike `list --resources`, which reflects the short-lived CLI discovery process. ## Prove the shared-worker value locally -One practical workflow is: - 1. Discover your agents: ```bash openrtc list --agents-dir ./examples/agents --resources ``` -2. Start one shared worker with the dashboard enabled: +2. Start one shared worker with the dashboard and/or metrics output: ```bash openrtc dev \ @@ -147,14 +234,18 @@ One practical workflow is: --metrics-json-file ./runtime.json ``` -3. Watch the dashboard for: - - **Worker RSS** — current shared-worker memory - - **Active sessions** — how much load the single worker is handling - - **Estimated saved** — the gap between one shared worker and the “one worker - per agent” baseline - - **Per-agent sessions** — which agents are actively consuming capacity + Or enable JSONL for a sidecar TUI: + + ```bash + openrtc dev \ + --agents-dir ./examples/agents \ + --metrics-jsonl ./openrtc-metrics.jsonl + ``` + +3. Watch the dashboard (or `openrtc tui --watch ./openrtc-metrics.jsonl`) for + worker RSS, active sessions, routing, and errors. -4. Use `runtime.json` for automation, shell scripts, or container-side scraping. +4. Use `runtime.json` or the JSONL stream for automation or scraping. -For production capacity planning, compare these OpenRTC runtime snapshots with -host or container telemetry from your deployment platform. +For production capacity planning, compare these snapshots with host or container +telemetry from your deployment platform. diff --git a/docs/getting-started.md b/docs/getting-started.md index 5762af0..b07c8ab 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -14,15 +14,21 @@ pip install openrtc The base package includes the LiveKit Silero and turn-detector plugins used by OpenRTC's shared prewarm path. -Install the **Typer/Rich CLI** (`openrtc list`, `openrtc start`, `openrtc dev`) -with: +Install the **Typer/Rich CLI** (`openrtc list`, `openrtc start`, `openrtc dev`, +`openrtc console`, …) with: ```bash pip install 'openrtc[cli]' ``` -See [CLI](./cli) for output modes (`--plain`, `--json`, `--resources`) and -optional-dependency behavior. +Install the optional **Textual sidecar** for `openrtc tui --watch` with: + +```bash +pip install 'openrtc[cli,tui]' +``` + +See [CLI](./cli) for subcommands, output modes (`--plain`, `--json`, `--resources`), +the JSONL metrics stream (`--metrics-jsonl`), and optional-dependency behavior. If you are contributing locally, install the package in editable mode: @@ -31,7 +37,19 @@ python -m pip install -e . ``` Contributor environments typically use `uv sync --group dev`, which includes -Typer and Rich so the CLI runs without passing `--extra cli`. +Typer, Rich, and Textual so `openrtc` and `openrtc tui` run without extra flags. + +## CLI quick path + +With `LIVEKIT_URL`, `LIVEKIT_API_KEY`, and `LIVEKIT_API_SECRET` set, the minimal +worker invocation is: + +```bash +openrtc dev --agents-dir ./agents +``` + +Use `openrtc start` for production-style runs. See [CLI](./cli) for `console`, +`connect`, `download-files`, metrics files, and the sidecar TUI. ## Quick start diff --git a/docs/index.md b/docs/index.md index 18c7949..1d95ae3 100644 --- a/docs/index.md +++ b/docs/index.md @@ -18,8 +18,12 @@ The current package is intentionally small and focused: - select an agent using room or job metadata - share runtime dependencies across sessions in one worker process - start a LiveKit worker using the registered pool -- use the optional CLI (`pip install 'openrtc[cli]'`) for discovery, stable - `--json` / `--plain` output, and local `--resources` footprint hints +- use the optional CLI (`pip install 'openrtc[cli]'`) for discovery, worker + subcommands aligned with LiveKit (`dev`, `start`, `console`, `connect`, + `download-files`), stable `--json` / `--plain` output, and local `--resources` + footprint hints +- tail live metrics in a separate terminal with `openrtc tui --watch` after + enabling `--metrics-jsonl` on the worker (`pip install 'openrtc[cli,tui]'`) ## Read the docs From 2bd66a15eb5df145f641d55de2b9417d161ddfd0 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 22 Mar 2026 03:23:35 +0000 Subject: [PATCH 09/18] docs(vitepress): brand theme, home hero, and public assets Add a custom theme extending the default with OpenRTC cyan/navy tokens, DM Sans + JetBrains Mono, glassy nav, hero gradient title, and layout tweaks for the landscape banner. Switch nav logo to logo.png, copy brand PNGs into docs/public, and rebuild the index as a home layout with features. Ignore node_modules for local docs builds. Co-authored-by: Mahimai Raja J --- .gitignore | 3 + docs/.vitepress/config.ts | 13 ++- docs/.vitepress/theme/custom.css | 171 +++++++++++++++++++++++++++++++ docs/.vitepress/theme/index.ts | 7 ++ docs/index.md | 55 +++++----- docs/public/banner.png | Bin 0 -> 221793 bytes docs/public/logo.png | Bin 0 -> 182666 bytes 7 files changed, 222 insertions(+), 27 deletions(-) create mode 100644 docs/.vitepress/theme/custom.css create mode 100644 docs/.vitepress/theme/index.ts create mode 100644 docs/public/banner.png create mode 100644 docs/public/logo.png diff --git a/.gitignore b/.gitignore index 928ef42..623673c 100644 --- a/.gitignore +++ b/.gitignore @@ -164,6 +164,9 @@ venv.bak/ # Rope project settings .ropeproject +# Node (VitePress docs) +node_modules/ + # mkdocs documentation /site diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index be7f7ba..0d902ce 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -6,8 +6,19 @@ export default defineConfig({ base: '/openrtc-python/', cleanUrls: true, lastUpdated: true, + head: [ + ['link', { rel: 'preconnect', href: 'https://fonts.googleapis.com' }], + [ + 'link', + { + rel: 'preconnect', + href: 'https://fonts.gstatic.com', + crossorigin: '', + }, + ], + ], themeConfig: { - logo: '/logo.svg', + logo: '/logo.png', nav: [ { text: 'Guide', link: '/getting-started' }, { text: 'Concepts', link: '/concepts/architecture' }, diff --git a/docs/.vitepress/theme/custom.css b/docs/.vitepress/theme/custom.css new file mode 100644 index 0000000..1efb742 --- /dev/null +++ b/docs/.vitepress/theme/custom.css @@ -0,0 +1,171 @@ +/** + * OpenRTC docs theme — aligned with brand assets (cyan / deep blue, modern sans). + */ + +@import url('https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,400..700;1,9..40,500..700&family=JetBrains+Mono:wght@400;500&display=swap'); + +:root { + --ort-font-sans: 'DM Sans', ui-sans-serif, system-ui, sans-serif, + 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; + --ort-font-mono: 'JetBrains Mono', ui-monospace, 'Menlo', 'Monaco', 'Consolas', + monospace; + + /* Light: cool neutrals + readable cyan accents */ + --vp-c-brand-1: #006f94; + --vp-c-brand-2: #0088b8; + --vp-c-brand-3: #00a3d9; + --vp-c-brand-soft: rgba(0, 163, 217, 0.14); + + --vp-c-bg: #f5fafc; + --vp-c-bg-alt: #e8f3f8; + --vp-c-bg-elv: #ffffff; + --vp-c-bg-soft: #e2eef5; + + --vp-c-divider: #d4e4ed; + --vp-c-gutter: #cfe0ea; + + --vp-font-family-base: var(--ort-font-sans); + --vp-font-family-mono: var(--ort-font-mono); + + --vp-home-hero-image-background-image: radial-gradient( + circle at 30% 30%, + rgba(0, 196, 255, 0.35) 0%, + rgba(0, 120, 180, 0.12) 45%, + transparent 72% + ); + + --vp-nav-logo-height: 34px; +} + +.dark { + /* Dark: deep navy canvas, electric cyan accents (banner / logo) */ + --vp-c-brand-1: #5ae4ff; + --vp-c-brand-2: #24d4ff; + --vp-c-brand-3: #00b8e6; + --vp-c-brand-soft: rgba(0, 220, 255, 0.14); + + --vp-c-bg: #070b12; + --vp-c-bg-alt: #0c121f; + --vp-c-bg-elv: #111a2c; + --vp-c-bg-soft: #152033; + + --vp-c-border: #2a3a4f; + --vp-c-divider: #1c2838; + --vp-c-gutter: #0a0e16; + + --vp-c-text-1: #e8f4f8; + --vp-c-text-2: #9db4c4; + --vp-c-text-3: #6b8294; + + --vp-home-hero-image-background-image: radial-gradient( + circle at 28% 28%, + rgba(0, 220, 255, 0.45) 0%, + rgba(0, 100, 160, 0.2) 42%, + transparent 70% + ); + + --vp-code-block-bg: #0c121f; + --vp-code-bg: rgba(0, 220, 255, 0.08); +} + +/* Home: subtle ambient glow behind hero */ +.VPHome { + background: radial-gradient( + ellipse 120% 70% at 50% -15%, + rgba(0, 180, 230, 0.09), + transparent 52% + ); +} + +.dark .VPHome { + background: radial-gradient( + ellipse 100% 55% at 50% 0%, + rgba(0, 200, 255, 0.14), + transparent 58% + ); +} + +/* Echo logo typography: italic, tight tracking on product name */ +.VPHero .heading .name { + font-style: italic; + letter-spacing: -0.03em; +} + +/* Gradient fill on hero title (clip) */ +.VPHero .heading .name.clip { + background: linear-gradient(118deg, #00c6ff 0%, #0090c9 42%, #005a7a 100%); + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent !important; + color: transparent !important; +} + +.dark .VPHero .heading .name.clip { + background: linear-gradient(118deg, #8aebff 0%, #3bdcff 38%, #00a8d4 100%); + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent !important; + color: transparent !important; +} + +/* Second line stays solid for readability */ +.VPHero .heading .text { + color: var(--vp-c-text-1); +} + +/* Landscape banner: use more horizontal room on large screens */ +@media (min-width: 960px) { + .VPHome .VPHero.has-image .image-container { + width: 100%; + max-width: 440px; + min-height: 260px; + height: auto; + } + + .VPHome .VPHero.has-image .image-src { + position: relative; + top: auto; + left: auto; + transform: none; + margin: 0 auto; + display: block; + max-width: 100%; + max-height: min(280px, 40vh); + width: auto; + height: auto; + object-fit: contain; + } + + .VPHome .VPHero.has-image .image-bg { + width: 280px; + height: 280px; + } +} + +/* Nav logo: crisp PNG scaling */ +.VPNavBarTitle img { + object-fit: contain; +} + +/* Top bar: light separation without heavy chrome */ +.VPNav { + border-bottom: 1px solid var(--vp-c-divider); + background-color: color-mix(in srgb, var(--vp-c-bg) 88%, transparent); + backdrop-filter: blur(10px); +} + +@supports not (backdrop-filter: blur(10px)) { + .VPNav { + background-color: var(--vp-c-bg); + } +} + +/* Sidebar: slight depth */ +.VPSidebar { + background-color: var(--vp-c-bg-alt); +} + +/* Doc links: clearer hover */ +.vp-doc a:hover { + text-decoration-thickness: 2px; +} diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts new file mode 100644 index 0000000..370438e --- /dev/null +++ b/docs/.vitepress/theme/index.ts @@ -0,0 +1,7 @@ +import type { Theme } from 'vitepress' +import DefaultTheme from 'vitepress/theme' +import './custom.css' + +export default { + extends: DefaultTheme, +} satisfies Theme diff --git a/docs/index.md b/docs/index.md index 1d95ae3..772fd2f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,29 +1,32 @@ -# OpenRTC - -OpenRTC is a Python package for running multiple LiveKit voice agents in a -single worker process with shared prewarmed runtime dependencies. - -## Why OpenRTC? - -- **Multi-agent routing** from a single worker process. -- **Shared prewarm** for VAD and turn detection models. -- **Explicit registration** through a small programmatic API. -- **LiveKit-native runtime** built on `livekit-agents`. - -## What you can do today - -The current package is intentionally small and focused: - -- register one or more LiveKit `Agent` subclasses with `AgentPool` -- select an agent using room or job metadata -- share runtime dependencies across sessions in one worker process -- start a LiveKit worker using the registered pool -- use the optional CLI (`pip install 'openrtc[cli]'`) for discovery, worker - subcommands aligned with LiveKit (`dev`, `start`, `console`, `connect`, - `download-files`), stable `--json` / `--plain` output, and local `--resources` - footprint hints -- tail live metrics in a separate terminal with `openrtc tui --watch` after - enabling `--metrics-jsonl` on the worker (`pip install 'openrtc[cli,tui]'`) +--- +layout: home +outline: false + +hero: + name: OpenRTC + text: Shared worker voice agents + tagline: Register multiple LiveKit agents in one process, route by metadata, and prewarm models once. + image: + src: /banner.png + alt: OpenRTC banner + actions: + - theme: brand + text: Get started + link: /getting-started + - theme: alt + text: CLI reference + link: /cli + +features: + - title: Multi-agent routing + details: Dispatch the right Agent implementation from a single worker using room or job metadata. + - title: Shared prewarm + details: Load VAD, turn detection, and other heavy dependencies once for every session in the pool. + - title: LiveKit-native runtime + details: Built on livekit-agents with familiar dev, start, console, and connect-style workflows. + - title: CLI and observability + details: Optional openrtc CLI with JSON output, resource hints, JSONL metrics, and a Textual sidecar TUI. +--- ## Read the docs diff --git a/docs/public/banner.png b/docs/public/banner.png new file mode 100644 index 0000000000000000000000000000000000000000..e102acd89a85277d742fd883ad8057ecf42a942d GIT binary patch literal 221793 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­(U>B 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%0A)*Zqm>As!=J4FLr$ssXBO9w25Tk9^9s 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 a$El5^k9mkeO5JWYE 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 !v*5e>>XOBY8;{F#0nT#z(I7mB8Ew!+P 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%0Ak%$_5S13jn5!z?K@#;KqCVmaah)nr9BqX6 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

(*z0M#wA( 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

$lW( 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%0AWWjooZ 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 B3KjqW literal 0 HcmV?d00001 From 4d42c396e7ec610fdeef5f25f14f76c10e347578 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 22 Mar 2026 03:26:13 +0000 Subject: [PATCH 10/18] docs(readme): rewrite for utility-package tone and structure Co-authored-by: Mahimai Raja J --- README.md | 254 +++++++++++++++--------------------------------------- 1 file changed, 71 insertions(+), 183 deletions(-) diff --git a/README.md b/README.md index 1bf3216..613b9bc 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,12 @@
-

+# openrtc-python + +Run N LiveKit voice agents in one worker. Pay the model-load cost once. + +*PyPI package name: [`openrtc`](https://pypi.org/project/openrtc/).* +

-OpenRTC is designed for the common case where you want to run several different -voice agents on a small VPS without paying the memory cost of one full -LiveKit worker per agent. - -
-
Table of Contents
    -
  1. Why OpenRTC exists
  2. -
  3. What OpenRTC wraps
  4. -
  5. Memory comparison
  6. +
  7. The problem
  8. +
  9. What openrtc does
  10. Installation
  11. -
  12. Quick start: register agents directly
  13. -
  14. Quick start: discover agent files
  15. -
  16. Routing behavior
  17. +
  18. Quick start: explicit registration with add()
  19. +
  20. Quick start: one Python file per agent with discover()
  21. +
  22. Memory: before and after
  23. +
  24. Routing
  25. Greetings and session options
  26. -
  27. Provider model strings
  28. -
  29. CLI usage
  30. +
  31. Provider configuration
  32. +
  33. CLI and TUI
  34. Public API at a glance
  35. Project structure
  36. Contributing
  37. +
  38. License

-## Why OpenRTC exists - -A standard `livekit-agents` worker process loads shared runtime assets such as -Python, Silero VAD, and turn-detection models. If you run ten agents as ten -separate workers, you pay that base memory cost ten times. - -OpenRTC keeps your agent classes completely standard and only centralizes the -worker boilerplate: - -- shared prewarm for VAD and turn detection -- metadata-based dispatch to the correct agent -- per-agent `AgentSession` construction inside one worker - -Your agent code still subclasses `livekit.agents.Agent` directly. If you stop -using OpenRTC later, your agent classes still work as normal LiveKit agents. - -## What OpenRTC wraps +## The problem -OpenRTC intentionally wraps only the worker orchestration layer: +You already ship three voice agents with `livekit-agents`. Each agent is its own worker on the same VPS. Every worker process loads the same shared stack: Python runtime, Silero VAD, and the turn-detection model. You are not loading three different models. You are loading the same stack three times because the process boundary forces it. On a 1–2 GB instance, that shows up as duplicate resident set for every idle worker. You pay RAM for copies you do not need. -1. `AgentServer()` setup and prewarm -2. a universal `@server.rtc_session()` entrypoint -3. per-call `AgentSession()` creation with the right providers +## What openrtc does -OpenRTC does **not** replace: - -- `livekit.agents.Agent` -- `@function_tool` -- `RunContext` -- `on_enter`, `on_exit`, `llm_node`, `stt_node`, `tts_node` -- standard LiveKit deployment patterns - -## Memory comparison - -| Deployment model | Shared runtime loads | Approximate memory shape | -| --- | --- | --- | -| 10 separate LiveKit workers | 10x | ~500 MB × 10 | -| 1 OpenRTC pool with 10 agents | 1x shared + per-call session cost | ~500 MB shared + active-call overhead | - -The exact numbers depend on your providers, concurrency, and environment, but -OpenRTC is built to reduce duplicate worker overhead. +`openrtc` gives you one `AgentPool` in one worker: prewarm runs once, each incoming call still gets its own `AgentSession`, and you register multiple `Agent` subclasses on the pool so dispatch can pick one per session from metadata or fallbacks. This package does not replace your agent code. It does not sit between you and `livekit.agents.Agent`, `@function_tool`, `RunContext`, `on_enter`, `on_exit`, `llm_node`, `stt_node`, or `tts_node`. You keep your subclasses and tools as they are. You change how many workers you run, not how you write an agent. ## Installation -Install OpenRTC from PyPI: - ```bash pip install openrtc ``` -The base package pulls in `livekit-agents[openai,silero,turn-detector]`, so the -runtime plugins required by shared prewarm are installed without extra flags. - -Install the Typer/Rich CLI (`openrtc list`, `openrtc start`, `openrtc dev`, …) -with: +The base install pulls in `livekit-agents[openai,silero,turn-detector]` so shared prewarm has the plugins it expects. ```bash pip install 'openrtc[cli]' ``` -Install the optional **Textual sidecar TUI** (`openrtc tui --watch`) with: +Optional Textual sidecar for live metrics: ```bash pip install 'openrtc[cli,tui]' ``` -If you are developing locally, the repository uses `uv` for environment and -command management. - -### Required environment variables - -OpenRTC uses the same environment variables as a standard LiveKit worker: +Set the same variables you use for any LiveKit worker: ```bash -LIVEKIT_URL=ws://localhost:7880 -LIVEKIT_API_KEY=devkey -LIVEKIT_API_SECRET=secret +export LIVEKIT_URL=ws://localhost:7880 +export LIVEKIT_API_KEY=devkey +export LIVEKIT_API_SECRET=secret ``` -For provider-native OpenAI plugin objects, set: +For OpenAI-backed plugins, set `OPENAI_API_KEY` as you already do. -```bash -OPENAI_API_KEY=... -``` - -## Quick start: register agents directly with `add()` +## Quick start: explicit registration with `add()` -Use `AgentPool.add(...)` when you want the most explicit setup. +Use this when you want every agent registered in one place with explicit names and providers. ```python from livekit.agents import Agent @@ -172,15 +122,11 @@ pool.add( pool.run() ``` -## Quick start: discover agent files with `@agent_config(...)` +## Quick start: one Python file per agent with `discover()` -Use discovery when you want one agent module per file. OpenRTC will import each -module, find a local `Agent` subclass, and optionally read overrides from the -`@agent_config(...)` decorator. +Use this when you prefer one module per agent and optional `@agent_config(...)` on each class. -Discovered agents are safe to run under `livekit dev`, including spawn-based -worker runtimes such as macOS. For direct `add()` registration, define agent -classes at module scope so worker processes can reload them. +Create a directory (for example `agents/`) and add one `.py` file per agent. Then: ```python from pathlib import Path @@ -197,7 +143,7 @@ pool.discover(Path("./agents")) pool.run() ``` -Example agent file: +Example file `agents/restaurant.py`: ```python from livekit.agents import Agent @@ -210,20 +156,24 @@ class RestaurantAgent(Agent): super().__init__(instructions="You help callers make restaurant bookings.") ``` -### Discovery defaults +If a module has no `@agent_config`, the agent name defaults to the filename stem. STT, LLM, TTS, and greeting fall back to the pool defaults. -A discovered module does not need to provide any OpenRTC metadata. If the agent -class has no `@agent_config(...)` decorator: +Discovered agents work with `livekit dev` and spawn-based workers on macOS. For `add()`, define agent classes at module scope so worker reload can import them. -- the agent name defaults to the Python filename stem -- STT/LLM/TTS/greeting fall back to `AgentPool(...)` defaults +## Memory: before and after -That keeps discovery straightforward while still allowing per-agent overrides -when needed. +Assume an illustrative **~400 MB** idle baseline per worker for the shared stack (VAD, turn detector, and similar). Your measured RSS will differ by provider, model, and OS. + +| | Before openrtc | After openrtc | +| --- | --- | --- | +| Three workers, same stack | about **3 × 400 MB ≈ 1.2 GB** idle baseline (three loads) | — | +| One worker, three registered agents | — | about **one × 400 MB** idle baseline (one load) plus per-session overhead | -## Routing behavior +Exact numbers depend on your providers, concurrency, and call patterns. The win is not loading that stack once per agent worker. -For each incoming room, `AgentPool` resolves the agent in this order: +## Routing + +One process hosts several agent classes, so each session must resolve to a single registered name. `AgentPool` resolves the agent in this order: 1. `ctx.job.metadata["agent"]` 2. `ctx.job.metadata["demo"]` @@ -232,16 +182,11 @@ For each incoming room, `AgentPool` resolves the agent in this order: 5. room name prefix match, such as `restaurant-call-123` 6. the first registered agent -This lets one worker process host several agents while staying compatible with -standard LiveKit job and room metadata. - -If metadata references an unknown registered name, OpenRTC raises a `ValueError` -instead of silently falling back. +If metadata names an agent that is not registered, you get a `ValueError` instead of a silent fallback. ## Greetings and session options -OpenRTC can play a greeting after `ctx.connect()` and pass extra options into -`AgentSession(...)`. +You can pass a greeting and extra `AgentSession` options per registration. ```python pool.add( @@ -254,55 +199,25 @@ pool.add( ) ``` -Direct keyword arguments take precedence over the same keys inside -`session_kwargs`. +Direct keyword arguments win over the same keys inside `session_kwargs`. -By default, OpenRTC builds explicit `turn_handling` for each session using the -multilingual turn detector with VAD-based interruption. That keeps the shared -turn detector available without implicitly enabling LiveKit adaptive -interruption. To opt into adaptive interruption explicitly, pass -`session_kwargs={"turn_handling": {"interruption": {"mode": "adaptive"}}}`. +By default, OpenRTC sets explicit `turn_handling` with the multilingual turn detector and VAD-based interruption. To opt into adaptive interruption, pass `session_kwargs={"turn_handling": {"interruption": {"mode": "adaptive"}}}`. ## Provider configuration -OpenRTC now passes `stt`, `llm`, and `tts` through to `livekit-agents` -unchanged. - -For self-hosted and provider-native setups, pass instantiated provider objects: +Pass instantiated provider objects through to `livekit-agents` unchanged, for example: - `openai.STT(model="gpt-4o-mini-transcribe")` - `openai.responses.LLM(model="gpt-4.1-mini")` - `openai.TTS(model="gpt-4o-mini-tts")` -If you pass raw strings such as `openai/gpt-4.1-mini`, OpenRTC leaves them -unchanged and `livekit-agents` will interpret them according to the current -LiveKit runtime, which may mean inference-backed behavior on compatible cloud -deployments. +If you pass strings such as `openai/gpt-4.1-mini`, OpenRTC leaves them as-is and the LiveKit runtime interprets them for your deployment. -## CLI usage +## CLI and TUI -OpenRTC includes a CLI for discovery-based workflows. Subcommands mirror the -LiveKit Agents CLI (`dev`, `start`, `console`, `connect`, `download-files`, as -in `python agent.py `), plus `list` and `tui`. +Install `openrtc[cli]` to get `openrtc` on your PATH. Subcommands follow the LiveKit Agents CLI shape (`dev`, `start`, `console`, `connect`, `download-files`), plus `list` and `tui`. -**Typical path:** set `LIVEKIT_URL`, `LIVEKIT_API_KEY`, and `LIVEKIT_API_SECRET`, -then run the worker with only `--agents-dir` (plus any `--default-*` strings -your agents need). - -```bash -export LIVEKIT_URL=ws://localhost:7880 -export LIVEKIT_API_KEY=devkey -export LIVEKIT_API_SECRET=secret - -openrtc dev --agents-dir ./agents -# or -openrtc start --agents-dir ./agents -``` - -Defaults are conservative (no dashboard, 1s refresh where applicable). Tuning -flags are grouped under **Advanced** in each command’s `--help`. - -### List discovered agents +**List what discovery would register** (defaults are string passthroughs for `livekit-agents`, not constructed provider objects): ```bash openrtc list \ @@ -312,58 +227,34 @@ openrtc list \ --default-tts openai/gpt-4o-mini-tts ``` -These CLI defaults are raw passthrough strings for `livekit-agents`, not -provider-object construction. - -Stable output for scripts and CI: - -- `--plain` — line-oriented text without ANSI or table borders (similar to the - legacy `print` format). Use `--resources` for source-size and RSS lines. -- `--json` — machine-readable JSON with a `schema_version` field; combine with - `--resources` for `resource_summary` (footprint + resident-set metadata). - The `resident_set` object includes a `description`: on **Linux** it reflects - current **VmRSS**; on **macOS** it is **peak** `ru_maxrss` (bytes), not - instantaneous live RSS—compare runs only on the same OS. - -### Run workers (production and development) +**Run a production worker** (after exporting `LIVEKIT_*`): ```bash openrtc start --agents-dir ./agents -openrtc dev --agents-dir ./agents ``` -Optional runtime visibility: +**Run a development worker**: -- **`--dashboard`** — Rich summary (worker RSS, sessions, routing, savings - estimate). Off by default. -- **`--metrics-json-file ./runtime.json`** — Overwrites a JSON file each tick with - the latest snapshot (automation / CI). See **Advanced** in `--help`. -- **`--metrics-jsonl ./openrtc-metrics.jsonl`** — Append **JSON Lines** (truncates - when the worker starts): versioned `snapshot` rows plus optional `event` - rows for session lifecycle. Use with a second terminal: +```bash +openrtc dev --agents-dir ./agents +``` - ```bash - pip install 'openrtc[cli,tui]' - openrtc tui --watch ./openrtc-metrics.jsonl - ``` +Optional visibility: `--dashboard` prints a Rich summary in the terminal. `--metrics-json-file ./runtime.json` overwrites a JSON snapshot on each tick. Use that for scripts, dashboards, or CI. For JSON Lines plus a separate terminal UI, use `--metrics-jsonl ./metrics.jsonl` with `openrtc tui --watch ./metrics.jsonl` after `pip install 'openrtc[cli,tui]'`. -Other worker subcommands match LiveKit: `openrtc console`, `openrtc connect ---room …`, and `openrtc download-files` (minimal options: agents dir + connection -only). See [docs/cli.md](docs/cli.md) for full detail. +Stable machine output: `openrtc list --json` and `--plain`. Combine `--resources` when you want footprint hints. OpenRTC-only flags are stripped before the handoff to LiveKit’s CLI parser. -Worker commands discover agents first, then delegate to the LiveKit CLI; -OpenRTC-only flags are not forwarded to LiveKit’s parser. +Full flag lists live in [docs/cli.md](docs/cli.md). ## Public API at a glance -OpenRTC currently exposes: +Everything openrtc exposes publicly is listed here. Anything else is internal and not treated as stable. - `AgentPool` - `AgentConfig` - `AgentDiscoveryConfig` - `agent_config(...)` -On `AgentPool`, the primary public methods and properties are: +On `AgentPool`: - `add(...)` - `discover(...)` @@ -372,8 +263,7 @@ On `AgentPool`, the primary public methods and properties are: - `remove(name)` - `run()` - `runtime_snapshot()` -- `drain_metrics_stream_events()` — drain queued session lifecycle events for JSONL - export (used by the CLI; rarely needed in application code) +- `drain_metrics_stream_events()` — for JSONL export paths (mainly CLI; rare in app code) - `server` ## Project structure @@ -388,16 +278,14 @@ src/openrtc/ └── pool.py ``` -- `pool.py` contains the core `AgentPool` implementation and discovery helpers -- `cli.py` / `cli_app.py` provide the Typer/Rich CLI (`openrtc[cli]`) -- `metrics_stream.py` defines the JSONL metrics stream format -- `tui_app.py` implements the optional Textual sidecar (`openrtc[tui]`) -- `__init__.py` exposes the public package API +- `pool.py` — `AgentPool`, discovery, routing +- `cli.py` / `cli_app.py` — Typer/Rich CLI (`openrtc[cli]`) +- `metrics_stream.py` — JSONL metrics schema +- `tui_app.py` — optional Textual sidecar (`openrtc[tui]`) ## Contributing -Contributions are welcome. Please read [CONTRIBUTING.md](CONTRIBUTING.md) -before opening a pull request. +See [CONTRIBUTING.md](CONTRIBUTING.md). ## License From 8d66c7b4acfe5b61e106f98608ec532ade018231 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 22 Mar 2026 03:31:21 +0000 Subject: [PATCH 11/18] test(cli): make download-files option assertion locale-safe Assert exit code 2 and the unknown flag name only; Click's default English phrase is gettext-translated when locale catalogs differ. Co-authored-by: Mahimai Raja J --- tests/test_cli.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/test_cli.py b/tests/test_cli.py index 2490a1b..63f60b1 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -245,9 +245,10 @@ def test_download_files_has_minimal_options_no_provider_defaults( "deepgram/x", ], ) - assert result.exit_code != 0 + assert result.exit_code == 2 out = (result.stdout or "") + (result.stderr or "") - assert "No such option" in out and "default-stt" in out + # Option name is stable; the "No such option" prefix is gettext-translated on non-English locales. + assert "default-stt" in out def test_list_exits_cleanly_when_agents_dir_does_not_exist( From 87e433a7627f74e439998c03817b0d4130ed213b Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 22 Mar 2026 03:35:31 +0000 Subject: [PATCH 12/18] test(cli): force wide COLUMNS for Rich error output in download-files test Click's CliRunner only overrides env keys passed into invoke; a narrow COLUMNS from CI caused Rich to wrap the unknown flag so 'default-stt' was not a contiguous substring. Co-authored-by: Mahimai Raja J --- tests/test_cli.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/test_cli.py b/tests/test_cli.py index 63f60b1..5a5f93d 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -244,10 +244,13 @@ def test_download_files_has_minimal_options_no_provider_defaults( "--default-stt", "deepgram/x", ], + # Rich wraps error text to COLUMNS from the environment; CI often sets a + # narrow width, which splits the flag across ANSI segments so the literal + # substring "default-stt" disappears. + env={"COLUMNS": "160", "LINES": "50"}, ) assert result.exit_code == 2 out = (result.stdout or "") + (result.stderr or "") - # Option name is stable; the "No such option" prefix is gettext-translated on non-English locales. assert "default-stt" in out From cae8db8be50c8c1a0e2485481e53e82cd5faf980 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 22 Mar 2026 03:40:35 +0000 Subject: [PATCH 13/18] test(cli): normalize Rich/ANSI output before download-files flag assertion Co-authored-by: Mahimai Raja J --- tests/test_cli.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/tests/test_cli.py b/tests/test_cli.py index 5a5f93d..8df5927 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -4,6 +4,7 @@ import importlib import json import logging +import re import sys from dataclasses import dataclass from pathlib import Path @@ -20,6 +21,14 @@ SavingsEstimate, ) +# Rich/Click may inject ANSI and soft-wrap error text; normalize before substring checks. +_ANSI_ESCAPE_RE = re.compile(r"\x1b\[[0-?]*[ -/]*[@-~]") + + +def _normalize_cli_output_for_assert(text: str) -> str: + plain = _ANSI_ESCAPE_RE.sub("", text) + return plain.replace("\n", "").replace("\r", "") + @dataclass class StubConfig: @@ -244,14 +253,11 @@ def test_download_files_has_minimal_options_no_provider_defaults( "--default-stt", "deepgram/x", ], - # Rich wraps error text to COLUMNS from the environment; CI often sets a - # narrow width, which splits the flag across ANSI segments so the literal - # substring "default-stt" disappears. - env={"COLUMNS": "160", "LINES": "50"}, ) assert result.exit_code == 2 out = (result.stdout or "") + (result.stderr or "") - assert "default-stt" in out + normalized = _normalize_cli_output_for_assert(out) + assert re.search(r"default[-_]stt", normalized), normalized[:800] def test_list_exits_cleanly_when_agents_dir_does_not_exist( From 449389b538baf991e5de80a3ac8b98fdad9082be Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 22 Mar 2026 04:06:28 +0000 Subject: [PATCH 14/18] fix: address review items for extras, CLI strip, metrics types, and tests - Include rich+typer in the tui extra so `openrtc tui` works without [cli]. - Harden TUI status line when wall_time_unix is missing/invalid; type _fh as TextIO. - Strip OpenRTC value flags by always consuming the following argv token. - Deduplicate RuntimeReporter scheduling loop; document JsonlMetricsSink truncation. - Add MetricsStreamEvent TypedDict and use it for drain_stream_events/drain_metrics. - Simplify deque unpickle for stream events; fix @import font notation for stylelint. - Share minimal_pool_runtime_snapshot fixture; poll JSONL in reporter tests. - Extend argv-strip test for values that look like flags. Co-authored-by: Mahimai Raja J --- docs/.vitepress/theme/custom.css | 2 +- pyproject.toml | 5 ++ src/openrtc/cli_app.py | 71 ++++++++--------- src/openrtc/metrics_stream.py | 6 +- src/openrtc/pool.py | 8 +- src/openrtc/resources.py | 23 ++++-- src/openrtc/tui_app.py | 12 ++- tests/conftest.py | 37 +++++++++ tests/test_cli.py | 6 +- tests/test_metrics_stream.py | 130 +++++++++++++++++-------------- tests/test_tui_app.py | 46 +++-------- 11 files changed, 200 insertions(+), 146 deletions(-) diff --git a/docs/.vitepress/theme/custom.css b/docs/.vitepress/theme/custom.css index 1efb742..3ceb214 100644 --- a/docs/.vitepress/theme/custom.css +++ b/docs/.vitepress/theme/custom.css @@ -2,7 +2,7 @@ * OpenRTC docs theme — aligned with brand assets (cyan / deep blue, modern sans). */ -@import url('https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,400..700;1,9..40,500..700&family=JetBrains+Mono:wght@400;500&display=swap'); +@import 'https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,400..700;1,9..40,500..700&family=JetBrains+Mono:wght@400;500&display=swap'; :root { --ort-font-sans: 'DM Sans', ui-sans-serif, system-ui, sans-serif, diff --git a/pyproject.toml b/pyproject.toml index 9b28c57..468c1be 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,6 +31,8 @@ cli = [ "typer>=0.12", ] tui = [ + "rich>=13", + "typer>=0.12", "textual>=0.47,<2", ] @@ -77,6 +79,9 @@ ignore = [ "W191", ] +[tool.ruff.lint.per-file-ignores] +"tests/conftest.py" = ["E402"] + [tool.mypy] python_version = "3.10" warn_return_any = true diff --git a/src/openrtc/cli_app.py b/src/openrtc/cli_app.py index b3c77b7..51f90ac 100644 --- a/src/openrtc/cli_app.py +++ b/src/openrtc/cli_app.py @@ -124,53 +124,44 @@ def _run(self) -> None: ) next_jsonl = now + self._jsonl_interval if self._jsonl_sink else float("inf") - if self._dashboard: - with Live( - self._build_dashboard_renderable(), - console=console, - refresh_per_second=max(int(round(1 / self._refresh_seconds)), 1), - transient=True, - ) as live: - while True: - now = time.monotonic() - wait_periodic = max(0.0, next_periodic - now) - wait_jsonl = ( - max(0.0, next_jsonl - now) - if self._jsonl_sink is not None - else float("inf") - ) - timeout = min(wait_periodic, wait_jsonl, 3600.0) - if self._stop_event.wait(timeout): - break - now = time.monotonic() - if self._needs_periodic_file_or_ui and now >= next_periodic: - live.update(self._build_dashboard_renderable()) - self._write_json_snapshot() - next_periodic += self._refresh_seconds - if self._jsonl_sink is not None and now >= next_jsonl: - self._emit_jsonl() - next_jsonl += self._jsonl_interval - live.update(self._build_dashboard_renderable()) - return - - while True: - now = time.monotonic() - wait_periodic = max(0.0, next_periodic - now) + def schedule_cycle(live: Live | None) -> bool: + """Wait until the next tick; run JSON/JSONL/dashboard work. Return False to exit.""" + nonlocal next_periodic, next_jsonl + n = time.monotonic() + wait_periodic = max(0.0, next_periodic - n) wait_jsonl = ( - max(0.0, next_jsonl - now) + max(0.0, next_jsonl - n) if self._jsonl_sink is not None else float("inf") ) timeout = min(wait_periodic, wait_jsonl, 3600.0) if self._stop_event.wait(timeout): - break - now = time.monotonic() - if self._needs_periodic_file_or_ui and now >= next_periodic: + return False + n = time.monotonic() + if self._needs_periodic_file_or_ui and n >= next_periodic: + if live is not None: + live.update(self._build_dashboard_renderable()) self._write_json_snapshot() next_periodic += self._refresh_seconds - if self._jsonl_sink is not None and now >= next_jsonl: + if self._jsonl_sink is not None and n >= next_jsonl: self._emit_jsonl() next_jsonl += self._jsonl_interval + return True + + if self._dashboard: + with Live( + self._build_dashboard_renderable(), + console=console, + refresh_per_second=max(int(round(1 / self._refresh_seconds)), 1), + transient=True, + ) as live: + while schedule_cycle(live): + pass + live.update(self._build_dashboard_renderable()) + return + + while schedule_cycle(None): + pass def _build_dashboard_renderable(self) -> Panel: snapshot = self._pool.runtime_snapshot() @@ -364,6 +355,10 @@ def _strip_openrtc_only_flags_for_livekit(argv_tail: list[str]) -> list[str]: that does not recognize OpenRTC options such as ``--agents-dir``. Those must be removed before the handoff while preserving any forwarded LiveKit flags (e.g. ``--reload``, ``--url``) when we add pass-through options later. + + For flags in ``_OPENRTC_ONLY_FLAGS_WITH_VALUE``, the **next** token is always + consumed as the value when present, even if it starts with ``--`` (e.g. a + path or provider string must not be mistaken for a following flag). """ out: list[str] = [] i = 0 @@ -388,7 +383,7 @@ def _strip_openrtc_only_flags_for_livekit(argv_tail: list[str]) -> list[str]: continue if arg in _OPENRTC_ONLY_FLAGS_WITH_VALUE: i += 1 - if i < len(argv_tail) and not argv_tail[i].startswith("--"): + if i < len(argv_tail): i += 1 continue out.append(arg) diff --git a/src/openrtc/metrics_stream.py b/src/openrtc/metrics_stream.py index 347ecfc..b8bd8a6 100644 --- a/src/openrtc/metrics_stream.py +++ b/src/openrtc/metrics_stream.py @@ -78,7 +78,11 @@ def __init__(self, path: Path) -> None: self._lock = Lock() def open(self) -> None: - """Create parent dirs, truncate file, open for append.""" + """Create parent dirs and open the JSONL file for writing. + + Uses ``self._path.open("w", ...)``, which **truncates** any existing file. + That is intentional: each worker run starts a fresh stream (see class doc). + """ self._path.parent.mkdir(parents=True, exist_ok=True) self._file = self._path.open("w", encoding="utf-8") diff --git a/src/openrtc/pool.py b/src/openrtc/pool.py index 794236f..6ba761b 100644 --- a/src/openrtc/pool.py +++ b/src/openrtc/pool.py @@ -18,7 +18,11 @@ from livekit.agents import Agent, AgentServer, AgentSession, JobContext, JobProcess, cli -from openrtc.resources import PoolRuntimeSnapshot, RuntimeMetricsStore +from openrtc.resources import ( + MetricsStreamEvent, + PoolRuntimeSnapshot, + RuntimeMetricsStore, +) logger = logging.getLogger("openrtc") @@ -270,7 +274,7 @@ def runtime_snapshot(self) -> PoolRuntimeSnapshot: """Return a live snapshot of worker metrics for dashboards and automation.""" return self._runtime_state.metrics.snapshot(registered_agents=len(self._agents)) - def drain_metrics_stream_events(self) -> list[dict[str, Any]]: + def drain_metrics_stream_events(self) -> list[MetricsStreamEvent]: """Drain pending session lifecycle events for JSONL sidecar export.""" return self._runtime_state.metrics.drain_stream_events() diff --git a/src/openrtc/resources.py b/src/openrtc/resources.py index 6fea476..ca41dd1 100644 --- a/src/openrtc/resources.py +++ b/src/openrtc/resources.py @@ -8,7 +8,7 @@ from dataclasses import dataclass, field from pathlib import Path from threading import Lock -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, TypedDict if TYPE_CHECKING: from openrtc.pool import AgentConfig @@ -18,6 +18,18 @@ _STREAM_EVENTS_MAXLEN = 256 +class MetricsStreamEvent(TypedDict, total=False): + """One drained session lifecycle row for JSONL export. + + Rows always include ``event`` and ``agent`` from the store; ``session_failed`` + rows may include ``error``. + """ + + event: str + agent: str + error: str + + @dataclass(frozen=True, slots=True) class AgentDiskFootprint: """On-disk size for a single agent module file.""" @@ -112,7 +124,7 @@ class RuntimeMetricsStore: last_error: str | None = None sessions_by_agent: dict[str, int] = field(default_factory=dict) _lock: Lock = field(default_factory=Lock, init=False, repr=False, compare=False) - _stream_events: deque[dict[str, Any]] = field( + _stream_events: deque[MetricsStreamEvent] = field( default_factory=lambda: deque(maxlen=_STREAM_EVENTS_MAXLEN), init=False, repr=False, @@ -143,10 +155,7 @@ def __setstate__(self, state: Mapping[str, object]) -> None: for key, value in dict(state["sessions_by_agent"]).items() } raw_events = state.get("_stream_events", []) - self._stream_events = deque( - list(raw_events), - maxlen=_STREAM_EVENTS_MAXLEN, - ) + self._stream_events = deque(raw_events, maxlen=_STREAM_EVENTS_MAXLEN) self._lock = Lock() def record_session_started(self, agent_name: str) -> None: @@ -188,7 +197,7 @@ def record_session_failure(self, agent_name: str, exc: BaseException) -> None: }, ) - def drain_stream_events(self) -> list[dict[str, Any]]: + def drain_stream_events(self) -> list[MetricsStreamEvent]: """Remove and return pending stream events for JSONL export (order preserved).""" with self._lock: out = list(self._stream_events) diff --git a/src/openrtc/tui_app.py b/src/openrtc/tui_app.py index b4841cf..47c9a18 100644 --- a/src/openrtc/tui_app.py +++ b/src/openrtc/tui_app.py @@ -3,7 +3,7 @@ from __future__ import annotations from pathlib import Path -from typing import Any +from typing import Any, TextIO from textual.app import App, ComposeResult from textual.widgets import Footer, Header, Static @@ -21,7 +21,7 @@ def __init__(self, watch_path: Path, *, from_start: bool = False) -> None: super().__init__() self._path = watch_path.resolve() self._from_start = from_start - self._fh: Any = None + self._fh: TextIO | None = None self._buf = "" self._latest: dict[str, Any] | None = None self._last_event: dict[str, Any] | None = None @@ -89,9 +89,15 @@ def _refresh_view(self) -> None: return seq = self._latest.get("seq") wall = self._latest.get("wall_time_unix") + wall_s = "n/a" + if wall is not None: + try: + wall_s = f"{float(wall):.3f}" + except (TypeError, ValueError): + wall_s = "n/a" status = self.query_one("#status", Static) status.update( - f"seq={seq} wall={float(wall):.3f} registered={payload.get('registered_agents')} " + f"seq={seq} wall={wall_s} registered={payload.get('registered_agents')} " f"active={payload.get('active_sessions')} " f"uptime={float(payload.get('uptime_seconds', 0)):.1f}s" ) diff --git a/tests/conftest.py b/tests/conftest.py index af55de9..ec02d51 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -78,3 +78,40 @@ def run_app(self, server: AgentServer) -> None: sys.modules["livekit"] = livekit_module sys.modules["livekit.agents"] = agents_module + + +import pytest + +from openrtc.resources import ( + PoolRuntimeSnapshot, + ProcessResidentSetInfo, + SavingsEstimate, +) + + +@pytest.fixture +def minimal_pool_runtime_snapshot() -> PoolRuntimeSnapshot: + """Small :class:`PoolRuntimeSnapshot` for metrics stream / TUI tests.""" + return PoolRuntimeSnapshot( + timestamp=1.0, + uptime_seconds=0.5, + registered_agents=1, + active_sessions=0, + total_sessions_started=0, + total_session_failures=0, + last_routed_agent=None, + last_error=None, + sessions_by_agent={}, + resident_set=ProcessResidentSetInfo( + bytes_value=1024, + metric="test", + description="test", + ), + savings_estimate=SavingsEstimate( + agent_count=1, + shared_worker_bytes=1024, + estimated_separate_workers_bytes=1024, + estimated_saved_bytes=0, + assumptions=(), + ), + ) diff --git a/tests/test_cli.py b/tests/test_cli.py index 8df5927..0d19bbb 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -16,6 +16,7 @@ from openrtc.cli import app, main from openrtc.resources import ( + MetricsStreamEvent, PoolRuntimeSnapshot, ProcessResidentSetInfo, SavingsEstimate, @@ -70,7 +71,7 @@ def discover(self, agents_dir: Path) -> list[StubConfig]: def run(self) -> None: self.run_called = True - def drain_metrics_stream_events(self) -> list[dict[str, Any]]: + def drain_metrics_stream_events(self) -> list[MetricsStreamEvent]: return [] def runtime_snapshot(self) -> PoolRuntimeSnapshot: @@ -309,6 +310,9 @@ def test_strip_openrtc_only_flags_for_livekit_removes_openrtc_options() -> None: "--reload" ] assert _strip_openrtc_only_flags_for_livekit([]) == [] + assert _strip_openrtc_only_flags_for_livekit( + ["--metrics-json-file", "--not-a-flag", "--reload"], + ) == ["--reload"] def test_cli_entrypoint_documents_optional_extra() -> None: diff --git a/tests/test_metrics_stream.py b/tests/test_metrics_stream.py index 2c93cf7..de38fd1 100644 --- a/tests/test_metrics_stream.py +++ b/tests/test_metrics_stream.py @@ -18,43 +18,40 @@ snapshot_envelope, ) from openrtc.resources import ( + MetricsStreamEvent, PoolRuntimeSnapshot, - ProcessResidentSetInfo, - SavingsEstimate, ) -def _minimal_snapshot() -> PoolRuntimeSnapshot: - return PoolRuntimeSnapshot( - timestamp=1.0, - uptime_seconds=0.5, - registered_agents=1, - active_sessions=0, - total_sessions_started=0, - total_session_failures=0, - last_routed_agent=None, - last_error=None, - sessions_by_agent={}, - resident_set=ProcessResidentSetInfo( - bytes_value=1024, - metric="test", - description="test", - ), - savings_estimate=SavingsEstimate( - agent_count=1, - shared_worker_bytes=1024, - estimated_separate_workers_bytes=1024, - estimated_saved_bytes=0, - assumptions=(), - ), +def _read_jsonl_lines(path: Path) -> list[str]: + if not path.exists(): + return [] + return [ln for ln in path.read_text(encoding="utf-8").split("\n") if ln.strip()] + + +def _wait_for_jsonl_lines( + path: Path, + *, + min_lines: int, + timeout: float = 5.0, + poll_interval: float = 0.02, +) -> list[str]: + deadline = time.monotonic() + timeout + while time.monotonic() < deadline: + lines = _read_jsonl_lines(path) + if len(lines) >= min_lines: + return lines + time.sleep(poll_interval) + raise AssertionError( + f"timed out after {timeout}s waiting for {min_lines} JSONL line(s) in {path!s}", ) class _StubPool: - def __init__(self) -> None: - self._snap = _minimal_snapshot() + def __init__(self, snapshot: PoolRuntimeSnapshot) -> None: + self._snap = snapshot - def drain_metrics_stream_events(self) -> list[dict[str, object]]: + def drain_metrics_stream_events(self) -> list[MetricsStreamEvent]: return [] def runtime_snapshot(self) -> PoolRuntimeSnapshot: @@ -92,11 +89,13 @@ def test_parse_metrics_jsonl_line_rejects_unknown_kind() -> None: assert parse_metrics_jsonl_line(bad) is None -def test_jsonl_metrics_sink_requires_open_before_write(tmp_path: Path) -> None: +def test_jsonl_metrics_sink_requires_open_before_write( + tmp_path: Path, + minimal_pool_runtime_snapshot: PoolRuntimeSnapshot, +) -> None: sink = JsonlMetricsSink(tmp_path / "unopened.jsonl") - snap = _minimal_snapshot() with pytest.raises(RuntimeError, match="open"): - sink.write_snapshot(snap) + sink.write_snapshot(minimal_pool_runtime_snapshot) with pytest.raises(RuntimeError, match="open"): sink.write_event({"event": "x"}) @@ -118,11 +117,14 @@ def test_parse_metrics_jsonl_line_accepts_event() -> None: assert rec["payload"]["agent"] == "x" -def test_jsonl_sink_writes_snapshot_then_event(tmp_path: Path) -> None: +def test_jsonl_sink_writes_snapshot_then_event( + tmp_path: Path, + minimal_pool_runtime_snapshot: PoolRuntimeSnapshot, +) -> None: path = tmp_path / "e.jsonl" sink = JsonlMetricsSink(path) sink.open() - sink.write_snapshot(_minimal_snapshot()) + sink.write_snapshot(minimal_pool_runtime_snapshot) sink.write_event({"event": "session_finished", "agent": "a"}) sink.close() lines = path.read_text(encoding="utf-8").strip().split("\n") @@ -142,8 +144,10 @@ def test_runtime_metrics_store_drains_stream_events() -> None: assert store.drain_stream_events() == [] -def test_snapshot_envelope_shape() -> None: - snap = _minimal_snapshot() +def test_snapshot_envelope_shape( + minimal_pool_runtime_snapshot: PoolRuntimeSnapshot, +) -> None: + snap = minimal_pool_runtime_snapshot env = snapshot_envelope(seq=7, snapshot=snap) assert env["schema_version"] == METRICS_STREAM_SCHEMA_VERSION assert env["kind"] == KIND_SNAPSHOT @@ -152,11 +156,14 @@ def test_snapshot_envelope_shape() -> None: assert env["payload"] == snap.to_dict() -def test_jsonl_sink_truncates_on_open_and_increments_seq(tmp_path: Path) -> None: +def test_jsonl_sink_truncates_on_open_and_increments_seq( + tmp_path: Path, + minimal_pool_runtime_snapshot: PoolRuntimeSnapshot, +) -> None: path = tmp_path / "stream.jsonl" sink = JsonlMetricsSink(path) sink.open() - snap = _minimal_snapshot() + snap = minimal_pool_runtime_snapshot sink.write_snapshot(snap) sink.write_snapshot(snap) sink.close() @@ -168,16 +175,19 @@ def test_jsonl_sink_truncates_on_open_and_increments_seq(tmp_path: Path) -> None assert b["seq"] == 2 -def test_jsonl_sink_new_open_truncates_previous_file(tmp_path: Path) -> None: +def test_jsonl_sink_new_open_truncates_previous_file( + tmp_path: Path, + minimal_pool_runtime_snapshot: PoolRuntimeSnapshot, +) -> None: path = tmp_path / "stream.jsonl" sink1 = JsonlMetricsSink(path) sink1.open() - sink1.write_snapshot(_minimal_snapshot()) + sink1.write_snapshot(minimal_pool_runtime_snapshot) sink1.close() sink2 = JsonlMetricsSink(path) sink2.open() - sink2.write_snapshot(_minimal_snapshot()) + sink2.write_snapshot(minimal_pool_runtime_snapshot) sink2.close() lines = path.read_text(encoding="utf-8").strip().split("\n") @@ -187,24 +197,26 @@ def test_jsonl_sink_new_open_truncates_previous_file(tmp_path: Path) -> None: def test_runtime_reporter_emits_snapshot_then_drained_events_in_order( tmp_path: Path, + minimal_pool_runtime_snapshot: PoolRuntimeSnapshot, ) -> None: """Each tick writes one snapshot line, then any events from the pool (order).""" class _PoolWithOneEvent: - def __init__(self) -> None: + def __init__(self, snap: PoolRuntimeSnapshot) -> None: + self._snap = snap self._sent = False def runtime_snapshot(self) -> PoolRuntimeSnapshot: - return _minimal_snapshot() + return self._snap - def drain_metrics_stream_events(self) -> list[dict[str, object]]: + def drain_metrics_stream_events(self) -> list[MetricsStreamEvent]: if self._sent: return [] self._sent = True return [{"event": "session_started", "agent": "demo"}] path = tmp_path / "ordered.jsonl" - pool = _PoolWithOneEvent() + pool = _PoolWithOneEvent(minimal_pool_runtime_snapshot) reporter = RuntimeReporter( pool, dashboard=False, @@ -214,23 +226,25 @@ def drain_metrics_stream_events(self) -> list[dict[str, object]]: metrics_jsonl_interval=0.25, ) reporter.start() - time.sleep(0.6) - reporter.stop() + try: + lines = _wait_for_jsonl_lines(path, min_lines=2, timeout=5.0) + finally: + reporter.stop() - lines = [ln for ln in path.read_text(encoding="utf-8").split("\n") if ln.strip()] - assert len(lines) >= 1 first = json.loads(lines[0]) assert first["kind"] == KIND_SNAPSHOT assert first["seq"] >= 1 - if len(lines) >= 2: - second = json.loads(lines[1]) - assert second["kind"] == KIND_EVENT - assert second["payload"]["event"] == "session_started" + second = json.loads(lines[1]) + assert second["kind"] == KIND_EVENT + assert second["payload"]["event"] == "session_started" -def test_runtime_reporter_emits_jsonl_periodically(tmp_path: Path) -> None: +def test_runtime_reporter_emits_jsonl_periodically( + tmp_path: Path, + minimal_pool_runtime_snapshot: PoolRuntimeSnapshot, +) -> None: path = tmp_path / "live.jsonl" - pool = _StubPool() + pool = _StubPool(minimal_pool_runtime_snapshot) reporter = RuntimeReporter( pool, dashboard=False, @@ -240,11 +254,11 @@ def test_runtime_reporter_emits_jsonl_periodically(tmp_path: Path) -> None: metrics_jsonl_interval=0.25, ) reporter.start() - time.sleep(0.85) - reporter.stop() + try: + lines = _wait_for_jsonl_lines(path, min_lines=2, timeout=5.0) + finally: + reporter.stop() - lines = [ln for ln in path.read_text(encoding="utf-8").split("\n") if ln.strip()] - assert len(lines) >= 2 first = json.loads(lines[0]) last = json.loads(lines[-1]) assert first["schema_version"] == METRICS_STREAM_SCHEMA_VERSION diff --git a/tests/test_tui_app.py b/tests/test_tui_app.py index 5ed0572..0c5b3c2 100644 --- a/tests/test_tui_app.py +++ b/tests/test_tui_app.py @@ -7,41 +7,11 @@ import pytest from openrtc.metrics_stream import snapshot_envelope -from openrtc.resources import ( - PoolRuntimeSnapshot, - ProcessResidentSetInfo, - SavingsEstimate, -) +from openrtc.resources import PoolRuntimeSnapshot pytest.importorskip("textual") -def _minimal_snapshot() -> PoolRuntimeSnapshot: - return PoolRuntimeSnapshot( - timestamp=1.0, - uptime_seconds=0.5, - registered_agents=1, - active_sessions=0, - total_sessions_started=0, - total_session_failures=0, - last_routed_agent=None, - last_error=None, - sessions_by_agent={}, - resident_set=ProcessResidentSetInfo( - bytes_value=1024, - metric="test", - description="test", - ), - savings_estimate=SavingsEstimate( - agent_count=1, - shared_worker_bytes=1024, - estimated_separate_workers_bytes=1024, - estimated_saved_bytes=0, - assumptions=(), - ), - ) - - @pytest.mark.asyncio async def test_metrics_tui_displays_event_line(tmp_path) -> None: from openrtc.metrics_stream import event_envelope @@ -66,11 +36,14 @@ async def test_metrics_tui_displays_event_line(tmp_path) -> None: @pytest.mark.asyncio -async def test_metrics_tui_skips_malformed_line_then_parses_valid(tmp_path) -> None: +async def test_metrics_tui_skips_malformed_line_then_parses_valid( + tmp_path, + minimal_pool_runtime_snapshot: PoolRuntimeSnapshot, +) -> None: from openrtc.tui_app import MetricsTuiApp path = tmp_path / "mix.jsonl" - snap = _minimal_snapshot() + snap = minimal_pool_runtime_snapshot good = json.dumps(snapshot_envelope(seq=1, snapshot=snap), sort_keys=True) path.write_text("not-valid-json\n" + good + "\n", encoding="utf-8") @@ -83,11 +56,14 @@ async def test_metrics_tui_skips_malformed_line_then_parses_valid(tmp_path) -> N @pytest.mark.asyncio -async def test_metrics_tui_displays_snapshot_line(tmp_path) -> None: +async def test_metrics_tui_displays_snapshot_line( + tmp_path, + minimal_pool_runtime_snapshot: PoolRuntimeSnapshot, +) -> None: from openrtc.tui_app import MetricsTuiApp path = tmp_path / "stream.jsonl" - snap = _minimal_snapshot() + snap = minimal_pool_runtime_snapshot line = json.dumps(snapshot_envelope(seq=1, snapshot=snap), sort_keys=True) path.write_text(line + "\n", encoding="utf-8") From f69fcb13242f2f1dadeb707dd91f8bc711b83cd9 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 22 Mar 2026 04:06:32 +0000 Subject: [PATCH 15/18] chore: refresh uv.lock for tui extra deps Co-authored-by: Mahimai Raja J --- uv.lock | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/uv.lock b/uv.lock index 341d7cd..0fc073a 100644 --- a/uv.lock +++ b/uv.lock @@ -1662,7 +1662,9 @@ cli = [ { name = "typer" }, ] tui = [ + { name = "rich" }, { name = "textual" }, + { name = "typer" }, ] [package.dev-dependencies] @@ -1683,8 +1685,10 @@ dev = [ requires-dist = [ { name = "livekit-agents", extras = ["openai", "silero", "turn-detector"], specifier = "~=1.4" }, { name = "rich", marker = "extra == 'cli'", specifier = ">=13" }, + { name = "rich", marker = "extra == 'tui'", specifier = ">=13" }, { name = "textual", marker = "extra == 'tui'", specifier = ">=0.47,<2" }, { name = "typer", marker = "extra == 'cli'", specifier = ">=0.12" }, + { name = "typer", marker = "extra == 'tui'", specifier = ">=0.12" }, ] provides-extras = ["cli", "tui"] From 1ce1ab23190ea979c63ecf213d0ec40762d98cfa Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 22 Mar 2026 13:41:02 +0000 Subject: [PATCH 16/18] fix: env snapshot for LiveKit CLI, stricter JSONL parse, stream overflow, TUI reopen - Wrap LIVEKIT_* / LIVEKIT_LOG_LEVEL overrides in snapshot/restore around handoff. - Validate seq/wall_time_unix/payload in parse_metrics_jsonl_line; reject bool seq. - Replace maxlen deque drops with explicit cap, overflow counter, warning log, and synthetic metrics_stream_overflow row on drain. - Sync TUI file handle on inode change or truncation; read after reopen in same poll. - Allow unknown LiveKit flags on start/dev/console/connect via Typer context_settings. - Tests: reload passthrough, env restore, malformed envelope, overflow burst, TUI unlink. Co-authored-by: Mahimai Raja J --- src/openrtc/cli_app.py | 134 +++++++++++++++++++++------------- src/openrtc/metrics_stream.py | 20 +++++ src/openrtc/resources.py | 45 ++++++++++-- src/openrtc/tui_app.py | 44 ++++++++++- tests/test_cli.py | 56 ++++++++++++++ tests/test_metrics_stream.py | 40 ++++++++++ tests/test_tui_app.py | 26 +++++++ 7 files changed, 307 insertions(+), 58 deletions(-) diff --git a/src/openrtc/cli_app.py b/src/openrtc/cli_app.py index 51f90ac..2fb662f 100644 --- a/src/openrtc/cli_app.py +++ b/src/openrtc/cli_app.py @@ -1,11 +1,13 @@ from __future__ import annotations +import contextlib import json import logging import os import sys import threading import time +from collections.abc import Iterator from pathlib import Path from typing import Annotated, Any @@ -16,6 +18,7 @@ from rich.progress_bar import ProgressBar from rich.table import Table from rich.text import Text +from typer import Context from openrtc.metrics_stream import JsonlMetricsSink from openrtc.pool import AgentConfig, AgentPool @@ -408,24 +411,48 @@ def _livekit_sys_argv(subcommand: str) -> None: sys.argv = [prog, subcommand] -def _apply_optional_livekit_connection_env( +_LIVEKIT_ENV_OVERRIDE_KEYS: tuple[str, ...] = ( + "LIVEKIT_URL", + "LIVEKIT_API_KEY", + "LIVEKIT_API_SECRET", + "LIVEKIT_LOG_LEVEL", +) + + +def _snapshot_livekit_env() -> dict[str, str | None]: + return {key: os.environ.get(key) for key in _LIVEKIT_ENV_OVERRIDE_KEYS} + + +def _restore_livekit_env(snapshot: dict[str, str | None]) -> None: + for key, previous in snapshot.items(): + if previous is None: + os.environ.pop(key, None) + else: + os.environ[key] = previous + + +@contextlib.contextmanager +def _livekit_env_overrides( *, url: str | None, api_key: str | None, api_secret: str | None, -) -> None: - """Mirror LiveKit CLI env vars when the user passes connection flags on OpenRTC.""" - if url is not None: - os.environ["LIVEKIT_URL"] = url - if api_key is not None: - os.environ["LIVEKIT_API_KEY"] = api_key - if api_secret is not None: - os.environ["LIVEKIT_API_SECRET"] = api_secret - - -def _apply_optional_livekit_log_level(log_level: str | None) -> None: - if log_level is not None: - os.environ["LIVEKIT_LOG_LEVEL"] = log_level + log_level: str | None, +) -> Iterator[None]: + """Temporarily set LiveKit env vars; restore previous values on exit.""" + snapshot = _snapshot_livekit_env() + try: + if url is not None: + os.environ["LIVEKIT_URL"] = url + if api_key is not None: + os.environ["LIVEKIT_API_KEY"] = api_key + if api_secret is not None: + os.environ["LIVEKIT_API_SECRET"] = api_secret + if log_level is not None: + os.environ["LIVEKIT_LOG_LEVEL"] = log_level + yield + finally: + _restore_livekit_env(snapshot) def _delegate_discovered_pool_to_livekit( @@ -451,19 +478,18 @@ def _delegate_discovered_pool_to_livekit( **_pool_kwargs(default_stt, default_llm, default_tts, default_greeting) ) _discover_or_exit(agents_dir, pool) - _apply_optional_livekit_connection_env( - url=url, api_key=api_key, api_secret=api_secret - ) - _apply_optional_livekit_log_level(log_level) - _livekit_sys_argv(subcommand) - _run_pool_with_reporting( - pool, - dashboard=dashboard, - dashboard_refresh=dashboard_refresh, - metrics_json_file=metrics_json_file, - metrics_jsonl=metrics_jsonl, - metrics_jsonl_interval=metrics_jsonl_interval, - ) + with _livekit_env_overrides( + url=url, api_key=api_key, api_secret=api_secret, log_level=log_level + ): + _livekit_sys_argv(subcommand) + _run_pool_with_reporting( + pool, + dashboard=dashboard, + dashboard_refresh=dashboard_refresh, + metrics_json_file=metrics_json_file, + metrics_jsonl=metrics_jsonl, + metrics_jsonl_interval=metrics_jsonl_interval, + ) def _run_connect_handoff( @@ -490,24 +516,24 @@ def _run_connect_handoff( **_pool_kwargs(default_stt, default_llm, default_tts, default_greeting) ) _discover_or_exit(agents_dir, pool) - _apply_optional_livekit_connection_env( - url=url, api_key=api_key, api_secret=api_secret - ) - prog = sys.argv[0] - tail: list[str] = ["connect", "--room", room] - if participant_identity is not None: - tail.extend(["--participant-identity", participant_identity]) - if log_level is not None: - tail.extend(["--log-level", log_level]) - sys.argv = [prog, *tail] - _run_pool_with_reporting( - pool, - dashboard=dashboard, - dashboard_refresh=dashboard_refresh, - metrics_json_file=metrics_json_file, - metrics_jsonl=metrics_jsonl, - metrics_jsonl_interval=metrics_jsonl_interval, - ) + with _livekit_env_overrides( + url=url, api_key=api_key, api_secret=api_secret, log_level=None + ): + prog = sys.argv[0] + tail: list[str] = ["connect", "--room", room] + if participant_identity is not None: + tail.extend(["--participant-identity", participant_identity]) + if log_level is not None: + tail.extend(["--log-level", log_level]) + sys.argv = [prog, *tail] + _run_pool_with_reporting( + pool, + dashboard=dashboard, + dashboard_refresh=dashboard_refresh, + metrics_json_file=metrics_json_file, + metrics_jsonl=metrics_jsonl, + metrics_jsonl_interval=metrics_jsonl_interval, + ) def _discover_or_exit(agents_dir: Path, pool: AgentPool) -> list[AgentConfig]: @@ -923,8 +949,15 @@ def _build_list_json_payload( return payload -@app.command("start") +_LIVEKIT_CLI_CONTEXT_SETTINGS = { + "allow_extra_args": True, + "ignore_unknown_options": True, +} + + +@app.command("start", context_settings=_LIVEKIT_CLI_CONTEXT_SETTINGS) def start_command( + _ctx: Context, agents_dir: AgentsDirArg, default_stt: DefaultSttArg = None, default_llm: DefaultLlmArg = None, @@ -960,8 +993,9 @@ def start_command( ) -@app.command("dev") +@app.command("dev", context_settings=_LIVEKIT_CLI_CONTEXT_SETTINGS) def dev_command( + _ctx: Context, agents_dir: AgentsDirArg, default_stt: DefaultSttArg = None, default_llm: DefaultLlmArg = None, @@ -997,8 +1031,9 @@ def dev_command( ) -@app.command("console") +@app.command("console", context_settings=_LIVEKIT_CLI_CONTEXT_SETTINGS) def console_command( + _ctx: Context, agents_dir: AgentsDirArg, default_stt: DefaultSttArg = None, default_llm: DefaultLlmArg = None, @@ -1034,8 +1069,9 @@ def console_command( ) -@app.command("connect") +@app.command("connect", context_settings=_LIVEKIT_CLI_CONTEXT_SETTINGS) def connect_command( + _ctx: Context, agents_dir: AgentsDirArg, room: ConnectRoomArg, default_stt: DefaultSttArg = None, diff --git a/src/openrtc/metrics_stream.py b/src/openrtc/metrics_stream.py index b8bd8a6..4e33f48 100644 --- a/src/openrtc/metrics_stream.py +++ b/src/openrtc/metrics_stream.py @@ -40,6 +40,17 @@ def snapshot_envelope(*, seq: int, snapshot: PoolRuntimeSnapshot) -> dict[str, A } +def _metrics_json_seq_ok(value: object) -> bool: + """``seq`` must be a JSON integer (reject bool, which subclasses int).""" + return isinstance(value, int) and not isinstance(value, bool) + + +def _metrics_json_wall_ok(value: object) -> bool: + if isinstance(value, bool): + return False + return isinstance(value, (int, float)) + + def parse_metrics_jsonl_line(line: str) -> dict[str, Any] | None: """Return a parsed stream record (snapshot or event), or ``None`` if invalid.""" stripped = line.strip() @@ -54,6 +65,15 @@ def parse_metrics_jsonl_line(line: str) -> dict[str, Any] | None: kind = record.get("kind") if kind not in (KIND_SNAPSHOT, KIND_EVENT): return None + seq = record.get("seq") + if not _metrics_json_seq_ok(seq): + return None + wall = record.get("wall_time_unix") + if not _metrics_json_wall_ok(wall): + return None + payload = record.get("payload") + if payload is None or not isinstance(payload, dict): + return None return record diff --git a/src/openrtc/resources.py b/src/openrtc/resources.py index ca41dd1..64cb318 100644 --- a/src/openrtc/resources.py +++ b/src/openrtc/resources.py @@ -22,12 +22,14 @@ class MetricsStreamEvent(TypedDict, total=False): """One drained session lifecycle row for JSONL export. Rows always include ``event`` and ``agent`` from the store; ``session_failed`` - rows may include ``error``. + rows may include ``error``. A synthetic ``metrics_stream_overflow`` row may + include ``overflow_dropped``. """ event: str agent: str error: str + overflow_dropped: int @dataclass(frozen=True, slots=True) @@ -125,7 +127,13 @@ class RuntimeMetricsStore: sessions_by_agent: dict[str, int] = field(default_factory=dict) _lock: Lock = field(default_factory=Lock, init=False, repr=False, compare=False) _stream_events: deque[MetricsStreamEvent] = field( - default_factory=lambda: deque(maxlen=_STREAM_EVENTS_MAXLEN), + default_factory=deque, + init=False, + repr=False, + compare=False, + ) + _metrics_stream_overflow_since_drain: int = field( + default=0, init=False, repr=False, compare=False, @@ -142,6 +150,7 @@ def __getstate__(self) -> dict[str, object]: "last_error": self.last_error, "sessions_by_agent": dict(self.sessions_by_agent), "_stream_events": stream_events, + "_metrics_stream_overflow_since_drain": self._metrics_stream_overflow_since_drain, } def __setstate__(self, state: Mapping[str, object]) -> None: @@ -155,9 +164,23 @@ def __setstate__(self, state: Mapping[str, object]) -> None: for key, value in dict(state["sessions_by_agent"]).items() } raw_events = state.get("_stream_events", []) - self._stream_events = deque(raw_events, maxlen=_STREAM_EVENTS_MAXLEN) + self._stream_events = deque(raw_events) + self._metrics_stream_overflow_since_drain = int( + state.get("_metrics_stream_overflow_since_drain", 0) + ) self._lock = Lock() + def _append_stream_event_locked(self, event: MetricsStreamEvent) -> None: + if len(self._stream_events) >= _STREAM_EVENTS_MAXLEN: + self._metrics_stream_overflow_since_drain += 1 + logger.warning( + "metrics stream buffer full (%s events); dropping event %r", + _STREAM_EVENTS_MAXLEN, + event.get("event"), + ) + return + self._stream_events.append(event) + def record_session_started(self, agent_name: str) -> None: """Increment active counters for one routed session.""" with self._lock: @@ -166,7 +189,7 @@ def record_session_started(self, agent_name: str) -> None: self.sessions_by_agent[agent_name] = ( self.sessions_by_agent.get(agent_name, 0) + 1 ) - self._stream_events.append( + self._append_stream_event_locked( {"event": "session_started", "agent": agent_name}, ) @@ -179,7 +202,7 @@ def record_session_finished(self, agent_name: str) -> None: self.sessions_by_agent[agent_name] = next_value else: self.sessions_by_agent.pop(agent_name, None) - self._stream_events.append( + self._append_stream_event_locked( {"event": "session_finished", "agent": agent_name}, ) @@ -189,7 +212,7 @@ def record_session_failure(self, agent_name: str, exc: BaseException) -> None: self.last_routed_agent = agent_name self.total_session_failures += 1 self.last_error = f"{exc.__class__.__name__}: {exc}" - self._stream_events.append( + self._append_stream_event_locked( { "event": "session_failed", "agent": agent_name, @@ -202,6 +225,16 @@ def drain_stream_events(self) -> list[MetricsStreamEvent]: with self._lock: out = list(self._stream_events) self._stream_events.clear() + dropped = self._metrics_stream_overflow_since_drain + self._metrics_stream_overflow_since_drain = 0 + if dropped > 0: + out.append( + { + "event": "metrics_stream_overflow", + "agent": "__openrtc__", + "overflow_dropped": dropped, + }, + ) return out def snapshot(self, *, registered_agents: int) -> PoolRuntimeSnapshot: diff --git a/src/openrtc/tui_app.py b/src/openrtc/tui_app.py index 47c9a18..384a6c8 100644 --- a/src/openrtc/tui_app.py +++ b/src/openrtc/tui_app.py @@ -2,6 +2,7 @@ from __future__ import annotations +import os from pathlib import Path from typing import Any, TextIO @@ -25,6 +26,8 @@ def __init__(self, watch_path: Path, *, from_start: bool = False) -> None: self._buf = "" self._latest: dict[str, Any] | None = None self._last_event: dict[str, Any] | None = None + self._path_st_ino: int | None = None + self._path_st_dev: int | None = None def compose(self) -> ComposeResult: yield Header(show_clock=True) @@ -41,9 +44,7 @@ def on_mount(self) -> None: self._path.parent.mkdir(parents=True, exist_ok=True) if not self._path.exists(): self._path.touch() - self._fh = self._path.open("r", encoding="utf-8") - if not self._from_start: - self._fh.seek(0, 2) + self._open_metrics_file() self.set_interval(0.25, self._poll_file) def on_unmount(self) -> None: @@ -51,7 +52,44 @@ def on_unmount(self) -> None: self._fh.close() self._fh = None + def _capture_path_identity(self, st: os.stat_result) -> None: + self._path_st_ino = st.st_ino + self._path_st_dev = st.st_dev + + def _open_metrics_file(self) -> None: + if self._fh is not None: + self._fh.close() + self._fh = None + self._buf = "" + self._fh = self._path.open("r", encoding="utf-8") + if self._from_start: + self._fh.seek(0) + else: + self._fh.seek(0, 2) + st = os.stat(self._path) + self._capture_path_identity(st) + + def _sync_metrics_file_handle(self) -> None: + """Reopen the reader after truncation or path replacement so new bytes are visible.""" + try: + st = os.stat(self._path) + except OSError: + return + if self._fh is None: + self._open_metrics_file() + return + pos = self._fh.tell() + identity_ok = ( + self._path_st_ino is not None + and self._path_st_dev is not None + and st.st_ino == self._path_st_ino + and st.st_dev == self._path_st_dev + ) + if not identity_ok or st.st_size < pos: + self._open_metrics_file() + def _poll_file(self) -> None: + self._sync_metrics_file_handle() if self._fh is None: return chunk = self._fh.read() diff --git a/tests/test_cli.py b/tests/test_cli.py index 0d19bbb..30a8eac 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -4,6 +4,7 @@ import importlib import json import logging +import os import re import sys from dataclasses import dataclass @@ -315,6 +316,61 @@ def test_strip_openrtc_only_flags_for_livekit_removes_openrtc_options() -> None: ) == ["--reload"] +def test_dev_passes_reload_through_argv_strip( + monkeypatch: pytest.MonkeyPatch, + tmp_path: Path, +) -> None: + import openrtc.cli_app as cli_app_mod + + agents = tmp_path / "agents" + agents.mkdir() + stub_pool = StubPool(discovered=[StubConfig(name="a", agent_cls=StubAgent)]) + monkeypatch.setattr(cli_app_mod, "AgentPool", lambda **kwargs: stub_pool) + def _run_pool_stub(pool: StubPool, **kwargs: Any) -> None: + pool.run() + + monkeypatch.setattr(cli_app_mod, "_run_pool_with_reporting", _run_pool_stub) + real_strip = cli_app_mod._strip_openrtc_only_flags_for_livekit + recorded: list[tuple[list[str], list[str]]] = [] + + def recording_strip(tail: list[str]) -> list[str]: + out = real_strip(tail) + recorded.append((list(tail), list(out))) + return out + + monkeypatch.setattr( + cli_app_mod, + "_strip_openrtc_only_flags_for_livekit", + recording_strip, + ) + monkeypatch.setattr( + sys, + "argv", + ["openrtc", "dev", "--agents-dir", str(agents), "--reload"], + ) + exit_code = main(["dev", "--agents-dir", str(agents), "--reload"]) + assert exit_code == 0 + assert stub_pool.run_called + assert recorded + assert recorded[0][1] == ["--reload"] + + +def test_livekit_env_restored_after_delegate_returns( + monkeypatch: pytest.MonkeyPatch, +) -> None: + import openrtc.cli_app as cli_app_mod + + stub_pool = StubPool(discovered=[StubConfig(name="a", agent_cls=StubAgent)]) + monkeypatch.setattr(cli_app_mod, "AgentPool", lambda **kwargs: stub_pool) + monkeypatch.setattr(cli_app_mod, "_run_pool_with_reporting", lambda *a, **k: None) + monkeypatch.setenv("LIVEKIT_URL", "ws://persist") + exit_code = main( + ["start", "--agents-dir", "./agents", "--url", "ws://temporary-override"], + ) + assert exit_code == 0 + assert os.environ.get("LIVEKIT_URL") == "ws://persist" + + def test_cli_entrypoint_documents_optional_extra() -> None: from openrtc.cli import CLI_EXTRA_INSTALL_HINT diff --git a/tests/test_metrics_stream.py b/tests/test_metrics_stream.py index de38fd1..7f3ce24 100644 --- a/tests/test_metrics_stream.py +++ b/tests/test_metrics_stream.py @@ -3,6 +3,7 @@ from __future__ import annotations import json +import logging import time from pathlib import Path @@ -76,6 +77,24 @@ def test_parse_metrics_jsonl_line() -> None: assert parse_metrics_jsonl_line('{"schema_version": 999}') is None +def test_parse_metrics_jsonl_line_rejects_malformed_envelope() -> None: + base = { + "schema_version": METRICS_STREAM_SCHEMA_VERSION, + "kind": KIND_SNAPSHOT, + "seq": 1, + "wall_time_unix": 1.0, + "payload": {"x": 1}, + } + bad_seq = {**base, "seq": True} + assert parse_metrics_jsonl_line(json.dumps(bad_seq)) is None + bad_wall = {**base, "wall_time_unix": None} + assert parse_metrics_jsonl_line(json.dumps(bad_wall)) is None + bad_payload = {**base, "payload": None} + assert parse_metrics_jsonl_line(json.dumps(bad_payload)) is None + bad_payload2 = {**base, "payload": [1, 2]} + assert parse_metrics_jsonl_line(json.dumps(bad_payload2)) is None + + def test_parse_metrics_jsonl_line_rejects_unknown_kind() -> None: bad = json.dumps( { @@ -144,6 +163,27 @@ def test_runtime_metrics_store_drains_stream_events() -> None: assert store.drain_stream_events() == [] +def test_runtime_metrics_store_overflow_emits_synthetic_on_drain( + monkeypatch: pytest.MonkeyPatch, + caplog: pytest.LogCaptureFixture, +) -> None: + from openrtc import resources as resources_mod + from openrtc.resources import RuntimeMetricsStore + + monkeypatch.setattr(resources_mod, "_STREAM_EVENTS_MAXLEN", 3) + store = RuntimeMetricsStore() + with caplog.at_level(logging.WARNING, logger="openrtc"): + for _ in range(6): + store.record_session_started("x") + drained = store.drain_stream_events() + assert len([e for e in drained if e.get("event") == "session_started"]) == 3 + overflow_rows = [e for e in drained if e.get("event") == "metrics_stream_overflow"] + assert len(overflow_rows) == 1 + assert overflow_rows[0].get("overflow_dropped") == 3 + assert "metrics stream buffer full" in caplog.text + assert store.drain_stream_events() == [] + + def test_snapshot_envelope_shape( minimal_pool_runtime_snapshot: PoolRuntimeSnapshot, ) -> None: diff --git a/tests/test_tui_app.py b/tests/test_tui_app.py index 0c5b3c2..d16274a 100644 --- a/tests/test_tui_app.py +++ b/tests/test_tui_app.py @@ -75,3 +75,29 @@ async def test_metrics_tui_displays_snapshot_line( text = str(status.renderable) assert "seq=1" in text assert "registered=1" in text + + +@pytest.mark.asyncio +async def test_metrics_tui_reopens_after_writer_truncates_file( + tmp_path, + minimal_pool_runtime_snapshot: PoolRuntimeSnapshot, +) -> None: + from openrtc.tui_app import MetricsTuiApp + + path = tmp_path / "rot.jsonl" + snap = minimal_pool_runtime_snapshot + first = json.dumps(snapshot_envelope(seq=1, snapshot=snap), sort_keys=True) + path.write_text(first + "\n", encoding="utf-8") + + app = MetricsTuiApp(path, from_start=True) + async with app.run_test() as pilot: + app._poll_file() + await pilot.pause() + assert "seq=1" in str(app.query_one("#status").renderable) + + path.unlink() + second = json.dumps(snapshot_envelope(seq=2, snapshot=snap), sort_keys=True) + path.write_text(second + "\n", encoding="utf-8") + app._poll_file() + await pilot.pause() + assert "seq=2" in str(app.query_one("#status").renderable) From 3b7380abc1584b539aefced0ddbb8bd8842bca9a Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 22 Mar 2026 13:48:09 +0000 Subject: [PATCH 17/18] test: raise patch coverage; install tui extra in CI - Install openrtc[cli,tui] in GitHub Actions so Textual TUI tests run under cov. - Add JsonlMetricsSink.seq, bool wall_time, AgentPool.drain_metrics tests. - Expand tui_app tests for tail mode, reopen, bad payloads, wall fallback, run_metrics_tui, stat OSError, and defensive branches. Co-authored-by: Mahimai Raja J --- .github/workflows/test.yml | 2 +- tests/test_cli.py | 1 + tests/test_metrics_stream.py | 30 ++++ tests/test_pool.py | 6 + tests/test_tui_app.py | 263 +++++++++++++++++++++++++++++++++++ 5 files changed, 301 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3e5768b..da944fb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,7 +26,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - python -m pip install -e ".[cli]" pytest pytest-asyncio pytest-cov + python -m pip install -e ".[cli,tui]" pytest pytest-asyncio pytest-cov - name: Run tests with coverage run: pytest --cov=openrtc --cov-report=xml --cov-fail-under=80 diff --git a/tests/test_cli.py b/tests/test_cli.py index 30a8eac..b988aea 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -326,6 +326,7 @@ def test_dev_passes_reload_through_argv_strip( agents.mkdir() stub_pool = StubPool(discovered=[StubConfig(name="a", agent_cls=StubAgent)]) monkeypatch.setattr(cli_app_mod, "AgentPool", lambda **kwargs: stub_pool) + def _run_pool_stub(pool: StubPool, **kwargs: Any) -> None: pool.run() diff --git a/tests/test_metrics_stream.py b/tests/test_metrics_stream.py index 7f3ce24..a2bec06 100644 --- a/tests/test_metrics_stream.py +++ b/tests/test_metrics_stream.py @@ -77,6 +77,36 @@ def test_parse_metrics_jsonl_line() -> None: assert parse_metrics_jsonl_line('{"schema_version": 999}') is None +def test_parse_metrics_jsonl_line_rejects_bool_wall_time() -> None: + bad = json.dumps( + { + "schema_version": METRICS_STREAM_SCHEMA_VERSION, + "kind": KIND_SNAPSHOT, + "seq": 1, + "wall_time_unix": True, + "payload": {}, + } + ) + assert parse_metrics_jsonl_line(bad) is None + + +def test_jsonl_sink_seq_property( + tmp_path: Path, + minimal_pool_runtime_snapshot: PoolRuntimeSnapshot, +) -> None: + """Cover :attr:`JsonlMetricsSink.seq` (lock + counter).""" + snap = minimal_pool_runtime_snapshot + path = tmp_path / "seq.jsonl" + sink = JsonlMetricsSink(path) + sink.open() + assert sink.seq == 0 + sink.write_snapshot(snap) + assert sink.seq == 1 + sink.write_event({"event": "x"}) + assert sink.seq == 2 + sink.close() + + def test_parse_metrics_jsonl_line_rejects_malformed_envelope() -> None: base = { "schema_version": METRICS_STREAM_SCHEMA_VERSION, diff --git a/tests/test_pool.py b/tests/test_pool.py index dcef602..592025b 100644 --- a/tests/test_pool.py +++ b/tests/test_pool.py @@ -588,3 +588,9 @@ def __init__(self, **kwargs: object) -> None: assert snapshot.total_sessions_started == 0 assert snapshot.total_session_failures == 0 assert snapshot.sessions_by_agent == {} + + +def test_drain_metrics_stream_events_delegates_to_runtime_store() -> None: + pool = AgentPool() + pool.add("test", DemoAgent, stt="a", llm="b", tts="c") + assert pool.drain_metrics_stream_events() == [] diff --git a/tests/test_tui_app.py b/tests/test_tui_app.py index d16274a..8ddd16d 100644 --- a/tests/test_tui_app.py +++ b/tests/test_tui_app.py @@ -3,6 +3,8 @@ from __future__ import annotations import json +import os +from pathlib import Path import pytest @@ -101,3 +103,264 @@ async def test_metrics_tui_reopens_after_writer_truncates_file( app._poll_file() await pilot.pause() assert "seq=2" in str(app.query_one("#status").renderable) + + +@pytest.mark.asyncio +async def test_metrics_tui_creates_watch_file_when_missing(tmp_path: Path) -> None: + from openrtc.tui_app import MetricsTuiApp + + watch = tmp_path / "nested" / "metrics.jsonl" + app = MetricsTuiApp(watch, from_start=True) + async with app.run_test(): + assert watch.is_file() + + +@pytest.mark.asyncio +async def test_metrics_tui_tail_mode_seeks_to_end_then_reads_appends( + tmp_path: Path, + minimal_pool_runtime_snapshot: PoolRuntimeSnapshot, +) -> None: + from openrtc.tui_app import MetricsTuiApp + + path = tmp_path / "tail.jsonl" + snap = minimal_pool_runtime_snapshot + path.write_text( + json.dumps(snapshot_envelope(seq=1, snapshot=snap), sort_keys=True) + "\n", + encoding="utf-8", + ) + app = MetricsTuiApp(path, from_start=False) + async with app.run_test() as pilot: + assert app._fh is not None + assert app._fh.tell() == path.stat().st_size + more = ( + json.dumps(snapshot_envelope(seq=2, snapshot=snap), sort_keys=True) + "\n" + ) + path.write_text(path.read_text(encoding="utf-8") + more, encoding="utf-8") + app._poll_file() + await pilot.pause() + assert "seq=2" in str(app.query_one("#status").renderable) + + +@pytest.mark.asyncio +async def test_metrics_tui_poll_returns_early_when_no_new_bytes( + tmp_path: Path, + minimal_pool_runtime_snapshot: PoolRuntimeSnapshot, +) -> None: + from openrtc.tui_app import MetricsTuiApp + + path = tmp_path / "empty_poll.jsonl" + snap = minimal_pool_runtime_snapshot + path.write_text( + json.dumps(snapshot_envelope(seq=1, snapshot=snap), sort_keys=True) + "\n", + encoding="utf-8", + ) + app = MetricsTuiApp(path, from_start=True) + async with app.run_test() as pilot: + app._poll_file() + await pilot.pause() + app._poll_file() + await pilot.pause() + assert "seq=1" in str(app.query_one("#status").renderable) + + +@pytest.mark.asyncio +async def test_metrics_tui_sync_opens_when_handle_cleared( + tmp_path: Path, + minimal_pool_runtime_snapshot: PoolRuntimeSnapshot, +) -> None: + from openrtc.tui_app import MetricsTuiApp + + path = tmp_path / "reopen.jsonl" + snap = minimal_pool_runtime_snapshot + path.write_text( + json.dumps(snapshot_envelope(seq=1, snapshot=snap), sort_keys=True) + "\n", + encoding="utf-8", + ) + app = MetricsTuiApp(path, from_start=True) + async with app.run_test() as pilot: + app._fh.close() + app._fh = None + app._poll_file() + await pilot.pause() + assert app._fh is not None + assert "seq=1" in str(app.query_one("#status").renderable) + + +@pytest.mark.asyncio +async def test_metrics_tui_refresh_event_line_noop_without_event( + tmp_path: Path, +) -> None: + from openrtc.tui_app import MetricsTuiApp + + path = tmp_path / "no_ev.jsonl" + path.touch() + app = MetricsTuiApp(path, from_start=True) + async with app.run_test() as pilot: + app._last_event = None + app._refresh_event_line() + await pilot.pause() + + +@pytest.mark.asyncio +async def test_metrics_tui_refresh_view_noop_when_latest_missing( + tmp_path: Path, +) -> None: + from openrtc.tui_app import MetricsTuiApp + + path = tmp_path / "no_latest.jsonl" + path.touch() + app = MetricsTuiApp(path, from_start=True) + async with app.run_test() as pilot: + app._latest = None + app._refresh_view() + await pilot.pause() + + +@pytest.mark.asyncio +async def test_metrics_tui_sync_ignores_stat_oserror( + tmp_path: Path, + monkeypatch: pytest.MonkeyPatch, +) -> None: + import openrtc.tui_app as tu + from openrtc.tui_app import MetricsTuiApp + + path = tmp_path / "stat_err.jsonl" + path.touch() + real_stat = os.stat + armed = {"on": False} + + target = os.fspath(path) + + def stat_fn( + p: str | os.PathLike[str], + *args: object, + **kwargs: object, + ) -> os.stat_result: + if armed["on"] and os.fspath(p) == target: + raise OSError("stat failed") + return real_stat(p, *args, **kwargs) + + monkeypatch.setattr(tu.os, "stat", stat_fn) + app = MetricsTuiApp(path, from_start=True) + async with app.run_test() as pilot: + armed["on"] = True + app._poll_file() + await pilot.pause() + + +@pytest.mark.asyncio +async def test_metrics_tui_refresh_view_skips_bad_payload_shapes( + tmp_path: Path, + minimal_pool_runtime_snapshot: PoolRuntimeSnapshot, +) -> None: + from openrtc.tui_app import MetricsTuiApp + + path = tmp_path / "bad_payload.jsonl" + path.touch() + app = MetricsTuiApp(path, from_start=True) + async with app.run_test() as pilot: + app._latest = {"payload": "not-a-dict"} + app._refresh_view() + app._latest = { + "seq": 9, + "wall_time_unix": 1.0, + "payload": { + "registered_agents": 1, + "active_sessions": 0, + "uptime_seconds": 1.0, + "sessions_by_agent": [1, 2], + "last_routed_agent": None, + "last_error": None, + "total_sessions_started": 0, + "total_session_failures": 0, + }, + } + app._refresh_view() + await pilot.pause() + text = str(app.query_one("#agents").renderable) + assert "invalid payload" in text + + +@pytest.mark.asyncio +async def test_metrics_tui_wall_time_invalid_falls_back_to_na( + tmp_path: Path, + minimal_pool_runtime_snapshot: PoolRuntimeSnapshot, +) -> None: + from openrtc.tui_app import MetricsTuiApp + + path = tmp_path / "wall.jsonl" + path.touch() + app = MetricsTuiApp(path, from_start=True) + snap = minimal_pool_runtime_snapshot + async with app.run_test() as pilot: + app._latest = { + "seq": 3, + "wall_time_unix": "not-numeric", + "payload": snap.to_dict(), + } + app._refresh_view() + await pilot.pause() + assert "wall=n/a" in str(app.query_one("#status").renderable) + + +@pytest.mark.asyncio +async def test_metrics_tui_action_quit_exits(tmp_path: Path) -> None: + from openrtc.tui_app import MetricsTuiApp + + path = tmp_path / "quit.jsonl" + path.touch() + app = MetricsTuiApp(path, from_start=True) + async with app.run_test() as pilot: + app.action_quit() + await pilot.pause() + + +def test_run_metrics_tui_calls_app_run( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + import openrtc.tui_app as tu + + ran: list[object] = [] + + def fake_run(self: object) -> None: + ran.append(self) + + monkeypatch.setattr(tu.MetricsTuiApp, "run", fake_run) + p = tmp_path / "x.jsonl" + p.touch() + tu.run_metrics_tui(p, from_start=True) + assert len(ran) == 1 + assert getattr(ran[0], "_path", None) == p.resolve() + + +@pytest.mark.asyncio +async def test_metrics_tui_poll_returns_when_open_does_not_restore_handle( + tmp_path: Path, + monkeypatch: pytest.MonkeyPatch, +) -> None: + from openrtc.tui_app import MetricsTuiApp + + path = tmp_path / "noop_open.jsonl" + path.touch() + app = MetricsTuiApp(path, from_start=True) + async with app.run_test(): + + def noop_open() -> None: + app._fh = None + app._buf = "" + + monkeypatch.setattr(app, "_open_metrics_file", noop_open) + app._fh = None + app._poll_file() + + +@pytest.mark.asyncio +async def test_metrics_tui_on_unmount_closes_file_handle(tmp_path: Path) -> None: + from openrtc.tui_app import MetricsTuiApp + + path = tmp_path / "um.jsonl" + path.touch() + app = MetricsTuiApp(path, from_start=True) + async with app.run_test(): + assert app._fh is not None + assert app._fh is None From 18d5e6f69a88cc1766a68139b4969df8139d84ec Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 22 Mar 2026 13:57:04 +0000 Subject: [PATCH 18/18] chore(codecov): ignore Textual tui_app.py in Codecov reports Exclude optional TUI module from Codecov project/patch math; pytest --cov still measures it in CI with [cli,tui]. Dots escaped for regex per Codecov docs. Co-authored-by: Mahimai Raja J --- codecov.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/codecov.yml b/codecov.yml index 9ab4c6e..42af682 100644 --- a/codecov.yml +++ b/codecov.yml @@ -3,6 +3,12 @@ # Codecov checks and PR comments. Patch status is informational so small PRs # are not blocked twice (pytest remains the hard gate for overall %). +# Optional Textual sidecar (`openrtc[tui]`). Excluded from Codecov totals/patch so +# PR checks are not dominated by UI-only lines; `pytest --cov=openrtc` still +# includes it unless you omit it locally. +ignore: + - "**/openrtc/tui_app\\.py" + coverage: precision: 2 round: down