Conversation
- extract a native embedded client SDK with Rust core, FFI bindings, and test harness support - add Swift and Kotlin wrappers, packaging, smoke tests, and protocol compatibility coverage - target iOS, macOS, and Android embedded-client flows without localhost sidecars
# Conflicts: # .github/workflows/ci.yml # mesh-llm/Cargo.toml # mesh-llm/src/api/routes/mod.rs # mesh-llm/src/inference/election.rs # mesh-llm/src/inference/moe.rs # mesh-llm/src/models/catalog.rs # mesh-llm/src/network/nostr.rs # mesh-llm/src/network/proxy.rs # mesh-llm/src/plugin/transport.rs # mesh-llm/src/runtime/mod.rs
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR introduces an embedded Mesh SDK stack that allows app runtimes to embed a Mesh client directly (instead of depending on a localhost sidecar), with Rust, UniFFI, Swift, and Kotlin surfaces plus CI/smoke coverage.
Changes:
- Added new Rust crates (
mesh-client,mesh-api,mesh-api-ffi,mesh-host-core,mesh-llm-test-harness) and extracted/shared protocol/network/model logic for embedded use. - Added Swift and Kotlin SDK packaging, examples, and platform compliance artifacts (Swift privacy manifest; Android 16KB page alignment).
- Added CI smoke/fixture scripts and protocol compatibility tests to validate embedded-client paths.
Reviewed changes
Copilot reviewed 128 out of 142 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| sdk/swift/Sources/MeshLLM/EventStream.swift | Adds async streaming convenience + bridging logic for events/cancellation. |
| sdk/swift/README.md | Documents Swift SDK install/usage and App Store compliance notes. |
| sdk/swift/PrivacyInfo.xcprivacy | Adds Apple privacy manifest template for XCFramework. |
| sdk/swift/PrivacyInfo-README.md | Documents privacy manifest embedding requirements and verification. |
| sdk/swift/Package.swift | Adds SwiftPM package with optional binary XCFramework linkage. |
| sdk/swift/.gitignore | Ignores Swift build dir and generated XCFramework. |
| sdk/kotlin/src/test/kotlin/ai/meshllm/MeshClientTest.kt | Adds Kotlin unit tests for flow cancellation and event ordering. |
| sdk/kotlin/src/main/kotlin/uniffi/mesh_ffi/MeshFfi.kt | Defines Kotlin-side UniFFI DTOs and handle interfaces. |
| sdk/kotlin/src/main/kotlin/ai/meshllm/MeshClient.kt | Implements Kotlin client wrapper, DTO mapping, and Flow APIs. |
| sdk/kotlin/src/main/jniLibs/.gitignore | Ignores generated Android .so build outputs. |
| sdk/kotlin/src/main/AndroidManifest.xml | Adds minimal manifest required for AAR packaging. |
| sdk/kotlin/settings.gradle.kts | Defines Kotlin SDK Gradle root project name. |
| sdk/kotlin/scripts/verify-alignment.sh | Adds Android 16KB page-size alignment verification script. |
| sdk/kotlin/ndk-version.txt | Pins the NDK version used for native builds. |
| sdk/kotlin/gradlew | Adds Gradle wrapper script for Kotlin SDK. |
| sdk/kotlin/gradle/wrapper/gradle-wrapper.properties | Pins Gradle distribution for Kotlin SDK. |
| sdk/kotlin/example/example-jvm/src/main/kotlin/ai/meshllm/example/ExampleMain.kt | Adds JVM example app that uses JNA + Kotlin bindings. |
| sdk/kotlin/example/example-jvm/settings.gradle.kts | Defines example JVM project name. |
| sdk/kotlin/example/example-jvm/gradlew | Adds Gradle wrapper to the JVM example subproject. |
| sdk/kotlin/example/example-jvm/gradle/wrapper/gradle-wrapper.properties | Pins Gradle for the JVM example. |
| sdk/kotlin/example/example-jvm/build.gradle.kts | Configures Kotlin/JVM example build + sourceset wiring. |
| sdk/kotlin/consumer-proguard-rules.pro | Adds keep rules for consumer minification. |
| sdk/kotlin/build.gradle.kts | Adds Kotlin SDK build + native .so build task + AAR assembly. |
| sdk/kotlin/.gitignore | Ignores Gradle metadata and build outputs. |
| sdk/README.md | Documents multi-language SDK directory structure and layering. |
| scripts/ci-swift-sdk-smoke.sh | Adds Swift SDK smoke test runner script. |
| scripts/ci-sdk-fixture.sh | Adds shared CI fixture to stand up a real served model and export env. |
| scripts/ci-native-sdk-smoke.sh | Adds Rust FFI live smoke runner using the shared fixture. |
| scripts/ci-kotlin-sdk-smoke.sh | Adds Kotlin JVM example smoke runner using the shared fixture. |
| mesh-llm/tests/protocol_convert_matrix.rs | Adds protocol conversion/validation matrix tests against extracted protocol API. |
| mesh-llm/tests/protocol_compat_v0_client.rs | Adds ALPN/protocol-compat coverage for v0/v1 negotiation semantics. |
| mesh-llm/src/plugins/blackboard/mod.rs | Exposes is_enabled() accessor for blackboard plugin state. |
| mesh-llm/src/plugins/blackboard/mcp.rs | Adds dead-code allowances and MCP stdio server runner wiring. |
| mesh-llm/src/plugin/mod.rs | Adds constant for blackboard capability with dead-code allowance. |
| mesh-llm/src/models/topology.rs | Re-exports topology types from mesh-client and keeps helper inference fns. |
| mesh-llm/src/mesh/mod.rs | Re-exports extracted mesh/model descriptor logic from mesh-client. |
| mesh-llm/src/api/assets.rs | Switches console asset embedding to build-time env-selected include path. |
| mesh-llm/docs/JAN_MESH_API_INTEGRATION.md | Adds Jan integration contract doc for embedded mesh-api. |
| mesh-llm/docs/EMBEDDED_CLIENT_ADR.md | Adds ADR capturing embedded SDK design/tooling/compat guarantees. |
| mesh-llm/build.rs | Sets MESH_LLM_CONSOLE_DIST env to real or fallback console dist dir. |
| mesh-llm/Cargo.toml | Depends on extracted mesh-client (host-io) and adds dev-dep for tests. |
| mesh-llm-test-harness/tests/fixture.rs | Adds (ignored) fixture test skeleton for harness validation. |
| mesh-llm-test-harness/src/lib.rs | Implements FixtureMesh launcher to get a real invite token. |
| mesh-llm-test-harness/Cargo.toml | Adds harness crate deps (reqwest blocking + serde_json + thiserror). |
| mesh-host-core/src/lib.rs | Adds placeholder crate for host-side core. |
| mesh-host-core/Cargo.toml | Adds host-core crate manifest and feature skeleton. |
| mesh-client/tests/tunnel_relay.rs | Adds tunnel relay transfer test using mock transport IO. |
| mesh-client/tests/transport_mock.rs | Adds mock transport IO behavior tests. |
| mesh-client/tests/runtime_thread_leak.rs | Adds runtime thread-leak and shutdown behavior tests. |
| mesh-client/tests/reconnect_manual.rs | Adds reconnect/disconnect behavior tests (manual semantics). |
| mesh-client/tests/reconnect_automatic.rs | Adds reconnect attempt-cap and disconnect flag tests. |
| mesh-client/tests/public_api.rs | Adds compile-time public API shape checks. |
| mesh-client/tests/protocol_wire.rs | Adds extracted protocol wire-format tests and invariants. |
| mesh-client/tests/nostr_discovery.rs | Adds discovery scoring/filtering tests for extracted nostr logic. |
| mesh-client/tests/network_router_extraction.rs | Adds tests for router classification/complexity helpers. |
| mesh-client/tests/network_rewrite_extraction.rs | Adds tests for port rewrite map behavior. |
| mesh-client/tests/network_affinity_extraction.rs | Adds tests for affinity routing behavior. |
| mesh-client/tests/moe_ranking.rs | Adds tests for MoE ranking assignment and artifact behaviors. |
| mesh-client/tests/models_extraction.rs | Adds tests for catalog/capabilities/GGUF parsing extraction. |
| mesh-client/tests/mesh_types.rs | Adds tests for mesh/model descriptor types and demand merge semantics. |
| mesh-client/tests/mesh_client_api.rs | Adds tests for join/status/disconnect/cancel/list/chat/responses API surface. |
| mesh-client/tests/key_provider.rs | Adds tests for in-memory key provider round-trip behavior. |
| mesh-client/tests/http_parse_test.rs | Adds tests for minimal HTTP request parsing helpers. |
| mesh-client/tests/events.rs | Adds tests that all event variants are emit-capable. |
| mesh-client/tests/election_extraction.rs | Adds tests for extracted election helpers (bytes sizing + no-peers host). |
| mesh-client/tests/crypto_envelope.rs | Adds tests for message seal/open and keypair bytes round-trip. |
| mesh-client/tests/cancel_idempotent.rs | Adds tests that cancel is a no-op for unknown/completed IDs. |
| mesh-client/tests/cancel_active.rs | Adds test that canceling active request emits failed/cancelled. |
| mesh-client/src/runtime.rs | Implements a dedicated-thread Tokio runtime wrapper for embedded safety. |
| mesh-client/src/protocol/v0.rs | Implements legacy v0 tunnel-map JSON decode in mesh-client. |
| mesh-client/src/protocol/convert.rs | Implements canonical config hashing for protocol snapshots. |
| mesh-client/src/network/tunnel.rs | Adds abstract relay logic over generic transport IO. |
| mesh-client/src/network/transport_iroh.rs | Adds TransportIo adapter for iroh bi-streams. |
| mesh-client/src/network/transport.rs | Defines TransportIo trait and in-memory mock implementation. |
| mesh-client/src/network/rewrite.rs | Adds QUIC→TCP register-peer endpoint rewrite logic. |
| mesh-client/src/network/mod.rs | Wires up extracted network modules. |
| mesh-client/src/models/topology.rs | Adds topology model types in mesh-client. |
| mesh-client/src/models/mod.rs | Exposes models modules and re-exports topology types. |
| mesh-client/src/models/catalog.rs | Adds embedded model catalog parsing and helper APIs. |
| mesh-client/src/mesh/mod.rs | Exposes extracted mesh types module. |
| mesh-client/src/lib.rs | Defines mesh-client crate public modules and key re-exports. |
| mesh-client/src/inference/mod.rs | Wires inference modules (election + moe). |
| mesh-client/src/inference/election.rs | Adds extracted inference target types + selection helpers. |
| mesh-client/src/events.rs | Adds client event enum + listener trait. |
| mesh-client/src/crypto/provider.rs | Adds key provider trait + in-memory provider. |
| mesh-client/src/crypto/mod.rs | Wires crypto modules and re-exports. |
| mesh-client/src/crypto/keys.rs | Adds embedded-safe owner keypair generation/serialization. |
| mesh-client/src/crypto/error.rs | Adds crypto error enum. |
| mesh-client/src/client/mod.rs | Wires client builder module exports. |
| mesh-client/proto/node.proto | Adds portable protobuf schema for node control-plane types. |
| mesh-client/build.rs | Builds protobuf definitions for mesh-client. |
| mesh-client/README.md | Documents purpose/scope/layering of mesh-client crate. |
| mesh-client/Cargo.toml | Adds mesh-client dependencies and build tooling. |
| mesh-api/tests/public_api.rs | Adds mesh-api compile-time API shape checks. |
| mesh-api/src/token.rs | Adds InviteToken wrapper and parsing boundary around mesh-client token type. |
| mesh-api/src/lib.rs | Exposes mesh-api public surface and re-exports. |
| mesh-api/src/identity.rs | Adds OwnerKeypair wrapper and byte import/export helpers. |
| mesh-api/src/events.rs | Adds mesh-api event surface and listener trait. |
| mesh-api/src/client.rs | Implements public MeshClient wrapper + adapter mapping to mesh-client. |
| mesh-api/README.md | Documents mesh-api role as the public Rust SDK surface. |
| mesh-api/Cargo.toml | Adds mesh-api manifest and feature passthrough. |
| mesh-api-ffi/tests/smoke.rs | Adds basic ffi surface tests and placeholders for fixture-driven live smoke. |
| mesh-api-ffi/tests/live_sdk_smoke.rs | Adds live mesh smoke test driven via CI fixture env vars. |
| mesh-api-ffi/tests/error_mapping.rs | Adds tests enforcing ffi error mapping surface. |
| mesh-api-ffi/tests/client_exports_compile.rs | Adds compile-time checks for exported FFI surface. |
| mesh-api-ffi/src/mesh_ffi.udl | Defines UniFFI UDL surface for embedded client handle and DTOs. |
| mesh-api-ffi/src/lib.rs | Implements UniFFI exports, DTO mapping, and sync wrappers via pollster. |
| mesh-api-ffi/build.rs | Generates UniFFI scaffolding at build time. |
| mesh-api-ffi/README.md | Documents purpose/layout of mesh-api-ffi crate. |
| mesh-api-ffi/Cargo.toml | Adds UniFFI crate config and feature skeleton. |
| Cargo.toml | Adds new crates to workspace members. |
| CONTRIBUTING.md | Adds protocol backward-compat guidance and local test commands. |
| .github/workflows/ci.yml | Adds embedded dependency purity checks and SDK smoke CI jobs. |
| .cargo/config.toml | Adds Android 16KB page alignment linker flags for relevant targets. |
# Conflicts: # mesh-llm/src/mesh/mod.rs
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds an embedded SDK stack (Rust mesh-api, UniFFI bridge, Swift/Kotlin packages) so app runtimes can embed a Mesh client directly (no localhost sidecar), plus CI/smoke coverage and protocol-compat tests.
Changes:
- Introduces new Rust crates:
mesh-client(core),mesh-api(public SDK),mesh-api-ffi(UniFFI),mesh-host-core(placeholder), andmesh-llm-test-harness. - Adds Swift + Kotlin SDK packaging (SwiftPM + Kotlin AAR/JVM example) and CI scripts for native/Kotlin/Swift smoke runs.
- Adds protocol compatibility test suites and CI checks for embedded-client dependency purity + Android 16KB page alignment flags.
Reviewed changes
Copilot reviewed 129 out of 144 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| sdk/swift/Sources/MeshLLM/EventStream.swift | Swift async stream bridging for event streaming + cancellation behavior. |
| sdk/swift/README.md | Swift SDK installation/usage + App Store compliance notes. |
| sdk/swift/PrivacyInfo.xcprivacy | Apple privacy manifest template for XCFramework embedding. |
| sdk/swift/PrivacyInfo-README.md | Documentation for embedding/verifying privacy manifest in the XCFramework. |
| sdk/swift/Package.swift | SwiftPM package definition with optional UniFFI XCFramework binary target. |
| sdk/swift/.gitignore | Ignores Swift build artifacts and generated XCFramework. |
| sdk/kotlin/src/test/kotlin/ai/meshllm/MeshClientTest.kt | Kotlin unit tests validating flow ordering and cancellation behavior. |
| sdk/kotlin/src/main/kotlin/uniffi/mesh_ffi/MeshFfi.kt | Kotlin-side UniFFI DTOs/interfaces used by the Kotlin SDK layer. |
| sdk/kotlin/src/main/kotlin/ai/meshllm/MeshClient.kt | Kotlin SDK client wrapper + Flow-based streaming helpers. |
| sdk/kotlin/src/main/jniLibs/.gitignore | Ignores generated Android .so artifacts in source tree. |
| sdk/kotlin/src/main/AndroidManifest.xml | Minimal manifest required for AAR packaging. |
| sdk/kotlin/settings.gradle.kts | Kotlin SDK Gradle project naming. |
| sdk/kotlin/scripts/verify-alignment.sh | Script to verify Android 16KB LOAD segment alignment in .so. |
| sdk/kotlin/ndk-version.txt | NDK version pin for reproducible Android native builds. |
| sdk/kotlin/gradlew | Gradle wrapper script for Kotlin SDK project. |
| sdk/kotlin/gradle/wrapper/gradle-wrapper.properties | Gradle wrapper distribution pin for Kotlin SDK project. |
| sdk/kotlin/example/example-jvm/src/main/kotlin/ai/meshllm/example/ExampleMain.kt | JVM example app showing Kotlin SDK usage via JNA + generated bindings. |
| sdk/kotlin/example/example-jvm/settings.gradle.kts | JVM example Gradle project naming. |
| sdk/kotlin/example/example-jvm/gradlew | Gradle wrapper script for JVM example. |
| sdk/kotlin/example/example-jvm/gradle/wrapper/gradle-wrapper.properties | Gradle wrapper pin for JVM example. |
| sdk/kotlin/example/example-jvm/build.gradle.kts | JVM example build config + dependency and sourceSets wiring. |
| sdk/kotlin/consumer-proguard-rules.pro | Consumer ProGuard rules for Android AAR consumers. |
| sdk/kotlin/build.gradle.kts | Kotlin SDK build: native .so build task + custom AAR assembly. |
| sdk/kotlin/.gitignore | Ignores Gradle caches/build outputs for Kotlin SDK. |
| sdk/README.md | Top-level SDK directory overview + layering guidance. |
| scripts/ci-swift-sdk-smoke.sh | CI script to build Swift XCFramework and run Swift SDK smoke test. |
| scripts/ci-sdk-fixture.sh | Shared CI fixture to run a real served model + export env for SDK tests. |
| scripts/ci-native-sdk-smoke.sh | CI script to run Rust/FFI live SDK smoke test against fixture. |
| scripts/ci-kotlin-sdk-smoke.sh | CI script to run Kotlin JVM example against live fixture. |
| mesh-llm/tests/protocol_convert_matrix.rs | Protocol conversion matrix tests against mesh-client::protocol. |
| mesh-llm/tests/protocol_compat_v0_client.rs | ALPN + v0/v1 compatibility tests against public protocol API. |
| mesh-llm/src/plugins/blackboard/mod.rs | Adds is_enabled() accessor to blackboard store. |
| mesh-llm/src/plugins/blackboard/mcp.rs | MCP server wiring improvements + stdio transport entrypoint. |
| mesh-llm/src/plugin/mod.rs | Adds a blackboard capability constant (currently dead-code allowed). |
| mesh-llm/src/models/topology.rs | Switches topology types to re-export from mesh-client. |
| mesh-llm/src/mesh/mod.rs | Re-exports shared mesh types from mesh-client and trims duplicated defs. |
| mesh-llm/src/mesh/gossip.rs | Removes local merge_demand in favor of shared mesh-client version. |
| mesh-llm/src/api/assets.rs | Makes console asset embedding path configurable via build-time env var. |
| mesh-llm/docs/JAN_MESH_API_INTEGRATION.md | Integration contract doc for embedding mesh-api in Jan (Tauri). |
| mesh-llm/docs/EMBEDDED_CLIENT_ADR.md | ADR defining embedded SDK architecture + constraints + compatibility policy. |
| mesh-llm/build.rs | Sets MESH_LLM_CONSOLE_DIST env and provides fallback when UI dist absent. |
| mesh-llm/Cargo.toml | Adds mesh-client dependency (host-io) + dev-dep for tests. |
| mesh-llm-test-harness/tests/fixture.rs | Adds initial (ignored) test harness coverage. |
| mesh-llm-test-harness/src/lib.rs | Implements a fixture runner that spawns mesh-llm and polls /api/status. |
| mesh-llm-test-harness/Cargo.toml | New crate config for the harness (blocking reqwest + serde_json). |
| mesh-host-core/src/lib.rs | Placeholder crate for future host-core extraction. |
| mesh-host-core/Cargo.toml | New crate stub + feature scaffolding. |
| mesh-client/tests/tunnel_relay.rs | Tests for abstract tunnel relay copying bytes across transport IO. |
| mesh-client/tests/transport_mock.rs | Tests for the mock transport implementation. |
| mesh-client/tests/runtime_thread_leak.rs | Tests runtime drop behavior and thread leak prevention. |
| mesh-client/tests/reconnect_manual.rs | Tests manual reconnect/disconnect event emission semantics. |
| mesh-client/tests/reconnect_automatic.rs | Tests reconnect counters/flags + max attempts constant. |
| mesh-client/tests/public_api.rs | Compile-time public API shape tests for mesh-client. |
| mesh-client/tests/protocol_wire.rs | Wire/protocol integration tests for ALPN + frame (de)serialization. |
| mesh-client/tests/nostr_discovery.rs | Tests for Nostr discovery scoring/filtering logic. |
| mesh-client/tests/network_router_extraction.rs | Tests for request classification + split-suffix stripping. |
| mesh-client/tests/network_rewrite_extraction.rs | Tests for PortRewriteMap creation and behavior. |
| mesh-client/tests/network_affinity_extraction.rs | Tests for sticky affinity routing behavior. |
| mesh-client/tests/moe_ranking.rs | Tests for MoE ranking/assignment algorithms + cached artifact utilities. |
| mesh-client/tests/models_extraction.rs | Tests for model catalog and minimal GGUF parsing behavior. |
| mesh-client/tests/mesh_types.rs | Tests for shared mesh types + demand merge + descriptor inference behavior. |
| mesh-client/tests/mesh_client_api.rs | Tests for high-level client lifecycle methods + request id generation. |
| mesh-client/tests/key_provider.rs | Tests for in-memory key provider behavior. |
| mesh-client/tests/http_parse_test.rs | Tests for HTTP parsing utilities used in proxy/relay paths. |
| mesh-client/tests/events.rs | Tests for event types and listener emission. |
| mesh-client/tests/election_extraction.rs | Tests for election helpers + file size accounting. |
| mesh-client/tests/crypto_envelope.rs | Tests for crypto envelope seal/open and keypair byte roundtrip. |
| mesh-client/tests/cancel_idempotent.rs | Tests cancel behavior on unknown/completed request IDs. |
| mesh-client/tests/cancel_active.rs | Tests cancel behavior emits a failed/cancelled event. |
| mesh-client/src/runtime.rs | Dedicated-thread Tokio runtime implementation for embedded safety. |
| mesh-client/src/protocol/v0.rs | Legacy JSON tunnel-map decode for v0 protocol compatibility. |
| mesh-client/src/protocol/convert.rs | Canonical config hashing for protocol conversion/validation. |
| mesh-client/src/network/tunnel.rs | Abstract relay trait + generic byte relay function over TransportIo. |
| mesh-client/src/network/transport_iroh.rs | TransportIo adapter for iroh bi-streams. |
| mesh-client/src/network/transport.rs | Core TransportIo trait + in-memory mock implementation. |
| mesh-client/src/network/rewrite.rs | REGISTER_PEER relay rewrite logic for orchestrator port mappings. |
| mesh-client/src/network/mod.rs | Exposes network modules for embedded client core. |
| mesh-client/src/models/topology.rs | Shared model topology DTOs (serde) used across client/host. |
| mesh-client/src/models/mod.rs | Models module exports and re-exports. |
| mesh-client/src/models/catalog.rs | Bundled model catalog loader + helpers for HF resolve URL parsing. |
| mesh-client/src/mesh/mod.rs | Mesh module surface re-export. |
| mesh-client/src/lib.rs | mesh-client crate root + public exports. |
| mesh-client/src/inference/mod.rs | Inference module manifest. |
| mesh-client/src/inference/election.rs | Election/routing types and helper(s) extracted for embedded core. |
| mesh-client/src/events.rs | Embedded-client event types + listener trait. |
| mesh-client/src/crypto/provider.rs | Key provider trait + in-memory provider implementation. |
| mesh-client/src/crypto/mod.rs | Crypto module exports wiring. |
| mesh-client/src/crypto/keys.rs | Owner keypair implementation + owner-id derivation. |
| mesh-client/src/crypto/error.rs | Crypto error type definitions. |
| mesh-client/src/client/mod.rs | Client module exports wiring. |
| mesh-client/proto/node.proto | Extracted protobuf schema for node protocol v1 control plane. |
| mesh-client/build.rs | Builds protobuf definitions with vendored protoc. |
| mesh-client/README.md | Crate purpose + layering guidance for mesh-client. |
| mesh-client/Cargo.toml | New crate dependencies/features for embedded client core. |
| mesh-api/tests/public_api.rs | Compile-time public API shape tests for mesh-api. |
| mesh-api/src/token.rs | Public InviteToken newtype bridging to mesh-client. |
| mesh-api/src/lib.rs | mesh-api crate root exports. |
| mesh-api/src/identity.rs | Public OwnerKeypair wrapper + hex serialization. |
| mesh-api/src/events.rs | Public mesh-api event types and listener trait. |
| mesh-api/src/client.rs | Public SDK ClientBuilder + MeshClient surface wrapping mesh-client. |
| mesh-api/README.md | Crate purpose + guidance for Rust consumers. |
| mesh-api/Cargo.toml | New crate dependencies/features. |
| mesh-api-ffi/tests/smoke.rs | Unit tests for FFI handle creation, status, cancel, and event bridging. |
| mesh-api-ffi/tests/live_sdk_smoke.rs | Live smoke test against a real served model via CI fixture. |
| mesh-api-ffi/tests/error_mapping.rs | Tests for FFI error mapping + exported error trait assertions. |
| mesh-api-ffi/tests/client_exports_compile.rs | Compile-time tests ensuring exports and listener types are usable. |
| mesh-api-ffi/src/mesh_ffi.udl | UniFFI UDL defining exported client handle surface and DTOs. |
| mesh-api-ffi/src/lib.rs | UniFFI Rust implementation for MeshClientHandle and type mappings. |
| mesh-api-ffi/build.rs | UniFFI scaffolding generation configuration. |
| mesh-api-ffi/README.md | Crate purpose + layering guidance for bindings. |
| mesh-api-ffi/Cargo.toml | Crate config for UniFFI packaging + optional host feature. |
| Cargo.toml | Adds new SDK crates to the workspace members list. |
| CONTRIBUTING.md | Documents protocol backward-compatibility testing requirements. |
| .github/workflows/ci.yml | Adds embedded-client purity check + protocol matrix tests + SDK smoke jobs. |
| .cargo/config.toml | Adds Android linker flags for 16KB page-size alignment across targets. |
|
@copilot apply changes based on the comments in this thread |
Agent-Logs-Url: https://github.com/Mesh-LLM/mesh-llm/sessions/d895bb28-e2a9-45da-8b17-15337070ba8d Co-authored-by: i386 <50156+i386@users.noreply.github.com>
|
@copilot resolve the merge conflicts in this pull request |
# Conflicts: # Cargo.toml # mesh-llm/src/models/capabilities.rs
|
So far it looks like we have a good portion of this already working, but we haven't reached the embedded SDK boundary yet. The overall structure of the branch looks right as far as I can tell:
On the Rust side, everything I checked builds and tests cleanly. The Swift path is also usable locally. The XCFramework builds, a Swift exemplar project builds and runs, and the example and CI flow look like they can exercise a real request when the fixture environment is set up as expected. The live smoke fixture works in bridged mode as well. CI and the native smoke setup can start mesh-llm, discover a model, send a request, and stream a completion through the SDK stack. As it stands, this branch already functions as a prototype native client for interacting with a local Mesh-LLM API backed runtime, and that part is solid. Remaining workstreams
|
# Conflicts: # Cargo.lock # mesh-llm/src/mesh/mod.rs # mesh-llm/src/models/capabilities.rs # mesh-llm/src/models/topology.rs
|
Reviewed this — direction looks good and it's mostly additive, so low risk to existing mesh behavior. Two things worth raising before merge: Proto duplication looks unintentional
The two copies have already drifted:
Fix is structural rather than a resync: point both crates at a single Kotlin AAR ships stub bindings, not the real ones
Everything else (forked router/nostr/affinity copies in |
* main: fix: remove unintended PR job from 307 v0.62.1: release add test job to check CI fix(cuda): remove compute_103 from supported platforms
| if grep -wE "^\s*($FORBIDDEN)" /tmp/mesh-client-deps.txt; then | ||
| echo "ERROR: Forbidden dependency found in mesh-client" | ||
| grep -wE "^\s*($FORBIDDEN)" /tmp/mesh-client-deps.txt |
| tasks.named("assembleAar") { | ||
| dependsOn(buildNativeLibs) | ||
| } |
| } | ||
| } | ||
|
|
||
| #if canImport(mesh_ffiFFI) |
| private func cancelIfNeeded() { | ||
| stateLock.lock() | ||
| guard !finished else { | ||
| stateLock.unlock() | ||
| return | ||
| } | ||
| let requestId = self.requestId | ||
| stateLock.unlock() | ||
|
|
||
| guard let requestId else { | ||
| return | ||
| } | ||
| onCancel(requestId) | ||
| } |
|
|
||
| impl Drop for FixtureMesh { | ||
| fn drop(&mut self) { | ||
| // Send SIGTERM, wait up to 5s, then SIGKILL |
| swift_sdk_smoke: | ||
| needs: [changes, inference_smoke_tests] | ||
| if: ${{ needs.inference_smoke_tests.result == 'success' && (github.event_name == 'workflow_dispatch' || needs.changes.outputs.rust == 'true' || needs.changes.outputs.ui == 'true') }} | ||
| runs-on: macos-latest |
mesh-client previously carried its own copy of node.proto that had diverged from mesh-llm's: it added owner_id filter fields on the config messages (ConfigSubscribe, ConfigSnapshotResponse, ConfigUpdateNotification, ConfigPush) but was missing the hardware gossip additions (HardwareInfo, GpuInfo), attested-identity work (SignedNodeOwnership), and pinned-GPU model fields that landed on main after mesh-client forked. The two files also collided on PeerAnnouncement field 28: mesh-llm → SignedNodeOwnership owner_attestation mesh-client → string owner_id This keeps mesh-llm/proto/node.proto as the canonical schema (since it matches the deployed mesh) and ports the owner_id additions into it at their original tag numbers — those tags happened to be free in mesh-llm's version so no renumbering was required. Field 28 stays as owner_attestation, matching production. mesh-client/build.rs now compiles ../mesh-llm/proto/node.proto and mesh-client/proto/ is removed, so the workspace has one schema. Call sites updated to populate the new owner_id field: - mesh-llm/src/mesh/mod.rs: empty string for error/outgoing paths, local_owner_id or snapshot.owner_id where meaningful - test code in mesh/tests.rs and protocol/mod.rs - tests/protocol_convert_matrix.rs: also needed the NodeModelEntry pinned-GPU fields (the other direction of the divergence) Validated: - cargo check --workspace: clean - cargo test -p mesh-client: 83 lib + 188 integration pass - cargo test -p mesh-llm --lib: 875 pass, 0 fail - cargo test --test protocol_compat_v0_client --test protocol_convert_matrix: 11 pass - cargo fmt --all -- --check: clean
…ating Previously, passing an empty owner_keypair_bytes_hex to create_client would silently call OwnerKeypair::generate() and produce a brand-new identity. This is a footgun: a Swift/Kotlin app that fails to load its persisted keypair (missing file, keychain miss, etc.) would get a fresh identity every launch with no error surfaced to the caller. Now an empty or whitespace-only keypair hex returns FfiError::InvalidOwnerKeypair. Callers that genuinely want a new identity should create one explicitly via OwnerKeypair::generate() and pass its hex representation. Updated existing smoke tests that passed "" as a placeholder to use a generated keypair, and added a test that pins the new empty-input rejection behavior. Addresses GitHub Copilot review feedback on PR #233.
| let handle = create_client(String::new(), invite_token).expect("create_client"); | ||
| handle.join().expect("join"); |
| /// Old peers advertising only `mesh-llm/0` must be accepted with the JSON codec. | ||
| #[test] | ||
| fn protocol_from_alpn_v0_yields_json_v0() { | ||
| assert_eq!(protocol_from_alpn(ALPN_V0), ControlProtocol::JsonV0); | ||
| } |
| if grep -wE "^\s*($FORBIDDEN)" /tmp/mesh-client-deps.txt; then | ||
| echo "ERROR: Forbidden dependency found in mesh-client" | ||
| grep -wE "^\s*($FORBIDDEN)" /tmp/mesh-client-deps.txt |
| `mesh-client` has a strict dependency allowlist. Only these 18 crates are permitted: | ||
|
|
||
| `iroh`, `tokio`, `prost`, `bytes`, `rustls`, `quinn`, `serde`, `serde_json`, `thiserror`, `anyhow`, `tracing`, `sha2`, `ed25519-dalek`, `hex`, `uuid`, `url`, `http`, `base64` |
| pub fn reconnect(&mut self) -> Result<(), MeshError>; | ||
| } |
| private func cancelIfNeeded() { | ||
| stateLock.lock() | ||
| guard !finished else { | ||
| stateLock.unlock() | ||
| return | ||
| } | ||
| let requestId = self.requestId | ||
| stateLock.unlock() | ||
|
|
||
| guard let requestId else { | ||
| return | ||
| } | ||
| onCancel(requestId) | ||
| } |
| let client = ClientBuilder::new(kp, token) | ||
| .build() | ||
| .map_err(|_| FfiError::JoinFailed)?; |
The earlier commit to reject empty owner keypairs in create_client broke three live smoke paths that relied on passing "" to get an auto-generated keypair: - mesh-api-ffi/tests/live_sdk_smoke.rs: native SDK smoke - sdk/kotlin/example/example-jvm: Kotlin SDK smoke - sdk/swift/example/MeshExampleApp + Swift tests: Swift SDK smoke Add a new FFI function, generate_owner_keypair_hex(), that callers use to mint a keypair explicitly on first run and persist across launches. All four example/test call sites now generate an explicit keypair and pass it to create_client. Also: - Regenerate committed Swift bindings (mesh_ffi.swift, mesh_ffiFFI.h) via sdk/swift/scripts/generate-swift-bindings.sh so they expose the new function. - Add sdk/kotlin/scripts/generate-kotlin-bindings.sh — the Kotlin side previously had no regeneration script. The library source set also carried a hand-written stub (MeshFfi.kt, 67 lines) that shadowed the real bindings; delete it and ship the generated mesh_ffi.kt in both the library and the example source sets, keeping them in lockstep. Verified locally: - cargo check --workspace: clean - cargo fmt --all -- --check: clean - cargo test -p mesh-api-ffi --test smoke: 9 passed (1 ignored) - cargo test -p mesh-client: 83 lib + 188 integration pass
swift_sdk_smoke was cloning upstream-latest from a personal fork
(michaelneale/llama.cpp), while every other CI job builds from the
org fork (Mesh-LLM/llama.cpp) pinned to LLAMA_CPP_SHA. The personal
fork's branch lacks the --mesh-port patch mesh-llm now passes to
llama-server, so swift_sdk_smoke was failing with:
error: invalid argument: --mesh-port
Use the same clone-and-checkout recipe the Linux/CUDA/ROCm/Vulkan
jobs use, so Swift builds the same llama.cpp binary as everything
else.
| tasks.named("assembleAar") { | ||
| dependsOn(buildNativeLibs) | ||
| } |
| val assembleAar by tasks.registering(Zip::class) { | ||
| description = "Assemble AAR artifact with native libs and consumer ProGuard rules" | ||
| group = "build" |
|
|
||
| if [ ! -x "$BINDGEN" ]; then | ||
| echo "Installing uniffi-bindgen 0.31.0 into $BINDGEN_ROOT ..." | ||
| cargo install uniffi --version =0.31.0 --features cli --bin uniffi-bindgen \ |
| @JvmInline | ||
| value class RequestId(val value: String) |
| data class TokenDelta(val requestId: String, val delta: String) : Event() | ||
| data class Completed(val requestId: String) : Event() | ||
| data class Failed(val requestId: String, val error: String) : Event() |
| val requestId = chat(request) { event -> trySend(event) } | ||
| awaitClose { cancel(requestId) } | ||
| } | ||
|
|
||
| fun responsesFlow(request: ResponsesRequest): Flow<Event> = callbackFlow { | ||
| val requestId = responses(request) { event -> trySend(event) } | ||
| awaitClose { cancel(requestId) } |
| #[uniffi::export] | ||
| pub fn create_client( | ||
| owner_keypair_bytes_hex: String, | ||
| invite_token: String, | ||
| ) -> Result<Arc<MeshClientHandle>, FfiError> { | ||
| let token = invite_token | ||
| .parse::<InviteToken>() | ||
| .map_err(|_| FfiError::InvalidInviteToken)?; |
| let kp = OwnerKeypair::from_hex(trimmed).map_err(|_| FfiError::InvalidOwnerKeypair)?; | ||
| let client = ClientBuilder::new(kp, token) | ||
| .build() | ||
| .map_err(|_| FfiError::JoinFailed)?; |
| pub fn join(&self) -> Result<(), FfiError> { | ||
| let mut client = self.inner.lock().unwrap(); | ||
| block_on(client.join()).map_err(|_| FfiError::JoinFailed) | ||
| } | ||
|
|
||
| pub fn list_models(&self) -> Result<Vec<ModelDto>, FfiError> { | ||
| let client = self.inner.lock().unwrap(); | ||
| let models = block_on(client.list_models()).map_err(|_| FfiError::DiscoveryFailed)?; |
* origin/main: bump llama.cpp to e88186e78777 Normalize MoE share refs for split GGUFs refactor(ui): share resolved theme hook across topology and mermaid feat: Implement light mode for topology diagram
This branch adds an embedded Mesh SDK stack for app integrations.
After this change, app runtimes can embed a Mesh client directly instead of treating Mesh as a localhost-only sidecar. The branch introduces a public Rust SDK surface, a UniFFI layer for native bindings, and native Swift and Kotlin packages built on top of the same client core.
This branch also adds CI coverage for the embedded client path, so SDK consumers are validated against a real served model rather than only through the CLI and server workflows.
Closes #188
Architecture
The branch defines the embedded SDK layering explicitly:
mesh-clientis the internal client implementation crate.mesh-apiis the public Rust SDK for app integrations such as Jan.mesh-api-ffiis the UniFFI/native bindings layer.mesh-api-ffi.That gives the repo one shared client core with separate product-facing surfaces for Rust and native mobile/desktop consumers.
Protocol
This branch is not intended to introduce a breaking mesh protocol change.
Validation
Validated locally:
cargo test -p mesh-llm --test protocol_compat_v0_clientcargo test -p mesh-llm --test protocol_convert_matrixscripts/ci-native-sdk-smoke.sh target/debug/mesh-llm llama.cpp/build/bin ~/.models/SmolLM2-135M-Instruct-Q8_0.ggufscripts/ci-kotlin-sdk-smoke.sh target/debug/mesh-llm llama.cpp/build/bin ~/.models/SmolLM2-135M-Instruct-Q8_0.ggufscripts/ci-swift-sdk-smoke.sh target/debug/mesh-llm llama.cpp/build/bin ~/.models/SmolLM2-135M-Instruct-Q8_0.ggufCI notes:
native_sdk_smokeandkotlin_sdk_smokerun afterinference_smoke_tests.macoslane is documented as a Linux cross-build lane and does not require a macOS runner.swift_sdk_smokeis intentionally disabled until a Swift execution runner is available.