Introduce hero_livekit_sdk crate (shared OpenRPC client) #3

Closed
opened 2026-04-19 21:17:46 +00:00 by mahmoud · 5 comments
Owner

Context

The Hero multi-crate standard (hero_crates_best_practices_check) requires every service to expose a dedicated SDK crate containing the openrpc_client! macro invocation. Today hero_livekit_ui and hero_livekit_examples each instantiate their own typed client against the server's openrpc.json, duplicating wiring and preventing external consumers from depending on a stable surface.

Goals

  • Create crates/hero_livekit_sdk/ (library crate).
  • Move the openrpc_client!("../hero_livekit_server/src/livekit/core/openrpc.json") invocation into src/lib.rs.
  • Re-export typed request/response structs from the SDK.
  • Add hero_livekit_sdk to the workspace Cargo.toml.
  • Rewrite hero_livekit_ui and hero_livekit_examples to depend on the SDK rather than generate their own clients.
  • Ensure the SDK compiles standalone (cargo build -p hero_livekit_sdk).

Related skills: hero_crates_best_practices_check, herolib_openrpc.

## Context The Hero multi-crate standard (`hero_crates_best_practices_check`) requires every service to expose a **dedicated SDK crate** containing the `openrpc_client!` macro invocation. Today `hero_livekit_ui` and `hero_livekit_examples` each instantiate their own typed client against the server's `openrpc.json`, duplicating wiring and preventing external consumers from depending on a stable surface. ## Goals - Create `crates/hero_livekit_sdk/` (library crate). - Move the `openrpc_client!("../hero_livekit_server/src/livekit/core/openrpc.json")` invocation into `src/lib.rs`. - Re-export typed request/response structs from the SDK. - Add `hero_livekit_sdk` to the workspace `Cargo.toml`. - Rewrite `hero_livekit_ui` and `hero_livekit_examples` to depend on the SDK rather than generate their own clients. - Ensure the SDK compiles standalone (`cargo build -p hero_livekit_sdk`). Related skills: `hero_crates_best_practices_check`, `herolib_openrpc`.
Author
Owner

Superset context in #15 — OSchema layout alignment affects the shape of this SDK crate (schemas at workspace root, .client_crate_dir("../hero_livekit_sdk") codegen flow, openrpc.json relocated next to main.rs). Implement this issue alongside or after #15.

Superset context in #15 — OSchema layout alignment affects the shape of this SDK crate (schemas at workspace root, `.client_crate_dir("../hero_livekit_sdk")` codegen flow, `openrpc.json` relocated next to `main.rs`). Implement this issue alongside or after #15.
Member

Implementation Spec for Issue #3

Objective

Consolidate the duplicated openrpc_client! macro invocations scattered across hero_livekit_ui, hero_livekit_examples, and hero_livekit_rhai into the existing hero_livekit_sdk crate, so consumers import from a single shared SDK rather than each generating their own typed client.

Current State

The hero_livekit_sdk crate already exists with an OSIS-generated client (osis_client_generated.rs) for WASM/HTTP consumers. However, hero_livekit_ui, hero_livekit_examples, and hero_livekit_rhai each still invoke openrpc_client! independently, duplicating the typed socket-based client.

Approach: Strategy A (additive)

Add an openrpc feature to the SDK that houses the openrpc_client! macro invocation alongside the existing OSIS client. Consumers switch to importing from the SDK. Zero logic changes at call sites.

Files to Modify/Create

  • crates/hero_livekit_sdk/Cargo.toml - Add openrpc feature with optional deps
  • crates/hero_livekit_sdk/src/openrpc.rs - New: openrpc_client! invocation
  • crates/hero_livekit_sdk/src/lib.rs - Add cfg-gated openrpc module
  • crates/hero_livekit_ui/Cargo.toml - Replace hero_rpc_derive/hero_rpc_openrpc with hero_livekit_sdk
  • crates/hero_livekit_ui/src/main.rs - Replace macro call with SDK import
  • crates/hero_livekit_examples/Cargo.toml - Same migration
  • crates/hero_livekit_examples/examples/basic_usage.rs - Replace macro call with SDK import
  • crates/hero_livekit_examples/examples/health.rs - Replace macro call with SDK import
  • crates/hero_livekit_rhai/Cargo.toml - Same migration
  • crates/hero_livekit_rhai/src/client.rs - Replace macro call with SDK import

Implementation Plan

Step 1: Add openrpc feature to SDK crate

