# Agent manager compatibility contract

The native `AgentManager` implements LibreMetaverse's non-movement agent
services over the native network and capability layers. It owns a strong
network-manager reference until `Dispose`, so UDP and event-queue callbacks do
not disappear when the weak `GridClient` service cache is the only other
reference.

## Protocol selection and state

Chat, instant messages, conferences, gesture activation, animation, viewer
effects, balance requests, payments, profile updates, interests, picks,
classifieds, mute changes, and their replies retain the C# LLUDP packet choice
and wire fields. Capability-backed preferences, experiences, display names,
offline messages, attachment resources, viewer benefits, render information,
viewer statistics, postcards, and nav-mesh status use LLSD through the current
simulator's advertised capability. A missing optional capability produces the
same empty/`None` result as the reference; caller cancellation remains a typed
`Error::Cancelled`.

Incoming UDP and capability handlers update synchronized state before taking a
snapshot of the subscriber list. User callbacks therefore run without an
agent-state lock held. Group-chat membership, signaled animations, balance,
identity/group data, mute entries, preferences, benefits, and the last nav-mesh
status are shared between all `GridClient::Self` snapshots.
`Debug` output exposes only message and binary-payload lengths, never chat/IM
text, transaction descriptions, or capability URLs.

Mute lists are downloaded with the legacy RequestXfer/SendXferPacket protocol.
The receiver validates the agent, acknowledges ordered chunks, rejects
oversized or inconsistent transfers, replaces state only after a complete
download, and then raises `MuteListUpdated`.

## Gesture execution

Gesture assets use the C# version-2 text format. `PlayGestureAsync` first uses
`ViewerAsset` and falls back to the LLUDP asset-transfer protocol. It executes
chat-channel prefixes, animation start/stop, sound triggers, and timed waits in
sequence. The reference's animation-completion wait remains a no-op. Downloads
are bounded to 16 MiB, the whole operation is bounded to 30 seconds, and a
cancelled UDP transfer sends an abort packet.

## Verification

Unit tests cover UTF-8 chat splitting, identity and animation state, group-chat
ordering, invitation/display-name events, mute parsing, nav-mesh state, gesture
format round trips, and malformed assets. The offline fake-grid test performs
real seed discovery, serves a gesture through `ViewerAsset`, and observes the
resulting chat, animation, and sound packets on a loopback UDP peer.
