Ikon.Sdk 2.0.7

dotnet add package Ikon.Sdk --version 2.0.7
                    
NuGet\Install-Package Ikon.Sdk -Version 2.0.7
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Ikon.Sdk" Version="2.0.7" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Ikon.Sdk" Version="2.0.7" />
                    
Directory.Packages.props
<PackageReference Include="Ikon.Sdk" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Ikon.Sdk --version 2.0.7
                    
#r "nuget: Ikon.Sdk, 2.0.7"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Ikon.Sdk@2.0.7
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Ikon.Sdk&version=2.0.7
                    
Install as a Cake Addin
#tool nuget:?package=Ikon.Sdk&version=2.0.7
                    
Install as a Cake Tool

Ikon AI C# SDK

The Ikon AI C# SDK provides a simple way to connect to Ikon AI App from any .NET application. It supports .NET 10 and .NET Standard 2.1 (including Unity).

Features

  • Three authentication modes: API Key, Local Development, Backend
  • Automatic reconnection with exponential backoff
  • Audio streaming with Opus encoding/decoding
  • Flexible audio streaming modes
  • Function registration and remote invocation
  • Low-level protocol message access

Installation

Install the NuGet package:

dotnet add package Ikon.Sdk

Quick Start

using Ikon.Sdk;

// Create configuration with API key authentication
var config = new IkonClientConfig
{
    ApiKey = new ApiKeyConfig
    {
        ApiKey = Environment.GetEnvironmentVariable("IKON_API_KEY")!,
        SpaceId = "your-space-id",
        ExternalUserId = "user-123"
    },
    Description = "My App"
};

// Create and connect the client
await using var client = new IkonClient(config);

client.ReadyAsync += async (sender, e) =>
{
    Console.WriteLine("Connected!");
    await client.SignalReadyAsync();
};

client.MessageReceivedAsync += async (sender, e) =>
{
    Console.WriteLine($"Received: {e.Message.Opcode}");
};

await client.ConnectAsync();

Authentication Modes

The SDK supports three authentication modes. Exactly one must be configured.

API Key Authentication

Use this for programmatic access to Ikon AI App. Get your API key from the Ikon portal.

var config = new IkonClientConfig
{
    ApiKey = new ApiKeyConfig
    {
        ApiKey = "ikon-xxxxx",           // API key from portal
        SpaceId = "...",                  // Space ID
        ExternalUserId = "user-123",      // Your user identifier
        ChannelKey = "main",              // Optional: specific channel
        SessionId = "session-xyz",        // Optional: target a precomputed session
        BackendType = BackendType.Production,
        UserType = UserType.Human,
        ClientType = ClientType.DesktopApp
    }
};

Local Development

Connect directly to a local Ikon server during development.

var config = new IkonClientConfig
{
    Local = new LocalConfig
    {
        Host = "localhost",
        HttpsPort = 8443,
        UserId = "dev-user"
    }
};

Backend Authentication

Use existing Ikon backend login credentials. This is for applications that have already authenticated to the backend.

var config = new IkonClientConfig
{
    Backend = new BackendConfig
    {
        SpaceId = "...",
        ExternalUserId = "user-123",     // Your user identifier
        ChannelKey = "main",             // Optional
        SessionId = "session-xyz",       // Optional: target a precomputed session
        UserType = UserType.Human,
        ClientType = ClientType.DesktopApp
    }
};

Connection Lifecycle

Connection States

The client tracks its connection state via the State property:

State Description
Idle Initial state, not connected
Connecting Authentication and connection in progress
Connected Fully connected and ready
Reconnecting Lost connection, attempting automatic reconnect
Offline Disconnected (connection failed or max retries exceeded)

Helper extension methods are available:

  • state.IsConnecting() - True if Connecting or Reconnecting
  • state.IsConnected() - True if Connected
  • state.IsOffline() - True if Idle or Offline

Events

// Connection state changes
client.StateChangedAsync += async (sender, e) =>
{
    Console.WriteLine($"State: {e.State}");
};

// Connection established and ready
client.ReadyAsync += async (sender, e) =>
{
    // Perform initialization here
    await client.SignalReadyAsync();  // Signal that this client is ready (mandatory)
};

