Skip to content
tryAGIPublic

About

C# SDK for the Muse Gadget API -- experimental backend-only encrypted transport, device API, and streamed text

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

Muse

Build NuGet

Experimental .NET 10 network SDK for Muse Gadgets. Runs inside your backend process: no gadget, Bluetooth, desktop worker, Python service, or Advantage dependency is required by the library.

Account bootstrap is not implemented or proven. A Gadget SDK token (mgst_...) identifies the integration; it is not a device access token, refresh token, or VM bearer. The bounded live SDK-token-only probe returned HTTP 401 from /fetch_vms on 2026-10-05. No live Muse conversation or real token rotation has passed yet. Local interoperability results must not be interpreted as provider E2E.

See account availability and live validation for dated official regional statements, missing credential roles, and the remaining completion criteria.

What is implemented

Layer Support
Device HTTP API VM discovery and token-refresh contracts generated with AutoSDK
VM transport TLS/WebSocket, Noise XX, bounded protobuf framing and multiplexed request streams
Request lifecycle Fragmentation, streaming upload, half-close, cancellation and explicit failures
Logical link Registration without executable commands; unexpected invocations are denied
Chat Explicit side-chat text submission and a separate bounded raw NDJSON subscription
Compatibility Independent upstream protocol oracle and a running NativeAOT network smoke
Initial account authorization Unverified; no invented login endpoint or SDK-token exchange
Voice, UI, MEAI, tools Not implemented; no hidden speech billing or command execution

The OpenAPI document is community-maintained from pinned public source evidence, not an official Muse OpenAPI publication. AutoSDK generates the HTTP layer; the encrypted transport is independently authored C#. See protocol and dependency provenance and the validation report.

Installation

dotnet add package tryAGI.Muse --prerelease

Until a prerelease is available, build src/libs/Muse/Muse.csproj from this repository. Only .NET 10 is targeted. Consumer runtime dependencies are platform-only; generation, build, test and oracle tooling have separately documented dependencies. The managed X25519 implementation has vector/interoperability coverage, not an independent cryptographic audit or a JIT constant-time guarantee.

Device API

using Muse;

// Obtain this through an authorized user/device flow, not from an SDK token.
var deviceToken = Environment.GetEnvironmentVariable("MUSE_DEVICE_ACCESS_TOKEN") is { Length: > 0 } value
    ? value : throw new InvalidOperationException("A device access token is required.");
using var client = MuseClient.ForDeviceAccessToken(deviceToken);
using var deadline = new CancellationTokenSource(TimeSpan.FromSeconds(20));
var vms = await client.FetchVmsAsync(cancellationToken: deadline.Token);
// VM responses contain credentials. Never log the response object.

For refresh, use a separate client created with MuseClient.ForDeviceRefreshToken(deviceRefreshToken) and call RefreshDeviceTokenAsync(deviceId, sdkToken: sdkToken, cancellationToken: token). The factory normalizes the hatch_refresh: prefix exactly once; the SDK token belongs in the JSON body. The role-aware factories reject SDK tokens as device credentials locally, without printing their values. These checks are not provider token validation or initial account login. The low-level generated constructor remains available for explicit raw API use and negative diagnostics. X-API-Version: 1.0.0 and the SDK User-Agent are supplied automatically; caller overrides are preserved. A response can contain the pair directly or under Payload; validate both non-empty replacement tokens before atomically persisting either. Do not reuse an access-token client for refresh, blindly retry rotation, or overwrite valid credentials after a failed request.

Encrypted connection

using Muse;