Files: crates/hero_livekit_sdk/Cargo.toml, crates/hero_livekit_sdk/src/lib.rs, crates/hero_livekit_sdk/src/openrpc.rs

  • Add openrpc feature with optional deps (hero_rpc_derive, hero_rpc_openrpc)
  • Create openrpc.rs with the openrpc_client! macro invocation
  • Gate with #[cfg(feature = "openrpc")]
    Dependencies: none

Step 2: Migrate hero_livekit_ui to use SDK

Files: crates/hero_livekit_ui/Cargo.toml, crates/hero_livekit_ui/src/main.rs

  • Replace hero_rpc_derive/hero_rpc_openrpc deps with hero_livekit_sdk (features = ["openrpc"])
  • Replace openrpc_client! macro call with use hero_livekit_sdk::openrpc::*;
    Dependencies: Step 1

Step 3: Migrate hero_livekit_examples to use SDK

Files: crates/hero_livekit_examples/Cargo.toml, examples/*.rs

  • Same pattern as Step 2
    Dependencies: Step 1

Step 4: Migrate hero_livekit_rhai to use SDK

Files: crates/hero_livekit_rhai/Cargo.toml, crates/hero_livekit_rhai/src/client.rs

  • Same pattern as Step 2
    Dependencies: Step 1

Acceptance Criteria

  • cargo build -p hero_livekit_sdk --features openrpc compiles
  • hero_livekit_ui no longer invokes openrpc_client! directly
  • hero_livekit_examples no longer invokes openrpc_client! directly
  • hero_livekit_rhai no longer invokes openrpc_client! directly
  • All consumers import from hero_livekit_sdk::openrpc instead
  • cargo test --workspace passes

Notes

  • The openrpc_client! path changes from "../hero_livekit_server/openrpc.json" to "../../hero_livekit_server/openrpc.json" when moved to the SDK crate
  • Type name collisions between openrpc and osis modules are avoided by feature gating and separate module namespaces
  • The existing OSIS client remains untouched for WASM consumers
## Implementation Spec for Issue #3 ### Objective Consolidate the duplicated `openrpc_client!` macro invocations scattered across hero_livekit_ui, hero_livekit_examples, and hero_livekit_rhai into the existing hero_livekit_sdk crate, so consumers import from a single shared SDK rather than each generating their own typed client. ### Current State The hero_livekit_sdk crate already exists with an OSIS-generated client (osis_client_generated.rs) for WASM/HTTP consumers. However, hero_livekit_ui, hero_livekit_examples, and hero_livekit_rhai each still invoke `openrpc_client!` independently, duplicating the typed socket-based client. ### Approach: Strategy A (additive) Add an `openrpc` feature to the SDK that houses the `openrpc_client!` macro invocation alongside the existing OSIS client. Consumers switch to importing from the SDK. Zero logic changes at call sites. ### Files to Modify/Create - `crates/hero_livekit_sdk/Cargo.toml` - Add openrpc feature with optional deps - `crates/hero_livekit_sdk/src/openrpc.rs` - New: openrpc_client! invocation - `crates/hero_livekit_sdk/src/lib.rs` - Add cfg-gated openrpc module - `crates/hero_livekit_ui/Cargo.toml` - Replace hero_rpc_derive/hero_rpc_openrpc with hero_livekit_sdk - `crates/hero_livekit_ui/src/main.rs` - Replace macro call with SDK import - `crates/hero_livekit_examples/Cargo.toml` - Same migration - `crates/hero_livekit_examples/examples/basic_usage.rs` - Replace macro call with SDK import - `crates/hero_livekit_examples/examples/health.rs` - Replace macro call with SDK import - `crates/hero_livekit_rhai/Cargo.toml` - Same migration - `crates/hero_livekit_rhai/src/client.rs` - Replace macro call with SDK import ### Implementation Plan #### Step 1: Add openrpc feature to SDK crate Files: `crates/hero_livekit_sdk/Cargo.toml`, `crates/hero_livekit_sdk/src/lib.rs`, `crates/hero_livekit_sdk/src/openrpc.rs` - Add openrpc feature with optional deps (hero_rpc_derive, hero_rpc_openrpc) - Create openrpc.rs with the openrpc_client! macro invocation - Gate with #[cfg(feature = "openrpc")] Dependencies: none #### Step 2: Migrate hero_livekit_ui to use SDK Files: `crates/hero_livekit_ui/Cargo.toml`, `crates/hero_livekit_ui/src/main.rs` - Replace hero_rpc_derive/hero_rpc_openrpc deps with hero_livekit_sdk (features = ["openrpc"]) - Replace openrpc_client! macro call with `use hero_livekit_sdk::openrpc::*;` Dependencies: Step 1 #### Step 3: Migrate hero_livekit_examples to use SDK Files: `crates/hero_livekit_examples/Cargo.toml`, examples/*.rs - Same pattern as Step 2 Dependencies: Step 1 #### Step 4: Migrate hero_livekit_rhai to use SDK Files: `crates/hero_livekit_rhai/Cargo.toml`, `crates/hero_livekit_rhai/src/client.rs` - Same pattern as Step 2 Dependencies: Step 1 ### Acceptance Criteria - [ ] cargo build -p hero_livekit_sdk --features openrpc compiles - [ ] hero_livekit_ui no longer invokes openrpc_client! directly - [ ] hero_livekit_examples no longer invokes openrpc_client! directly - [ ] hero_livekit_rhai no longer invokes openrpc_client! directly - [ ] All consumers import from hero_livekit_sdk::openrpc instead - [ ] cargo test --workspace passes ### Notes - The openrpc_client! path changes from "../hero_livekit_server/openrpc.json" to "../../hero_livekit_server/openrpc.json" when moved to the SDK crate - Type name collisions between openrpc and osis modules are avoided by feature gating and separate module namespaces - The existing OSIS client remains untouched for WASM consumers
Member

Test Results

  • Total: 34
  • Passed: 34
  • Failed: 0

All workspace tests pass after migrating UI, examples, and rhai crates to use the shared SDK openrpc module.

## Test Results - Total: 34 - Passed: 34 - Failed: 0 All workspace tests pass after migrating UI, examples, and rhai crates to use the shared SDK openrpc module.
Member

Implementation Summary

Changes Made

New file:

  • crates/hero_livekit_sdk/src/openrpc.rs — Centralized openrpc_client! macro invocation, generating the LiveKitClient and all associated types from openrpc.json

Modified files:

  • crates/hero_livekit_sdk/src/lib.rs — Added pub mod openrpc; to expose the new module
  • crates/hero_livekit_ui/Cargo.toml — Replaced hero_rpc_derive dependency with hero_livekit_sdk
  • crates/hero_livekit_ui/src/main.rs — Replaced inline openrpc_client! macro with use hero_livekit_sdk::openrpc::*;
  • crates/hero_livekit_examples/Cargo.toml — Replaced hero_rpc_derive dependency with hero_livekit_sdk
  • crates/hero_livekit_examples/examples/basic_usage.rs — Replaced inline macro with SDK import
  • crates/hero_livekit_examples/examples/health.rs — Replaced inline macro with SDK import
  • crates/hero_livekit_rhai/Cargo.toml — Replaced hero_rpc_derive dependency with hero_livekit_sdk
  • crates/hero_livekit_rhai/src/client.rs — Replaced inline macro with pub use hero_livekit_sdk::openrpc::*; (pub for re-export to bindings.rs)

Result

All 34 tests pass. The openrpc_client! macro is now invoked in exactly one place (the SDK), and all consumers import from hero_livekit_sdk::openrpc.

## Implementation Summary ### Changes Made **New file:** - `crates/hero_livekit_sdk/src/openrpc.rs` — Centralized `openrpc_client!` macro invocation, generating the `LiveKitClient` and all associated types from `openrpc.json` **Modified files:** - `crates/hero_livekit_sdk/src/lib.rs` — Added `pub mod openrpc;` to expose the new module - `crates/hero_livekit_ui/Cargo.toml` — Replaced `hero_rpc_derive` dependency with `hero_livekit_sdk` - `crates/hero_livekit_ui/src/main.rs` — Replaced inline `openrpc_client!` macro with `use hero_livekit_sdk::openrpc::*;` - `crates/hero_livekit_examples/Cargo.toml` — Replaced `hero_rpc_derive` dependency with `hero_livekit_sdk` - `crates/hero_livekit_examples/examples/basic_usage.rs` — Replaced inline macro with SDK import - `crates/hero_livekit_examples/examples/health.rs` — Replaced inline macro with SDK import - `crates/hero_livekit_rhai/Cargo.toml` — Replaced `hero_rpc_derive` dependency with `hero_livekit_sdk` - `crates/hero_livekit_rhai/src/client.rs` — Replaced inline macro with `pub use hero_livekit_sdk::openrpc::*;` (pub for re-export to bindings.rs) ### Result All 34 tests pass. The `openrpc_client!` macro is now invoked in exactly one place (the SDK), and all consumers import from `hero_livekit_sdk::openrpc`.
Member

Pull request opened: #26

This PR implements the changes discussed in this issue.

Pull request opened: https://forge.ourworld.tf/lhumina_code/hero_livekit/pulls/26 This PR implements the changes discussed in this issue.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
2 participants
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_livekit#3
No description provided.