// Server is stopping (can still send messages)
client.StoppingAsync += async (sender, e) =>
{
    Console.WriteLine("Server stopping...");
};

// Disconnected from server
client.DisconnectedAsync += async (sender, e) =>
{
    Console.WriteLine("Disconnected");
};

// Error occurred
client.ErrorOccurredAsync += async (sender, e) =>
{
    Console.WriteLine($"Error: {e.Error.Message}");
};

// Protocol message received
client.MessageReceivedAsync += async (sender, e) =>
{
    Console.WriteLine($"Message: {e.Message.Opcode}");
};

Connecting and Disconnecting

// Connect (will throw on failure)
await client.ConnectAsync();

// Wait for a specific client to connect
bool found = await client.WaitForClientAsync(
    productId: "my-product",
    userId: "user-123",
    timeout: TimeSpan.FromSeconds(30)
);

// Disconnect
await client.DisconnectAsync();

// Or dispose (also disconnects)
await client.DisposeAsync();

Automatic Reconnection

The SDK automatically attempts to reconnect when the connection is lost unexpectedly. Configure reconnection behavior:

var config = new IkonClientConfig
{
    // ... authentication config ...
    Timeouts = new TimeoutConfig
    {
        InitialReconnectDelay = TimeSpan.FromMilliseconds(500),  // Initial backoff delay
        MaxReconnectAttempts = 4                                  // Max attempts (default)
    }
};

Reconnection uses exponential backoff starting from InitialReconnectDelay (500ms, 1s, 2s, 4s by default).

Sending Messages

Raw Protocol Messages

// Send a raw protocol message
var message = ProtocolMessage.Create(client.ClientContext.SessionId, payload);
await client.SendMessageAsync(message);

Typed Payloads

// Send a typed payload (creates ProtocolMessage automatically)
await client.SendMessageAsync(new MyCustomPayload { /* ... */ });

Audio

The SDK provides comprehensive audio support with automatic Opus encoding/decoding.

Sending Audio

Send audio to the server:

// Get audio samples (float PCM, range [-1.0, 1.0])
ReadOnlyMemory<float> samples = GetAudioSamples();

// Send audio
await client.SendAudioAsync(
    samples: samples,
    sampleRate: 48000,
    channelCount: 1,
    isFirst: true,      // First chunk of this stream
    isLast: false       // More chunks coming
);

// Send final chunk
await client.SendAudioAsync(samples, 48000, 1, isFirst: false, isLast: true);

// Optional: specify stream ID, total duration, encoder options, and target clients
await client.SendAudioAsync(
    samples: samples,
    sampleRate: 48000,
    channelCount: 1,
    isFirst: true,
    isLast: true,
    streamId: "my-audio-stream",              // Unique stream identifier
    totalDuration: TimeSpan.FromSeconds(5),
    encoderOptions: new AudioEncoderOptions   // Custom encoder settings
    {
        Bitrate = 64000,
        Complexity = 10
    },
    targetIds: new[] { 123, 456 }             // Target specific session IDs
);

// Set default encoder options for all audio
client.DefaultEncoderOptions = new AudioEncoderOptions
{
    Bitrate = 48000,
    Complexity = 8
};

Receiving Audio

Subscribe to audio events to receive incoming audio streams:

client.AudioInputStreamBeginAsync += async (sender, e) =>
{
    Console.WriteLine($"Audio stream started: {e.StreamId}");
    Console.WriteLine($"  Codec: {e.Codec}");
    Console.WriteLine($"  Sample rate: {e.SampleRate}");
    Console.WriteLine($"  Channel count: {e.ChannelCount}");

    // Optional: override sample rate (SDK will resample)
    // e.SampleRate = 44100;

    // Optional: change streaming mode
    // e.StreamingMode = AudioInputStreamingMode.DelayUntilTotalDurationKnown;
};

client.AudioInputFrameAsync += async (sender, e) =>
{
    // e.Samples contains decoded PCM float samples
    float[] samples = e.Samples;

    Console.WriteLine($"Frame: {e.StreamId}");
    Console.WriteLine($"  Samples: {samples.Length}");
    Console.WriteLine($"  IsFirst: {e.IsFirst}");
    Console.WriteLine($"  IsLast: {e.IsLast}");
    Console.WriteLine($"  Total duration: {e.TotalDuration}");  // Zero if unknown

    // Process or play the audio samples...
};

