-
Notifications
You must be signed in to change notification settings - Fork 2
Responder ladder
A message arrives. Exactly one agent has to answer it, or none does. The ladder is how that is decided, and every rung of it is deterministic except one, which is optional and has a deterministic fallback.
responder_plan returns either a decision or a bounded selector request. It
never dispatches a turn. The pure half lives in
tinyhivemind-core/src/responder/,
the waiting half in
tinyhivemind/src/responder/.
| rung | when |
|---|---|
ExplicitMention |
the body directly mentions an active agent |
DeskDefault |
the message is on a desk, and the desk resolves to its first effective active member |
AutoSelection |
the desk is in Auto mode with two or more effective members, so a selector is asked |
DirectAgent |
the chat identity is a direct message or a bare agent chat |
Orchestrator |
nothing above matched, so the host's fallback answers |
Reading order is the tiebreak everywhere it applies. direct_responder takes
the first non-quiet mention of an active agent, and a later mention is never
used as a fallback if the first one turns out to be unusable.
ResponderMode::Auto is the only place a model gets a say, and the shape of
that say is narrow on purpose. The library builds a SelectionRequest holding
the message, the desk id, and the candidate list. The host implements one port:
pub trait Selector: Send + Sync {
fn select<'a>(&'a self, request: &'a SelectionRequest) -> SelectorFuture<'a>;
}Whatever comes back goes through accept_selection, which accepts the output
only if it names exactly one candidate. Matching is ASCII case insensitive and
returns the candidate's canonical id. It tolerates one trailing period and one
matching quote or backtick wrapper, because models add those, and nothing else.
Two candidates matching is a rejection, not a coin flip.
Every outcome at that boundary is named in SelectionDisposition:
NotApplicable, Selected, Disabled, Unavailable, and the case where the
output did not name exactly one candidate. Each of the failure cases falls back
to the deterministic first effective member, so a selector that is down, slow,
or wrong degrades to Lead behaviour rather than to no answer.
SelectionPolicy::Disabled skips the rung entirely without changing which
agent ends up answering.
The one place an agent's own reply can start another turn, and the place where a hive mind would ordinarily turn into an unbounded cascade.
mention_dispatch
looks at a committed agent reply and decides whether it may enqueue exactly one
mentioned agent. Evaluation is fail closed. Once the first reading-order,
non-quiet direct agent mention is found, a self-mention or an inactive target
stops the decision there. It does not go looking for a second candidate.
Refusals are typed rather than silent: Disabled, HopLimitReached,
SourceInactive, and the target-side reasons.
The hop limit is host supplied, finite, and configurable. The library adds no hard ceiling of its own, and the whole feature is off unless host policy explicitly enables it. OpenCompany runs it at two hops.
The runtime crate carries the edge from that pure decision to a host-owned atomic queue:
pub trait MentionTurnQueue: Send + Sync {
fn enqueue_once(&self, request: MentionTurnRequest) -> MentionTurnFuture<'_>;
}A host implementation must do one atomic transaction keyed by the conversation
plus the trigger sequence. Inside it, re-read the stored reply and verify its
source, content, conversation and sequence; revalidate live policy,
authorization and target availability; and durably enqueue at most one child
turn. A duplicate returns Already. An expected live rejection returns
Refused. A rollback must leave neither an idempotency record nor a child
turn.
This port is the only idempotency
boundary in the system. tinyhivemind owns no journal, and it does not retry a
failure or a refusal. A no-dispatch decision calls the queue zero times; a
one-target decision calls it exactly once.
tinyhivemind is GPL-3.0-only. Built by @senamakel.
Start here
The algebra
- Shared medium
- Desks and rosters
- Mentions
- Cross-desk referral
- Transcript projection
- Threads
- Recall
- Responder ladder
Hive mechanics
Working on it
Reference