robopark 3.3.16 → 3.3.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/scheduler/main.py +36 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "robopark",
3
- "version": "3.3.16",
3
+ "version": "3.3.17",
4
4
  "description": "RoboPark fleet control CLI \u2014 scheduler, control UI, and character voice calls. Standalone: no infinicode runtime.",
5
5
  "type": "module",
6
6
  "bin": {
package/scheduler/main.py CHANGED
@@ -957,6 +957,41 @@ LIVEKIT_CONFIG_PATH = os.path.join(
957
957
  )
958
958
 
959
959
 
960
+ async def _ensure_local_livekit_server() -> None:
961
+ """Register a local LiveKit server when the deployment has none.
962
+
963
+ Everything camera-related is gated on a row in livekit_servers: without one
964
+ no livekit.yaml is written, `robopark serve` starts no media server, camera
965
+ tokens 503, nothing publishes, and the camera grid correctly reports an
966
+ empty fleet. A fresh install had no such row and nothing created one, so
967
+ cameras silently never worked while every other part of a call did.
968
+ """
969
+ try:
970
+ async with aiosqlite.connect(DB_PATH) as db:
971
+ async with db.execute("SELECT COUNT(*) FROM livekit_servers") as c:
972
+ row = await c.fetchone()
973
+ if row and int(row[0] or 0) > 0:
974
+ return
975
+
976
+ # Credentials are generated per install rather than shipped, so two
977
+ # deployments never share a signing key.
978
+ api_key = "API" + secrets.token_hex(6)
979
+ api_secret = secrets.token_urlsafe(30)
980
+ now = datetime.utcnow().isoformat()
981
+ await db.execute(
982
+ "INSERT INTO livekit_servers (id, name, url, webhook_url, api_key, api_secret, "
983
+ "max_sessions, status, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
984
+ (
985
+ "livekit-local", "Local LiveKit", "ws://localhost:7883", "",
986
+ api_key, api_secret, 8, "unknown", now,
987
+ ),
988
+ )
989
+ await db.commit()
990
+ logger.info("Registered a local LiveKit server (ws://localhost:7883) for camera streaming")
991
+ except Exception as exc:
992
+ logger.warning("Could not register a local LiveKit server: %s", exc)
993
+
994
+
960
995
  async def _write_local_livekit_config() -> None:
961
996
  """Emit a launchable config for a LiveKit server we host ourselves.
962
997
 
@@ -1030,6 +1065,7 @@ async def lifespan(app: FastAPI):
1030
1065
  logger.warning(
1031
1066
  "RoboPark agent secret is unavailable; voice-agent keepalive calls will 401."
1032
1067
  )
1068
+ await _ensure_local_livekit_server()
1033
1069
  await _write_local_livekit_config()
1034
1070
  asyncio.create_task(metrics_collector())
1035
1071
  asyncio.create_task(health_checker())