---
title: "Agents"
---

> Documentation Index
> Fetch the complete documentation index at: https://truememory-docs.mvstg.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Agents

An **agent** is a server-side configuration that decides how Truememory handles a chat request: which system prompt pipeline runs, which server-side tools are available, whether memory is read and written, and whether safety checks apply. You pick one per request with the `X-Agent-Id` header; if you never send the header, you get the general-purpose `chatbot` and can ignore this page entirely.

:::note[Agents are not personas]
An agent is *infrastructure* (a processing pipeline, fixed per instance). Your user's named AI companion — its name, personality, avatar — is a [persona](/ai-gateway/personas/), which is *data* the agent loads at request time. "The user's agent" in app language means their persona.
:::

All requests require a Bearer token from [Truememory Auth](/authentication/overview/).

## Selecting an Agent

Pass the `X-Agent-Id` header:

```bash
curl -X POST https://your-tie-host/v1/chat/completions \
  -H "X-Agent-Id: research-assistant" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"model": "anthropic/claude-sonnet-4-5", "messages": [{"role": "user", "content": "Hello"}]}'
```

If omitted, the default agent (`chatbot`) is used.

## Available Agents

| Agent | Description | Memory | Safety |
|-------|-------------|--------|--------|
| `chatbot` | General-purpose chatbot | shared | none |
| `onboarding` | Unified identity field collection — runs before memory is established | none | none |
| `eliza` | AI wellness coach — nutrition guidance, meal logging, supplement tracking | shared | none |
| `research-assistant` | Web search and calculator | shared | LlamaGuard |
| `rag-assistant` | Database search (RAG) | isolated | LlamaGuard |
| `command-agent` | Command execution | none | none |
| `bg-task-agent` | Background task processing | none | none |

- **Memory: shared** — memories are accessible across all agents that use the shared pool.
- **Memory: isolated** — memories are scoped to that specific agent. See [Memory](/memory/overview/) for details.
- **Safety: LlamaGuard** — user inputs and agent outputs are checked against Meta's Llama Guard content safety classifier before processing. Requests flagged as unsafe are rejected.

Memory scope is configured per agent — clients cannot override it. All agents support client-side tool calling via the `tools` parameter.

### Onboarding Agent

A unified identity-collection agent that runs the same field set across all apps. Use it to collect a user's identity fields through a natural one-question-at-a-time conversation, before the user has memory established. See the full guide at [Platform → Onboarding](/platform/onboarding/).

**What it collects (unified field set):**

| Field ID | Default Question |
|----------|-----------------|
| `preferred_name` | "What should I call you?" |
| `date_of_birth` | "When were you born?" |
| `location` | "Where in the world are you based?" |

Apps can override the question text for any unified field and append their own app-specific questions — all via `skill_instructions`. An app with its own flow can also skip the unified fields it doesn't list (`include_unified_fields: false`), add its own `rules`, and drop the final confirmation turn (`confirm_before_complete: false`) — see [Asking only your own questions](/platform/onboarding/#asking-only-your-own-questions).

**`skill_instructions` format (JSON):**

```json
{
  "acknowledge_source_app": true,
  "questions": [
    { "id": "preferred_name", "question": "What should we call you?" },
    { "id": "location", "question": "Where in the world are you based?" },
    { "id": "currentFocus", "question": "What are you focused on right now?" }
  ],
  "already_captured": {
    "preferred_name": "Julio"
  }
}
```

| Field | Description |
|-------|-------------|
| `questions` | App's question list. Unified field IDs override the default text; unknown IDs become app-specific questions appended after unified fields |
| `already_captured` | Fields already collected in a previous session (for resume). Truememory skips these |
| `acknowledge_source_app` | When `true`, the agent greets the user with "I already know a bit about you from [previous app]" if prior data exists |

**Merge rules:** Truememory always collects all unified fields — apps cannot drop them. Apps control question wording and order. App-specific questions always appear after unified fields.

**Observable events (in SSE stream):**

The onboarding agent emits four observable tool calls through OpenAI-compatible streaming chunks (same shape as any chat-completions tool call):

After each field is answered — appears inside a `delta.tool_calls` chunk:

