3.2 KiB
Grid-agent chat and instant-message interaction
InteractionCoordinator is the single bounded owner for public chat and
one-to-one instant messages. A live session generation installs exactly one
native AgentManager chat subscription and one IM subscription. Their RAII
guards are removed before logout. Connect and disconnect state travels on a
separate watch channel, so inbound queue saturation cannot delay generation
cancellation or reconnect fencing.
Admission and routing
Inputs are normalized into bounded values before enqueue. Self messages, objects and system chat, muted residents, typing notifications, group or conference IMs, malformed or oversized input, repeated delivery IDs, and reflections of delivered output are suppressed. Public chat is admitted only for a configured alias or mention, a brief nearby greeting, or a short-lived follow-up from a resident already engaged by the agent. Ambient region chat is not sent to the model.
Public chat always has Public origin, even when the resident UUID appears in
the operator allowlist. Public commands receive a fixed denial; public LSL
requests remain policy-gated. Direct-message authority is derived solely from
the sender UUID in authorized_avatar_uuids. Text claiming to be an operator
cannot change that origin. Unprivileged IM remains informational, while an
authorized IM may expose only the tools returned by PolicyGateway for its
immutable request context. Unknown or unregistered tools fail closed.
Each avatar and channel has an independent FIFO with fragment debounce. A
round-robin ready queue permits at most one active request per FIFO and enforces
the configured global inference cap, so a slow resident does not block other
residents or lifecycle work. Direct-message context expires after 24 hours as
defined by ConversationStore; public and direct context never mix.
Delivery and safety
Model work has a configured deadline and shares generation cancellation. Visible text is checked for credential, authorization, hidden-prompt, and tool schema markers; URLs are omitted and ASCII mentions are neutralized. The total response is bounded, then split only at UTF-8 boundaries into at most 1,023-byte grid messages. Public chat and IM use independent rate limiters.
Every outbound part carries its trigger delivery ID, conversation session ID, session generation, channel, part index, and part count. A delivery observation records success, timeout, policy denial, or failure plus the number of parts actually delivered. Fixed busy/failure text is emitted only for an admitted interaction. Successful public replies also publish a content-free attention request for later avatar behavior work.
Shutdown and focused verification
Disconnect cancels all generation tasks and drops queued input. Reconnect starts a fresh generation without clearing the bounded duplicate/reflection history. Shutdown disconnects first, joins every model/delivery task within the configured deadline, and flushes conversation persistence. No callback or task is detached.
cargo test --locked -p metacrate-grid-agent --lib interaction_tests
cargo test --locked -p metacrate-grid-agent --test dependency_policy
cargo clippy --locked -p metacrate-grid-agent --all-targets -- -D warnings