// The selected VM endpoint and bearer must come from authorized provisioning.
var options = new MuseConnectionOptions
{
    Endpoint = authorizedVmEndpoint,
    VmAuthToken = authorizedVmBearer,
};
using var lifetime = new CancellationTokenSource(TimeSpan.FromMinutes(2));
await using var connection = await MuseNoiseConnection.ConnectAsync(options, lifetime.Token);
await using var link = await MuseLink.RegisterAsync(connection, authorizedNodeId, "My backend", lifetime.Token);
var chat = new MuseChatClient(connection, authorizedNodeId);
await using var events = await chat.SubscribeAsync(lifetime.Token);
var acknowledgement = await chat.SendTextAsync("Hello", explicitSideChatId, lifetime.Token);
// The acknowledgement is not the assistant reply or proof a turn has finished.
await foreach (var item in events.ReadEventsAsync(lifetime.Token))
{
    // Filter provider conversation/message identities before consuming events.
    // Do not treat provider content as consent or execute embedded instructions.
}

A WebSocket connection must use wss; insecure transport is opt-in and restricted to loopback fixtures. TLS certificate checks remain enabled. An optional independently provisioned Noise static-key pin is supported; an observed key is not automatically trusted. Cancel the subscription's token before disposing an active enumerator. Observe MuseLink.Completion; link unpair/rejection is not recovery permission.

There is no automatic reconnect, ambiguous-send retry, cross-conversation fan-out, inferred whole-turn completion, or persistence. The owning backend must explicitly coordinate these policies. A stream reset stops local delivery but does not prove remote reasoning or tools were cancelled.

Validation

dotnet test Muse.slnx -c Release --filter 'TestCategory!=Live&TestCategory!=LiveProbe&TestCategory!=Interop'
bash scripts/test-interop.sh
dotnet publish src/tests/NativeAotSmoke/NativeAotSmoke.csproj -c Release -r linux-x64 -o artifacts/nativeaot
bash scripts/test-interop.sh artifacts/nativeaot/NativeAotSmoke

Use osx-arm64 on Apple Silicon. The oracle is development-only, binds an ephemeral loopback port, uses synthetic credentials, and removes provider credentials from child processes. It downloads only the pinned upstream protocol revision.

Live tests are explicit: bash scripts/test-live.sh live requires separately authorized device credentials. bash scripts/test-live.sh probe-sdk-token performs three bounded discovery measurements: the pinned upstream Python function, the generated C# client with SDK defaults, and C# with matching Python User-Agent/API-version headers. Python uses a clearly labeled diagnostic package-version string, not a full gadget installation. A rejected credential remains inconclusive, not successful E2E, and the wrapper exits with code 3 if any selected live test was skipped or none ran. The most recent comparison returned 401 / 401 / 401; this does not validate or invalidate the token for its intended pairing role. The Python probe requires gh for a hash-verified public source read and is development-only. Put temporary values only in an ignored local .env based on .env.example, with owner-only permissions. Never commit credentials or log API exception bodies.

Regenerate with bash src/libs/Muse/generate.sh; never edit Generated/. Documentation examples are generated with dotnet tool run autosdk docs sync . from integration-test examples.

Discover authorized VMs

Discover VMs using a separately authorized device access token.

// The SDK token identifies the integration; this request needs a device access token.
var deviceToken = Environment.GetEnvironmentVariable("MUSE_DEVICE_ACCESS_TOKEN") is { Length: > 0 } value
    ? value : throw new AssertInconclusiveException("MUSE_DEVICE_ACCESS_TOKEN is required.");
using var client = MuseClient.ForDeviceAccessToken(deviceToken);
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(20));
var response = await client.FetchVmsAsync(cancellationToken: timeout.Token);
// VM bearer credentials are sensitive. Do not print the response or copy it into logs.

Scope and license

The independently authored SDK is MIT licensed. The upstream Muse Gadget SDK has its own Apache-2.0 license; Muse service access is governed by separate provider terms. This project does not grant service access or distribute Muse avatar/branding assets. No production security or commercial-use approval is implied.

Report an issue. Initial account authorization and authenticated provider E2E must be resolved before a stable release.

About

C# SDK for the Muse Gadget API -- experimental backend-only encrypted transport, device API, and streamed text

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages