feat(service_livekit): per-user livekit ports via hero_cfg.toml [livekit] #176

Merged
sameh-farouk merged 2 commits from feat/livekit-per-user-ports-auto into development 2026-04-30 04:45:32 +00:00
Member

Closes #175. Supersedes #174 (which is now closed — the forward-compat 1-liner from that PR is folded into this single commit).

Companion to hero_livekit#34.

Summary

Single file changed (tools/modules/services/service_livekit.nu). Two coordinated edits:

  1. New helper svx_lk_read_hero_cfg_livekit — reads [livekit] section from ~/hero/cfg/hero_cfg.toml, returns {} if missing.
  2. svx_lk_install_and_configure reads the section once and passes the values (with 0 fallback for missing fields) into cfg_params's livekit_port / rtc_tcp_port / backend_port.

Makes service_livekit.nu both (a) forward-compatible with hero_livekit#34's required rtc_tcp_port param, and (b) per-user-aware via cfg.toml.

Architecture

  • hero_cfg.toml is the durable per-user source. Already carries [mycelium]; adding [livekit] follows the existing pattern (service_router.nu / service_collab.nu read sections from the same file).
  • runtime.json is correctly modeled as a derived cache. The wipe in svx_lk_wipe_stale_configs stays untouched — it correctly forces a clean slate on inconsistency. Per-user values survive wipes because the next service_livekit start re-reads hero_cfg.toml and re-derives runtime.json from there.

