---
name: grix-query
description: Use the typed `grix_query` tool for Grix contact lookup, keyword search, session search, and session message history lookup. Trigger when users ask to find contacts, search conversations, list visible sessions, or inspect recent messages in a known session.
---

# Grix Query

Use `grix_query` for read-only Grix lookup. It only queries existing contacts,
sessions, and raw session messages — it never sends or changes anything. The
Grix account is resolved from the current agent context; you do not pass it.

## Tool contract

Call `grix_query` with one `action`:

- `contact_search` — the owner's contact directory (friends + agents). Use
  exactly one mode: exact lookup with `id` (numeric contact/agent ID), keyword
  search with `keyword` (matches remark name, nickname, username, ID prefix),
  or list-all with neither (sorted by `created_at` desc).
- `session_search` — the owner's visible sessions. Same three modes: `id`
  (exact session ID), `keyword` (matches title and session ID), or neither
  (ordered by pinned status and `last_active_at`). Each result carries
  `session_type` (`1` private, `2` group); pass `sessionType` to filter by
  type, omit to get both.
  Fourth mode: `peerId` (a user ID) — returns the private chat between the
  current user and that account exactly, via the pair key rather than the
  title. Prefer it whenever the target user's ID is known (e.g. the agent
  owner). Takes precedence over `id`/`keyword`; error `4004` means no private
  chat exists with that user yet.
- `message_history` — recent clean messages of one session. Requires
  `sessionId`; `limit` defaults to 1; page backwards with `beforeId` = the
  oldest message ID from the previous page. History contains plain text and
  approval-family cards; tool/status/binding process cards are filtered out.
- `message_search` — keyword search inside one session. Requires `sessionId`
  and a real `keyword`; pages like `message_history`.

Pagination: `limit` (default 20, max 100) and `offset` for the two search
actions; `beforeId` for the two message actions. Results include `has_more`.

## Rules

1. Parse the request into exactly one action and validate required fields
   before calling.
2. If both `id` and `keyword` are given the backend prioritizes `id`; send
   only one unless you explicitly want exact-match behavior.
3. Never invent a `sessionId`. For message history or in-session search with
   no known session, resolve it via `session_search` first — if several
   sessions match, present the candidates and let the user choose.
4. One call per page. Keep paging only when the user asked for everything,
   the target is still unresolved, or one page is clearly insufficient; keep
   the same filters while paging. When you stop early, say the result is
   partial.
5. On errors, report the exact failure and fix; do not retry with guessed
   parameters:
   - `403/20011` — missing scope; ask the owner to grant it in the agent
     permission page.
   - `401/10001` — invalid key/auth; check agent config or rotate the key.
   - `403/10002` — agent not active or invalid provider type.
   - `400/10003` — invalid or missing parameters.
   - `404/4004` — session does not exist or is not visible.

## Response style

State the result first and include the key identifiers (`peer_id` /
`peer_type` for contacts, `session_id` for sessions, message IDs for
history). Never hide scope or auth errors behind generic wording.
