Skip to content

C# (.NET, Unity) API

Generated from the source and its doc comments (sdk/client-dotnet/AgentIM.Client/Client.cs).

Terminal window
dotnet add package AgentIM.Client
public sealed class ClientOptions

How the client starts: the server address, this device’s id, the cache, the token provider and how it names itself.

public string Url { get; set; } = "";

https://chat.example.com.

public string DeviceId { get; set; } = "";

This device’s id, the same every run (1..64 of A-Z a-z 0-9 _ -).

public string? DeviceName { get; set; }

A name for this device in the user’s device list, like “Maya’s iPhone”.

public string? Platform { get; set; }

The platform reported to the server (ios, android, windows…), for the device list and push.

public string? StoreDir { get; set; }

Where the cache lives; null keeps it in memory.

public Func<CancellationToken, Task<string>> TokenProvider { get; set; } = _

A client token from your backend; throw to stop.

public SynchronizationContext? Context { get; set; }

Where state changes and events are delivered (Unity: the main thread). Null: the SDK’s thread.

public string ClientName { get; set; } = "agentim-dotnet";

This app’s name, sent to the server with each connection (for diagnostics and minimum-version rules).

public string ClientVersion { get; set; } = "0.1.0";

This app’s version, sent with ClientName.

public TimeSpan CommandTimeout { get; set; } = TimeSpan.FromSeconds(60);

How long a command waits for the core.

public sealed class TokenRefusedException : Exception

Thrown by a token provider when the backend refuses the user.

public sealed class AgentIMException : Exception

The server’s code (forbidden, not_found, conflict, bad_request, blocked, rate_limited…) or the client’s (disconnected, timeout, closed…); unknown codes pass through as they are.

public string Code { get; }

The error code: the server’s (forbidden, not_found, conflict, bad_request, …) or the client’s (disconnected, timeout, closed, unauthenticated).

public bool Retryable { get; }

Whether the same request may work later.

public long? RetryAfterMs { get; }

How long the server asked to wait before trying again.

public sealed class Observable<T>

A value the UI follows: stays the same object until it changes.

public IDisposable Subscribe(Action<T> fn)

Called with the current value now, then with every change; dispose to stop.

public void Dispose()

Stops the subscription.

public sealed class Connection

The connection state and why: state is closed, connecting, connected, disconnected, suspended or failed.

public string State { get; }

closed, connecting, connected, disconnected, suspended or failed.

public string? Reason { get; }

Why it is not connected (an error code), when it is not.

public long? RetryAt { get; }

When the next reconnect attempt is due (Unix ms), while waiting to reconnect.

public sealed class Messages

One conversation’s messages as shown, oldest first; each has key, content, status (sent, sending, failed)…

public string ConvId { get; }

The conversation these messages belong to.

public Observable<IReadOnlyList<JsonObject>> List { get; } = new Observable<IReadOnlyList<JsonObject>>(Array.Empty<JsonObject>());

The messages as shown, oldest first, kept up to date.

public bool HasOlder { get; private set; }

Whether older messages can still be loaded.

public string? OlderEnd { get; private set; }

Why nothing older can be loaded: start (the beginning) or retention (deleted by the retention period).

public async Task<bool> LoadOlderAsync()

The page before the oldest shown: the cache first, then the server. False at the start.

public Task<JsonNode?> JumpToAsync(long seq)

A page around a message (it stays loaded).

public sealed class AgentIMClient : IDisposable

The AgentIM client for one account on one device: keeps the connection, syncs, sends the offline queue in order, keeps the local cache, and turns everything into observable state.

public Observable<Connection> Connection { get; } = new Observable<Connection>(new Connection("closed"));

The connection state (closed, connecting, connected, disconnected, suspended, failed) and why; subscribe to follow it.

public Observable<IReadOnlyList<JsonObject>> Conversations { get; } = new Observable<IReadOnlyList<JsonObject>>(Array.Empty<JsonObject>());

The conversation list, newest first, kept up to date.

public static string Version

The version of the native core.

public static AgentIMClient Create(ClientOptions o)