client.AudioInputStreamEndAsync += async (sender, e) =>
{
    Console.WriteLine($"Audio stream ended: {e.StreamId}");
};

Audio Streaming Modes

Control how audio frames are delivered:

Mode Behavior
Streaming Forward frames immediately (lowest latency)
DelayUntilTotalDurationKnown Buffer until the total duration is known, then stream
DelayUntilIsLast Buffer everything, emit all frames when stream ends

Set the streaming mode in the AudioInputStreamBeginAsync event handler:

client.AudioInputStreamBeginAsync += async (sender, e) =>
{
    // Buffer audio for UI timeline display
    e.StreamingMode = AudioInputStreamingMode.DelayUntilTotalDurationKnown;
};

Functions

The SDK provides a per-client function registry system that allows you to register callable functions that can be invoked locally or shared with other connected clients via the server. Each IkonClient has its own isolated FunctionRegistry accessible via client.FunctionRegistry.

Registering Functions

Attribute-Based Registration (Recommended)

Mark methods with the [Function] attribute and register the containing class:

using Ikon.Common.Core.Functions;

public class MyFunctions
{
    [Function(Description = "Greets a user by name")]
    public string Greet(string name)
    {
        return $"Hello, {name}!";
    }

    [Function(Description = "Calculates sum", Visibility = FunctionVisibility.Shared)]
    public async Task<int> AddAsync(int a, int b)
    {
        return a + b;
    }

    [Function(Description = "Streams numbers")]
    public async IAsyncEnumerable<int> CountAsync(int max)
    {
        for (int i = 0; i < max; i++)
            yield return i;
    }
}

// Register all [Function] methods from an instance
var myFuncs = new MyFunctions();
client.FunctionRegistry.RegisterFromInstance(myFuncs);

// Or register from a type (static methods only)
client.FunctionRegistry.RegisterFromType<MyStaticFunctions>();

// Or scan entire assembly
client.FunctionRegistry.RegisterFromAssembly(typeof(MyFunctions).Assembly);

Manual Registration (Lambda/Delegate)

Register functions directly using lambdas:

// Simple synchronous function
client.FunctionRegistry.AddFunction(
    Function.Register((string name) => $"Hello, {name}!", "Greet")
);

// Async function
client.FunctionRegistry.AddFunction(
    Function.Register(async (int a, int b) =>
    {
        await Task.Delay(10);
        return a + b;
    }, "AddAsync")
);

// With attributes (description, visibility, etc.)
client.FunctionRegistry.AddFunction(
    Function.Register(
        (string query) => SearchDatabase(query),
        "Search",
        new FunctionAttribute { Description = "Searches the database", Visibility = FunctionVisibility.Shared }
    )
);

Function Visibility

Functions can be either local or shared:

  • Local (default): Only available within this process
  • Shared: Distributed to the server and accessible by other connected clients
// Local - only available in this process (default)
[Function(Visibility = FunctionVisibility.Local)]
public string LocalOnly() => "local";

// Shared - distributed to server and other clients
[Function(Visibility = FunctionVisibility.Shared)]
public string SharedWithAll() => "shared";

// Override visibility at registration time
client.FunctionRegistry.RegisterFromInstance(myFuncs, FunctionVisibility.Shared);

Discovering Functions

Query the registry to find available functions:

// Check if a function exists
if (client.FunctionRegistry.HasFunction("MyFunc"))
{
    var func = client.FunctionRegistry.GetFunction("MyFunc");
    Console.WriteLine($"Found: {func?.Name}, Params: {func?.Parameters.Length}");
}

// Get all functions grouped by name (including remote)
var allFuncs = client.FunctionRegistry.Functions;

// Find which client sessions have a specific function
var clientIds = client.FunctionRegistry.GetClientSessionsWithFunction("SharedFunc");

// Wait for a function to become available (useful for coordination between clients)
bool available = await client.FunctionRegistry.WaitForFunctionAsync(
    "RemoteFunc",
    timeout: TimeSpan.FromSeconds(30)
);

Calling Functions

Call registered functions locally or remotely:

// Synchronous call
string result = client.FunctionRegistry.Call<string>("Greet", args: new object?[] { "World" });

