Ikon.Sdk 2.0.4

There is a newer version of this package available.
See the version list below for details.
dotnet add package Ikon.Sdk --version 2.0.4
                    
NuGet\Install-Package Ikon.Sdk -Version 2.0.4
                    
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.4" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Ikon.Sdk" Version="2.0.4" />
                    
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.4
                    
#r "nuget: Ikon.Sdk, 2.0.4"
                    
#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.4
                    
#: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.4
                    
Install as a Cake Addin
#tool nuget:?package=Ikon.Sdk&version=2.0.4
                    
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
using var client = new IkonClient(config);

client.Ready += async (sender, e) =>
{
    Console.WriteLine("Connected!");
    client.SignalReady();
};

client.MessageReceived += 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
        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 = "...",
        ChannelKey = "main",             // Optional
        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 (user-initiated 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.StateChanged += async (sender, e) =>
{
    Console.WriteLine($"State: {e.State}");
};

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

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

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

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

// Protocol message received
client.MessageReceived += 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)
client.Dispose();

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
    {
        ReconnectBackoff = TimeSpan.FromMilliseconds(500),  // Initial backoff
        MaxReconnectAttempts = 6                             // Max attempts
    }
};

Reconnection uses exponential backoff (500ms, 1s, 2s, 4s, 8s, 16s by default).

Sending Messages

Raw Protocol Messages

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

Typed Payloads

// Send a typed payload (creates ProtocolMessage automatically)
client.SendMessage(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
client.SendAudio(
    samples: samples,
    sampleRate: 48000,
    channelCount: 1,
    isFirst: true,      // First chunk of this stream
    isLast: false       // More chunks coming
);

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

// Optional: specify stream ID, total duration, encoder options, and target clients
client.SendAudio(
    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 function registry system that allows you to register callable functions that can be invoked locally or shared with other connected clients via the server.

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();
FunctionRegistry.Instance.RegisterFromInstance(myFuncs);

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

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

Manual Registration (Lambda/Delegate)

Register functions directly using lambdas:

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

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

// With attributes (description, visibility, etc.)
FunctionRegistry.Instance.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
FunctionRegistry.Instance.RegisterFromInstance(myFuncs, FunctionVisibility.Shared);

Discovering Functions

Query the registry to find available functions:

// Get all registered function names
var names = FunctionRegistry.Instance.GetAllFunctionNames();

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

// Get all functions (including remote)
var allFuncs = FunctionRegistry.Instance.Functions;

// Get only remote functions (registered by other clients)
var remoteFuncs = FunctionRegistry.Instance.GetRemoteFunctions();

// Get only local functions
var localFuncs = FunctionRegistry.Instance.GetLocalFunctions();

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

Calling Functions

Call registered functions locally or remotely:

// Synchronous call
string result = FunctionRegistry.Instance.Call<string>("Greet", "World");

// Async call
int sum = await FunctionRegistry.Instance.CallAsync<int>("AddAsync", 1, 2);

// Void async call
await FunctionRegistry.Instance.CallAsync("LogMessage", "Hello");

// Call a function on a specific remote client
int remoteSum = await FunctionRegistry.Instance.CallAsync<int>("Calculate", targetId: 123, 5, 10);

// Streaming results (async enumerable)
await foreach (var item in FunctionRegistry.Instance.CallAsyncEnumerable<int>("CountAsync", 10))
{
    Console.WriteLine(item);
}

Removing Functions

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

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

Function Events

Subscribe to function registration events:

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

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

Advanced Configuration

Timeouts

var config = new IkonClientConfig
{
    // ... authentication ...
    Timeouts = new TimeoutConfig
    {
        ConnectionTimeout = TimeSpan.FromSeconds(30),    // Connection timeout
        ProvisioningTimeout = TimeSpan.FromSeconds(60),  // Server startup timeout
        KeepaliveTimeout = TimeSpan.FromSeconds(125),    // Keepalive timeout
        ReconnectBackoff = TimeSpan.FromMilliseconds(500),
        MaxReconnectAttempts = 6
    }
};

Protocol Options

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

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

    // Receive all messages, not just those targeted to this client
    ReceiveAllMessages = false,

    // 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 Central registry for function registration and invocation
Function Immutable function metadata and callback
FunctionAttribute Attribute for marking methods as registerable 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 91 4/3/2026
2.0.6 152 2/24/2026
2.0.5 99 2/23/2026
2.0.4 115 2/16/2026
2.0.2 107 2/2/2026
2.0.1 161 1/26/2026