```json
{"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_abc","type":"function","function":{"name":"capture_field","arguments":"{\"field_id\":\"location\",\"value\":\"Asia/Kuala_Lumpur\"}"}}]}}]}
```

When the user explicitly opts out of an optional question — store as an opt-out signal:

```json
{"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_skp","type":"function","function":{"name":"skip_field","arguments":"{\"field_id\":\"currentFocus\",\"reason\":\"privacy\"}"}}]}}]}
```

When all fields are collected — terminal success event:

```json
{"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_xyz","type":"function","function":{"name":"onboarding_complete","arguments":"{\"fields\":{\"preferred_name\":\"Julio\",\"date_of_birth\":\"1995-05-23\",\"location\":\"Kuala Lumpur\"}}"}}]}}]}
```

User stopped early OR safety cap fired — terminal partial event:

```json
{"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_abr","type":"function","function":{"name":"onboarding_aborted","arguments":"{\"fields\":{\"preferred_name\":\"Julio\"},\"reason\":\"user_stopped\"}"}}]}}]}
```

- `capture_field` — per-field progress event for live UI feedback (checkmarks, progress dots). Values may still be corrected by the user, **so don't persist on this event**.
- `skip_field` — fires when the user opts out of an optional question. The field will be absent from the final `onboarding_complete` payload. Persist as an opt-out flag if you need to remember the user's choice.
- `onboarding_complete` — terminal success event. **Only persist on this event.**
- `onboarding_aborted` — terminal partial event (user opted out, malformed config, or 20-turn safety cap). Treat as partial data; route to a fallback rather than auto-persisting. Inspect `reason` to distinguish — `"max_turns_exceeded (...)"` indicates the safety cap fired.

After `onboarding_complete`, your app shows the user a confirmation screen. On confirm, write to auth metadata — split by ownership:

- **Unified fields** (`preferred_name`, `date_of_birth`, `location`) → `PATCH /auth/me` (with `metadata` field)
- **App-specific fields** (anything else) → `PATCH /auth/me/app-metadata?app=your_app`

Both endpoints take the user's Truememory Bearer token — the same `Authorization: Bearer $TOKEN` you use for chat completions. See [Platform → Onboarding](/platform/onboarding/#after-confirmation) for the full payload shapes.

**Example request:**

```bash
curl -X POST https://your-tie-host/v1/chat/completions \
  -H "X-Agent-Id: onboarding" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{
    "model": "anthropic/claude-sonnet-4-6",
    "messages": [{"role": "user", "content": "Hi"}],
    "stream": true,
    "persona_id": "your-companion-persona-id",
    "skill_instructions": "{\"questions\": [{\"id\": \"location\", \"question\": \"Where in the world are you?\"}], \"already_captured\": {}}"
  }'
```

> The onboarding agent has **no memory** — it runs before the user's memory graph is established. Confirmed field values should be written by your app backend to auth metadata after the user confirms on the confirmation screen.

---

### Eliza (Wellness Coach)

App-specific agent for the Vibrantly app: evidence-based nutrition guidance with meal and supplement logging via **client-side tools** (your app defines them in `tools` and executes the returned `tool_calls` — see [Tool calling](/ai-gateway/features/tool-calling/)). Other apps should not select this agent; its behavior is owned by Vibrantly.

---

## Message Compression

Moved — compression is a per-request chat feature, not an agent concern. See [Message compression](/ai-gateway/features/message-compression/).

---

Query `GET /info` to see all agents on your instance:

```json
{
  "agents": [
    {
      "key": "chatbot",
      "description": "A simple chatbot.",
      "memory_enabled": true,
      "memory_scope": "shared"
    },
    {
      "key": "eliza",
      "description": "An AI wellness coach for the Vibrantly app — nutrition guidance, meal logging, and supplement tracking.",
      "memory_enabled": true,
      "memory_scope": "shared"
    },
    {
      "key": "research-assistant",
      "description": "A research assistant with web search and calculator.",
      "memory_enabled": true,
      "memory_scope": "shared"
    }
  ],
  "default_agent": "chatbot"
}
```

Source: https://truememory-docs.mvstg.com/ai-gateway/agents/index.mdx