// Async call
int sum = await client.FunctionRegistry.CallAsync<int>("AddAsync", args: new object?[] { 1, 2 });

// Void async call
await client.FunctionRegistry.CallAsync("LogMessage", args: new object?[] { "Hello" });

// Call a function on a specific remote client (uses targetId parameter)
int remoteSum = await client.FunctionRegistry.CallAsync<int>("Calculate", targetId: 123, args: new object?[] { 5, 10 });

// Streaming results (async enumerable)
await foreach (var item in client.FunctionRegistry.CallAsyncEnumerable<int>("CountAsync", args: new object?[] { 10 }))
{
    Console.WriteLine(item);
}

Removing Functions

// Remove a specific function by name (local functions only)
client.FunctionRegistry.RemoveFunction("MyFunc");

// Remove a function with specific visibility
client.FunctionRegistry.RemoveFunction("MyFunc", FunctionVisibility.Shared);

// Clear all local functions
client.FunctionRegistry.ClearLocalFunctions();

Function Events

Subscribe to function registration events:

client.FunctionRegistry.FunctionRegistered += func =>
{
    Console.WriteLine($"Registered: {func.Name} ({func.Visibility})");
};

client.FunctionRegistry.FunctionUnregistered += name =>
{
    Console.WriteLine($"Unregistered: {name}");
};

Advanced Configuration

Timeouts

var config = new IkonClientConfig
{
    // ... authentication ...
    Timeouts = new TimeoutConfig
    {
        InitialReconnectDelay = TimeSpan.FromMilliseconds(500),  // Initial backoff delay
        MaxReconnectAttempts = 4                                  // Max reconnect attempts (default)
    }
};

Protocol Options

var config = new IkonClientConfig
{
    // ... authentication ...

    // Filter which message types to receive/send
    OpcodeGroupsFromServer = Opcode.GROUP_ALL,
    OpcodeGroupsToServer = Opcode.GROUP_ALL,

    // Payload serialization format
    PayloadType = PayloadType.Teleport  // Default
};

Client Identification

var config = new IkonClientConfig
{
    // ... authentication ...
    DeviceId = "unique-device-id",
    ProductId = "my-app",
    VersionId = "1.0.0",
    InstallId = "install-xyz",
    Locale = "en-US",
    Description = "My Application",
    UserAgent = "my-app/1.0.0",
    Parameters = new Dictionary<string, string>
    {
        ["custom_param"] = "value"
    }
};

API Reference

Core Types

Type Description
IkonClient Main client class for connecting to Ikon servers
IkonClientConfig Configuration for the client
ConnectionState Enum: Idle, Connecting, Connected, Reconnecting, Offline

Configuration Types

Type Description
LocalConfig Configuration for local server development
ApiKeyConfig Configuration for API key authentication
BackendConfig Configuration for backend authentication
TimeoutConfig Timeout settings
BackendType Enum: Production, Development

Audio Types

Type Description
AudioInputStreamingMode Enum: Streaming, DelayUntilTotalDurationKnown, DelayUntilIsLast
AudioInputStreamBeginEventArgs Event args for audio stream start
AudioInputFrameEventArgs Event args for audio frame
AudioInputStreamEndEventArgs Event args for audio stream end
AudioEncoderOptions Options for configuring the Opus encoder

Function Types

Type Description
FunctionRegistry Per-client registry for function registration and invocation
Function Immutable function metadata and callback
FunctionAttribute Attribute for marking methods as registerable functions
RegisterAllAttribute Class-level attribute to auto-register all public members as functions
FunctionVisibility Enum: Local, Shared
FunctionParameter Parameter metadata (name, type, default value)

Event Types

Type Description
MessageEventArgs Event args containing a ProtocolMessage
ConnectionStateEventArgs Event args containing the new ConnectionState
ErrorEventArgs Event args containing an Exception

License

This SDK is licensed under the Ikon AI SDK License. See LICENSE for details.

Support

For issues and feature requests, contact Ikon support or open an issue on GitHub.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.7 54 4/3/2026
2.0.6 151 2/24/2026
2.0.5 96 2/23/2026
2.0.4 114 2/16/2026
2.0.2 103 2/2/2026
2.0.1 158 1/26/2026