API reference#

The module’s public surface is its contract, rust-lib/chat_module.lidl. Everything on this page is rendered from that file, so it says exactly what a generated client can call.

For a walk-through of the calls in order – bring-up, identity, opening a conversation, sending – with working code, see building a module that uses the Chat module API on docs.logos.co.

Types are LIDL’s, not any one language’s. The primitives are tstr (text), bstr (binary), int, uint, float64, bool, any, and result – a structured success-or-error. They compose as [T] for an array, {K: V} for a map, and ?T for a value that may be absent. That set is fixed by the specification; how each maps onto a concrete type is up to the SDK generating your client.

Methods#

Calls are dispatched over the Logos IPC bus. Status-bearing methods return result: success carries any payload – a conversation id, or nothing – and failure a human-readable reason. Collection getters return an array of the named record. A method that returns a plain string returns it empty when the module has not been initialised.

init(config: ChatConfig) result#

Bring the module up and join the delivery network.

Delivery starts asynchronously and this returns without waiting for it, so the module is not yet reachable when it succeeds. Readiness arrives as a delivery_state_changed event reaching “online”; there is no polling equivalent. Subscribe to the events before calling this, or the early ones are missed.

Calling it again while initialised succeeds without doing anything, and the new config is ignored — call shutdown() first to reconfigure.

Storage lives under the instance directory the host assigns; init fails when the host assigned none. Two instances therefore run side by side by giving each host its own session directory, and need no port coordination: the delivery node picks its own.

shutdown() result#

Stop the module: end the inbound worker, drop the chat client, and write conversation state out. Succeeds when the module was never initialised. A later init() starts a fresh session from the persisted state.

get_log_path() tstr#

The file this module is writing its log to, in the instance directory the host assigned. Empty before init, and on a host that assigned none.

health() bool#

Liveness. Always true, and reachable without init or any lock held, so what a caller learns is whether this module answered at all: a host that lost the process fails the call instead, and a false is that failure surfacing.

get_installation_name() tstr#

This installation’s display name: the one set with set_installation_name, or the chat core’s own name for the installation when none was set.

set_installation_name(name: tstr) result#

Set this installation’s display name; empty restores the default. Local to this installation — it is not carried to peers.

get_address() tstr#

The local installation address, shared out-of-band so a peer can open a conversation with this installation via create_conversation. Empty before init.

create_conversation(peer_address: tstr) result#

Open a 1:1 conversation with the peer at peer_address (their get_address). Sends the cryptographic invite; the first message follows via send_message. Returns the new conversation’s id.

create_group_conversation(name: tstr, desc: tstr) result#

Create a group conversation with this installation as its only member; grow it with add_group_member. Every member sees the returned convo_id. name and desc are the group’s shared metadata, visible to every member; both may be empty for an unnamed group.

add_group_member(convo_id: tstr, peer_address: tstr) result#

Invite the peer at peer_address, and every device it has endorsed, into an existing group conversation. The invite is committed and delivered asynchronously; the peer observes the conversation once its instance has joined. Raises conversation_updated here, and members_changed once the group commits the add. Fails on an unknown convo_id.

list_conversations() [Conversation]#

Every conversation this installation holds, in no particular order — sort by last_activity_ms for a conversation list.

get_messages(convo_id: tstr) [Message]#

The messages this installation holds for a conversation, oldest first. An unknown conversation reports an empty list rather than failing.

list_group_members(convo_id: tstr) [GroupMember]#

The roster of a conversation, one GroupMember per element: committed members first, then invites still awaiting the group’s commit. A direct conversation reports both participants and never a pending one; an unknown conversation reports an empty roster.

send_message(convo_id: tstr, content: tstr) result#

Encrypt content and publish it to the conversation, then record it here and raise message_sent. Success means the message reached delivery, not that any peer received it. Fails on an unknown convo_id.

set_conversation_nickname(convo_id: tstr, nickname: tstr) result#

Label a conversation for this installation; empty clears the label. Local only — unlike a group’s name, no other member sees it. Raises conversation_updated. Fails on an unknown convo_id.

delete_conversation(convo_id: tstr) result#

Drop a conversation and its messages from this installation, and ignore anything that arrives for it afterwards rather than reopening it. Local only: the other members keep theirs. Raises conversation_deleted. Fails on an unknown convo_id.

status() Status#

