Files
MetaCrate/docs/grid-agent-perception.md
Chili Palmer 3a0ead7eb5
Some checks failed
CI / rust-skia (Rust only) (push) Successful in 2m48s
CI / required (push) Failing after 2m43s
feat(grid-agent): add bounded world perception tools (#124)
2026-08-17 23:52:33 +00:00

4.1 KiB

Grid-agent perception tools

The grid agent exposes compact read-only projections of state that the existing native managers have already observed. A tool call never starts a directory search, fetches an asset, selects an object, accepts inventory, sends a packet, or mutates the world. The snapshot boundary is enabled only after the native event queue reports readiness and is fenced by both session generation and region UUID.

Every result has schema_version, tool, generation, region_id, observed_unix_millis, freshness, trust, and provenance. freshness is observed for a new snapshot and cached for a snapshot reused within the two-second TTL. Missing manager facts are structured { "status": "unknown", "reason": "manager_cache_unavailable" } values. Deterministic distances and cardinal directions are declared as derived fields; model_inference is always none. Names, descriptions, hover text, parcel text, and inventory paths are marked untrusted_observed_data, stripped of controls and URL-shaped tokens, and limited to 256 UTF-8 bytes.

All eight tools are registered as policy capability Informational, risk ReadOnly, idempotent, fixed cost one tool call, with no approval. The five world-state tools may be offered to public chat and IM. Inventory search, received landmarks, and recent participants are owner-private projections and are exposed only to authorized IM, authenticated local operators, or explicitly granted scheduler runs. The interaction intent filter further narrows which informational tools a particular conversation may see.

Tool Arguments Result projection Example
world_location {} region name and agent position {"generation":4,"region_id":"…","position":{"x":128,"y":64,"z":24}}
agent_state {} agent UUID, position, health, sitting local ID {"health":100,"sitting_on_local_id":{"status":"unknown","reason":"manager_cache_unavailable"}}
nearby_avatars optional radius_meters, page, page_size UUID, name, position, distance, direction {"items":[{"name":"A Resident","distance_meters":3.2,"direction":"north"}]}
visible_objects optional radius_meters, page, page_size non-attachment UUID/local ID, safe text, position and scale {"items":[{"name":"Cube","local_id":12,"trust":"untrusted_observed_data"}]}
parcel_environment {} safe current parcel fields and cached terrain/environment facts {"parcel":{"status":"observed","area":512},"environment":{"water_height":20,"terrain_height":24}}
inventory_search required query; optional page, page_size cached item UUID, name, type, path and modification time {"items":[{"name":"Example","kind":"LSL","path":"/Scripts/Example"}]}
received_landmarks optional page, page_size cached landmark inventory metadata {"items":[{"name":"Home","region_id":{"status":"unknown","reason":"manager_cache_unavailable"}}]}
recent_participants optional page, page_size avatar UUID, channel and last-active time only {"items":[{"avatar_id":"…","channel":"direct_im"}]}

Radius is limited to 256 metres, page size to 20, page number to 1,000, inventory queries to 128 bytes, each source collection to 2,048 entries, and each encoded result to 32 KiB. Ordering is distance then UUID for world items, path/name then UUID for inventory and landmarks, and last-active time then UUID and channel for participants. Paged results set source_truncated when a native cache contained more than the inspected bound, so a bounded total is never presented as complete. Attachments are excluded. Owner identities, permissions, sale data, asset and capability URLs, media URLs, raw assets, inventory bodies, and all conversation content are absent by construction.

Snapshot capture has a three-second deadline and observes cancellation. A disconnect, reconnect, region crossing, or generation change invalidates the cache. Observability receives only authorization/call/tool identifiers, outcome, duration, result byte count, and cache-hit status; arguments and result payloads are never logged.