Starts a client with its options: the server address, this device’s id, the token provider and the cache. Nothing connects until ConnectAsync.

public Task<JsonNode?> CommandAsync(JsonObject cmd)

Any core command ({“cmd”: …}); completes with its result.

public IDisposable On(string type, Action<JsonObject> fn)

Events: operation, side, signal, reset, storage, event, read, mute (and the ones above).

public void SetNetwork(bool online)

The platform’s network: call on every change (Unity: Application.internetReachability).

public void SetForeground(bool foreground)

The app came to the foreground or went to the background (Unity: OnApplicationPause).

public Messages Messages(string convId)

The conversation’s messages, kept up to date.

public Task<JsonNode?> ConnectAsync()

Connects and keeps connecting: reconnects with backoff when the network or the server goes, syncs what it missed, sends the offline queue.

public Task<JsonNode?> CloseAsync()

Disconnects; the queue and the cache stay. ConnectAsync again picks up where it stopped.

public Task<JsonNode?> LogoutAsync()

Logs out here: closes and wipes the cache and the queue (GDPR).

public Task<JsonNode?> SendAsync(string convId, string text, string? clientMsgId = null, string? replyTo = null,

Returns {client_msg_id, key} once the message is queued and shown.

public Task<JsonNode?> SendFileAsync(string convId, string path, string? name = null, string? mime = null,

Sends a file or a photo from a path: shown at once as uploading, sent when it is up. A photo loses its EXIF and GPS (unless ) and gets a 320-pixel thumbnail (docs/en/design/messaging.md).

public Task<JsonNode?> FileUrlAsync(string convId, string fileId, string variant = "original")

A link (valid a few minutes) to read a file: original or thumb.

public Task<JsonNode?> EditAsync(string convId, string msgId, string text)

Edits one of my messages (by msgId, or by clientMsgId while it is still queued); the change shows at once.

public Task<JsonNode?> RecallAsync(string convId, string msgId)

Recalls one of my messages for everyone; a message still in the queue is simply not sent.

public Task<JsonNode?> ReadAsync(string convId, long? seq = null)

Marks the conversation read up to seq (default: the newest) on all my devices.

public Task<JsonNode?> RetryAsync(string convId, string clientMsgId)

Sends a failed message again (the same client_msg_id, so it is never doubled).

public Task<JsonNode?> DiscardAsync(string convId, string clientMsgId)

Drops a failed or waiting message from the queue.

public Task<JsonNode?> ReactAsync(string convId, string msgId, string key)

Adds a reaction (one emoji, or one of the app’s :names:); adding it twice changes nothing.

public Task<JsonNode?> UnreactAsync(string convId, string msgId, string key)

Removes my reaction; removing one that is not there changes nothing.

public Task<JsonNode?> PinAsync(string convId, string msgId)

Pins a message to the conversation; pinning it again changes nothing.

public Task<JsonNode?> UnpinAsync(string convId, string msgId)

Unpins a message.

public Task<JsonNode?> ListPinsAsync(string convId)

The conversation’s pinned messages, latest pin first.

public Task<JsonNode?> PullThreadAsync(string convId, string threadId, long afterSeq = 0)

A thread’s root and its replies after .

public Task<JsonNode?> ListThreadsAsync(string? convId = null)

The threads I follow (in one conversation, or all), latest reply first, with unread counts.

public Task<JsonNode?> ReadThreadAsync(string convId, string threadId, long seq)

Marks a thread read up to on all my devices.

public Task<JsonNode?> FollowThreadAsync(string convId, string threadId, bool follow = true)

Follows a thread (its replies notify me) or stops following it.

public Task<JsonNode?> MsgSummaryAsync(string convId, IEnumerable<string> msgIds)

The thread summary, reactions and pin of up to 100 messages (for messages loaded from history).

public Task<JsonNode?> CallAsync(string op, JsonObject? args = null)

A request that needs the server now (approvals, decisions, queries).

public Task<JsonNode?> DebugStateAsync()

Everything that helps report a problem: the connection, positions, the queue and recent failures.

public void Dispose()

Stops the client; no event arrives after it returns. Waiting commands fail with closed.