A snapshot of the module: how many conversations it holds, and what the delivery node is doing. Readable before init, reporting zero conversations.

Events#

Events are pushed over the lp_* IPC event channel; a consumer subscribes with on_<event>() rather than polling. They are fire-and-forget: they carry their arguments positionally, in the order listed here, and return nothing.

This is where the results of the network arrive. A call returns once the request is dispatched, so an inbound message, a peer accepting an invite, or the delivery node coming online each reach you as an event rather than as a return value. Subscribe before calling init, or the earliest ones are missed.

message_received(convo_id: tstr, content: tstr, timestamp_ms: int, sender: tstr)#

An inbound message was decrypted and recorded. sender: the sender’s directory-verified account address, or its device id when the sender claims no account.

message_sent(convo_id: tstr, content: tstr, timestamp_ms: int)#

A message this installation sent was published and recorded.

conversation_created(convo_id: tstr, is_outgoing: bool, peer_label: tstr, kind: tstr, name: tstr, desc: tstr)#

A conversation was opened — by a call here, or by a peer’s invite arriving. is_outgoing tells the two apart. kind: “direct” (1:1) or “group”, matching the Conversation record’s field. name, desc: the group’s shared metadata, empty for direct conversations and unnamed groups.

conversation_updated(convo_id: tstr)#

A conversation’s local metadata changed here: a nickname was set, or a member was invited. Re-read it with list_conversations.

members_changed(convo_id: tstr)#

The group committed a roster change. Call list_group_members for the roster it committed.

conversation_deleted(convo_id: tstr)#

A conversation was deleted on this installation.

delivery_state_changed(delivery_state: tstr, detail: tstr)#

The delivery node’s state changed: “initialising”, “online”, “error” or “stopped”, with detail carrying a human-readable reason where there is one. Reaching “online” is how a caller learns init() has finished bringing the network up.

Records#

The structured payloads the methods above exchange. A field marked optional may be absent.

type Conversation#
  • convo_id (tstr) – Identifies the conversation in every other call. Returned by create_conversation and create_group_conversation.

  • nickname (tstr, optional) – A label for this conversation, set with set_conversation_nickname. Local to this installation; no other member sees it.

  • message_count (int) – How many messages this installation holds for the conversation. It counts what was received here, not everything ever sent to the conversation.

  • last_activity_ms (int) – When the most recent held message arrived, in milliseconds since the Unix epoch. Zero when the conversation has no messages.

  • kind (tstr) – “direct” (1:1) or “group”. PrivateV1 and DirectV1 are both “direct”.

  • name (tstr, optional) – A group’s shared name, set at creation and identical for every member. Absent for direct conversations and unnamed groups; distinct from the local-only nickname.

  • description (tstr, optional) – A group’s shared description, set at creation alongside name and likewise the same for every member. Absent on the same terms.

  • preview (tstr, optional) – The last message’s content, truncated to 160 characters, for a conversation-list preview. Absent when the conversation has no messages.

type Message#
  • from_self (bool) – True for a message this installation sent, false for one it received.

  • content (tstr) – The message text, decrypted.

  • timestamp_ms (int) – When the message was sent (own messages) or recorded (received ones), in milliseconds since the Unix epoch.

  • sender (tstr, optional) – Sender’s account address (device id if unassociated); unset on messages this installation sent.

type Status#
  • convo_count (int) – How many conversations this installation currently holds.

  • delivery_state (tstr) – The delivery node’s state, same vocabulary as the delivery_state_changed event: “initialising”, “online”, “error” or “stopped”.

  • detail (tstr) – A human-readable reason for that state, empty when there is none.

type GroupMember#
  • address (tstr) – The member’s directory-verified account address, or empty when the member claims no confirmed account (the UI renders these as an unknown account).

  • pending (bool) – True while the group has not committed this member’s add, so it cannot read the conversation yet. Only invites this instance sent are reported, so a member another instance invited appears once the group commits it. The flag clears when that commit lands; an invite the group never commits stays pending for the life of the conversation.

type ChatConfig#
  • delivery_preset (tstr, optional) – The delivery network to join. Empty or absent means “logos.dev”.

  • log_level (tstr, optional) – How much of the chat core’s own account of a run to log: “error” | “warn” | “info” | “debug” | “trace”. Absent or unrecognised means “info”. Read once, at init: a later init leaves it as it was.