An earlier draft (#174) considered preserving runtime.json across wipes — that was the wrong layer to fix it and was dropped.

Behavior

Scenario hero_cfg.toml [livekit] Result
Single-user install (today) absent Defaults 7880 / 7881 / 8081. Unchanged.
Multi-user user without [livekit] absent Defaults — collides if sibling is also on defaults. Operator must add the section.
Multi-user with [livekit] per user present, non-overlapping triples Values flow: cfg.toml → configure RPC → runtime.json → yaml → livekit-server bind. Survives wipes.

Operator workflow on a multi-user box

# /home/alice/hero/cfg/hero_cfg.toml
[mycelium]
bridge_name = "br-alice"
ipv6_address = "..."

[livekit]
livekit_port = 7890
rtc_tcp_port = 7891
backend_port = 8091

Then service_livekit start and never touch it again.

Compatibility matrix with hero_livekit binary versions

service_livekit.nu hero_livekit binary configure RPC works?
old old
old new (#34) ✗ Missing required parameter
this PR old ✓ extra field ignored by old serde
this PR new (#34)

Land this PR at-or-before the hero_livekit binary is upgraded on operator boxes.

What's intentionally NOT in this PR

An allocator that auto-writes the [livekit] section. The section is operator-managed today; if a tool to allocate non-overlapping triples becomes useful, it can be added as a separate small helper (e.g. hero_user_livekit_alloc <user>) — kept OUT of multi_user_add, which is mycelium-focused and shouldn't carry livekit-specific allocation logic.

Test plan

  • service_livekit start with no [livekit] section: defaults apply, single-user setup unchanged
  • service_livekit start with [livekit] section: values flow into configure RPC → runtime.json → yaml → livekit-server bind
  • service_livekit start --reset (which wipes runtime.json): next start re-reads cfg.toml [livekit], values reconstructed
  • Two users coexist on dev box (138.201.206.39): sameh + ashraf with non-overlapping port triples
Closes #175. Supersedes #174 (which is now closed — the forward-compat 1-liner from that PR is folded into this single commit). Companion to [hero_livekit#34](https://forge.ourworld.tf/lhumina_code/hero_livekit/pulls/34). ## Summary Single file changed (`tools/modules/services/service_livekit.nu`). Two coordinated edits: 1. **New helper `svx_lk_read_hero_cfg_livekit`** — reads `[livekit]` section from `~/hero/cfg/hero_cfg.toml`, returns `{}` if missing. 2. **`svx_lk_install_and_configure`** reads the section once and passes the values (with `0` fallback for missing fields) into `cfg_params`'s `livekit_port` / `rtc_tcp_port` / `backend_port`. Makes service_livekit.nu both (a) forward-compatible with hero_livekit#34's required `rtc_tcp_port` param, and (b) per-user-aware via cfg.toml. ## Architecture - `hero_cfg.toml` is the durable per-user source. Already carries `[mycelium]`; adding `[livekit]` follows the existing pattern (`service_router.nu` / `service_collab.nu` read sections from the same file). - `runtime.json` is correctly modeled as a derived cache. The wipe in `svx_lk_wipe_stale_configs` stays untouched — it correctly forces a clean slate on inconsistency. Per-user values survive wipes because the next `service_livekit start` re-reads `hero_cfg.toml` and re-derives runtime.json from there. An earlier draft (#174) considered preserving runtime.json across wipes — that was the wrong layer to fix it and was dropped. ## Behavior | Scenario | hero_cfg.toml `[livekit]` | Result | |---|---|---| | Single-user install (today) | absent | Defaults 7880 / 7881 / 8081. **Unchanged.** | | Multi-user user without `[livekit]` | absent | Defaults — collides if sibling is also on defaults. Operator must add the section. | | Multi-user with `[livekit]` per user | present, non-overlapping triples | Values flow: cfg.toml → configure RPC → runtime.json → yaml → livekit-server bind. Survives wipes. | ## Operator workflow on a multi-user box ```toml # /home/alice/hero/cfg/hero_cfg.toml [mycelium] bridge_name = "br-alice" ipv6_address = "..." [livekit] livekit_port = 7890 rtc_tcp_port = 7891 backend_port = 8091 ``` Then `service_livekit start` and never touch it again. ## Compatibility matrix with hero_livekit binary versions | service_livekit.nu | hero_livekit binary | configure RPC works? | |---|---|---| | old | old | ✓ | | old | new (#34) | ✗ Missing required parameter | | **this PR** | old | ✓ extra field ignored by old serde | | **this PR** | new (#34) | ✓ | Land this PR at-or-before the hero_livekit binary is upgraded on operator boxes. ## What's intentionally NOT in this PR An allocator that auto-writes the `[livekit]` section. The section is operator-managed today; if a tool to allocate non-overlapping triples becomes useful, it can be added as a separate small helper (e.g. `hero_user_livekit_alloc <user>`) — kept OUT of `multi_user_add`, which is mycelium-focused and shouldn't carry livekit-specific allocation logic. ## Test plan - [x] `service_livekit start` with no `[livekit]` section: defaults apply, single-user setup unchanged - [x] `service_livekit start` with `[livekit]` section: values flow into configure RPC → runtime.json → yaml → livekit-server bind - [x] `service_livekit start --reset` (which wipes runtime.json): next start re-reads cfg.toml `[livekit]`, values reconstructed - [x] Two users coexist on dev box (138.201.206.39): sameh + ashraf with non-overlapping port triples
Companion to hero_livekit#34 + hero_skills#174. Closes the loop on
multi-user livekit by sourcing per-user port values from a durable
location (hero_cfg.toml) instead of relying on runtime.json being
preserved across wipes.

What changes:

  - New helper svx_lk_read_hero_cfg_livekit reads [livekit] section
    from ~/hero/cfg/hero_cfg.toml. Returns {} if the file or section
    is missing — callers default each field to 0 ("keep current").
  - svx_lk_install_and_configure reads the section once and passes
    the values into cfg_params. Hardcoded 0 placeholders are replaced
    with the read values.

Architecture: hero_cfg.toml is the durable per-user source (alongside
[mycelium]). runtime.json is a derived cache that gets regenerated by
the next configure RPC after every --reset / wipe. So per-user values
survive wipes by being re-read from cfg.toml here, not by preserving
the cache. The wipe in svx_lk_wipe_stale_configs stays untouched.

Backwards-compatible:

  - Single-user setups (no [livekit] section): each field falls back
    to 0 → wrapper uses defaults (7880/7881/8081). Existing single-
    user installs untouched.
  - Multi-user setups: operator (or external allocator) writes the
    [livekit] section once per user; service_livekit start picks it
    up automatically every restart. No bypass needed.

Pattern matches how service_router.nu / service_collab.nu read
[mycelium] from the same file.

Per-user port allocation policy is intentionally kept OUT of this PR.
The [livekit] section is operator-managed today (or by a future
hero_skills helper command). multi_user_add stays focused on
mycelium; bolting on a livekit-specific allocator there would be out
of pattern. If a tool to auto-allocate triples becomes useful, it can
be added separately as e.g. `hero_user_livekit_alloc <user>` without
touching multi_user_add.

Test plan:
  - service_livekit start with no [livekit] section: defaults apply
    (7880/7881/8081), single-user setup unchanged.
  - service_livekit start with [livekit] section: values flow into
    configure RPC -> runtime.json -> rendered yaml -> livekit-server
    binds the configured ports.
  - service_livekit start --reset (which wipes runtime.json): next
    start re-reads cfg.toml [livekit], values reconstructed.
sameh-farouk force-pushed feat/livekit-per-user-ports-auto from 5500b7b10e to 489b49d584 2026-04-30 02:14:46 +00:00 Compare
sameh-farouk changed title from feat(service_livekit): read [livekit] section from hero_cfg.toml for per-user ports to feat(service_livekit): per-user livekit ports via hero_cfg.toml [livekit] 2026-04-30 02:16:52 +00:00
sameh-farouk changed target branch from feat/livekit-per-user-ports-compat to development 2026-04-30 02:16:53 +00:00
Merge branch 'development' into feat/livekit-per-user-ports-auto
All checks were successful
Build and Publish Skills / build-and-publish (pull_request) Successful in 3s
dc7bce97ba
sameh-farouk merged commit b6c99ea6e9 into development 2026-04-30 04:45:32 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lhumina_code/hero_skills!176
No description provided.