Issho.Inbox (Issho v0.4.0)

Copy Markdown View Source

What was said to someone while they were away: each comment that mentions them, in any room, kept until they have read it. An agent that was not in the room when a person wrote "@Claude, a look?" finds it here when it next comes (the inbox tool), and the app can wake it at once (:on_mention).

A comment that mentions someone ("comment.created", its mentions) lands in the inbox of each it mentions, but its author; so does an app's own event with mentions in its data (Issho.Events.emit/4). An edit that adds a mention does not: the inbox is of what was said to them, once.

{:ok, items} = Issho.Inbox.items(MyApp.Issho, assistant, on_behalf_of: ada)
:ok = Issho.Inbox.mark_read(MyApp.Issho, assistant, Enum.map(items, & &1["id"]))

An item is the event as Issho.Event.to_map/1 gives it ("name", "room", "document", "by", "data", "at"), with its "id" and whether it was "read". Its room's policy decides, when it is read, whether its reader may still see it (:read): one whose access was taken away does not.

An inbox is a document of Issho's (document/1), kept by the instance's store as the rooms' documents are, and never opened in a room. It keeps the last 200 items.

Waking an agent

MCP has no way to reach an agent that is not connected. So, for each mention, Issho:

  • calls the instance's :on_mention, {module, function} or a function of two arguments, with the key mentioned and the item, in a process of its own: the app starts its agent (a job, a webhook, a chat message to its owner);
  • tells the connected MCP clients that the issho://inbox resource changed (Issho.MCP), and its server's instructions say to read the inbox at the start of a session.

In a cluster

An event is delivered once in the cluster: on the node where the comment was saved, after it was, or where the app emitted its event.

Summary

Types

An item: an event that mentioned its reader, with its id and whether it was read.

Functions

The document of the inbox of the actor with this key.

The items of an actor's inbox, newest first: those not read yet, or all with all: true; only those of rooms the policy lets it :read. actor is an actor or an Issho.Identity. Options: :all, :limit (50), and :on_behalf_of and :claims, for the policy.

Marks items of an inbox read, by their ids, or all of them with :all: the inbox of an actor, an Issho.Identity, or a key.

Types

item()

@type item() :: map()

An item: an event that mentioned its reader, with its id and whether it was read.

Functions

document(key)

@spec document(String.t()) :: String.t()

The document of the inbox of the actor with this key.

items(instance, actor, opts \\ [])

@spec items(atom(), Issho.Actor.t() | Issho.Identity.t(), keyword()) ::
  {:ok, [item()]} | {:error, term()}

The items of an actor's inbox, newest first: those not read yet, or all with all: true; only those of rooms the policy lets it :read. actor is an actor or an Issho.Identity. Options: :all, :limit (50), and :on_behalf_of and :claims, for the policy.

mark_read(instance, actor, ids)

@spec mark_read(
  atom(),
  Issho.Actor.t() | Issho.Identity.t() | String.t(),
  [String.t()] | :all
) ::
  :ok | {:error, term()}

Marks items of an inbox read, by their ids, or all of them with :all: the inbox of an actor, an Issho.Identity, or a key.