Migrate hero_livekit to hero_rpc2 (restore main-compat; preserve LiveKitService.* wire contract) #40
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "livekit_migration"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
Migrates
hero_livekitoff the retiredOServerframework onto hero_rpc2 /HeroOsisServer, restoring buildability and runtime correctness againstmain-pinned dependencies (post hero_rpc simplification). This supersedes the temporarybranch=developmentdep workaround currently onmain(5f34f35).Why
hero_rpcmaindroppedhero_rpc_server/hero_rpc_clientin favour ofhero_rpc2.hero_livekitwas the one consumer left un-migrated, so itsmainno longer built againstmain-pinned deps. This branch completes the migration so livekit ismain-compatible again — no morebranch=developmentpin.The one non-trivial fix — custom SFU method dispatch
hero_rpc2's adapter registers service methods under the generator's snake_case name (
live_kit_service.status) and jsonrpsee matches method names by exact, case-sensitive lookup. Every existing client (generatedhero_livekit_sdk, the admin dashboard JS, cross-repo callers) sends the PascalCase wire nameLiveKitService.status. The oldOServerlowercased inbound methods, so any casing worked; hero_rpc2 does not.crates/hero_livekit_server/src/main.rsassembles theRpcModuleexplicitly (mirroringHeroOsisServer::serve()) and registers aLiveKitService.<method>alias for each service-block method, forwarding to the samehandle_service_call_with_contextentry point under the snake_case dispatch key the generated match arms expect. TheLiveKitService.*wire contract is preserved byte-for-byte.Deps / lockfile (per request)
Cargo.toml: all hero_* deps pinbranch = "main"(0branch=development).Cargo.lock: fully refreshed against currentmainHEADs — hero_rpc2/hero_rpc_osisf6509f9, herolib9657556a, hero_proc_sdk0fe2a3d1.cargo metadata --lockedconsistent; removedhero_rpc_server/hero_rpc_clientabsent.rust-toolchain.toml:1.96(hero_rpc2/herolib_ai require it).Verification (local, on this box)
Build:
cargo build --release --locked --workspace✓ (clean, only async-trait warnings). Authz suite 11/11 ✓.Runtime — installed the migrated binaries, restarted via
hero_proc, exercised the live socket:LiveKitService.status(PascalCase alias)"running"— dispatches, no-32601live_kit_service.status(snake native)"running"LiveKitService.list_rooms→ SFU[](reaches livekit-server)room.*CRUD (adapter)[]LiveKitService.bogus-32601(correct negative)LiveKitService.start→ SFU lifecyclelivekit-servercame up @192.168.99.4:7880GET /openrpc.jsonhuddle.start+huddle.joinmint a valid JWT (video.room=huddle-10, roomJoin/canPublish,ws_url=ws://192.168.99.4:7880) — no consumer regressioncollab mints tokens locally from the hero_proc secret store, independent of livekit's RPC, and the migrated server correctly supervises the SFU those tokens target.
Merge note
mainwas merged into this branch (not rebased). The interimbranch=developmentworkaround is intentionally overridden by the migration'sbranch=mainpins; the publish-CI rustc-1.96 fix frommainis carried in.Risk
Low. Wire contract preserved; build + runtime + cross-consumer (collab) verified. Reviewer holds the merge gate.
The OServer→HeroOsisServer migration left the service-block lifecycle methods (LiveKitService.install/configure/start/.../issue_token) undispatchable: every call returned -32601 while rpc.discover and /openrpc.json still advertised them. Root cause: hero_rpc2's rpc2_adapter registers service methods with jsonrpsee under the *lowercased* name taken from OsisAppRpcHandler::openrpc_spec() (the build-generated docs/livekit/openrpc.json, whose service prefix is to_snake_case("LiveKitService") = "live_kit_service"). So the server registers `live_kit_service.install`. jsonrpsee matches method names by exact, case-sensitive HashMap lookup, but every client — the generated hero_livekit_sdk, the admin dashboard.js, and cross-repo callers like hero_collab — sends the PascalCase wire name `LiveKitService.install`. No match → -32601. The old OServer lowercased the *inbound* method before dynamic dispatch, so any casing worked; hero_rpc2 hands the raw body straight to RpcModule::raw_json_request with no rewrite, and HeroOsisServer exposes no hook to register a method under the exact name a client sends. Fix: hero_livekit_server now assembles the RpcModule itself (rpc2_adapter::module_for for CRUD + the generator-native live_kit_service.* methods) and additionally registers a `LiveKitService.<method>` alias for each service-block method, forwarding to the same handle_service_call_with_context entry point under the snake_case dispatch key the generated OsisLivekit::handle_rpc arms expect. Everything else (banner, socket prep, lifted headers, service info, rpc.discover/openrpc.json, graceful shutdown) mirrors HeroOsisServer::serve() exactly. Claim-based authz is unchanged — the alias forwards through AuthorizedOsisLivekit, so privileged methods stay gated. No generated files or upstream framework code were edited; the LiveKitService.* wire contract is preserved. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>