Newer
Older
navi-1 / docs / profiles.md
@Eugene Sukhodolskiy Eugene Sukhodolskiy on 14 Apr 3 KB Add backend documentation

Profiles

Profiles define the agent's identity, tools, and behaviour for a specific domain.

Profile definition (navi/profiles/base.py)

@dataclass
class AgentProfile:
    id: str                          # unique identifier (used in API, sessions, switch_profile)
    name: str                        # human-readable name
    description: str                 # shown in profile selector
    system_prompt: str               # domain-specific instructions
    enabled_tools: list[str]         # tool names available to this profile
    model: str = "..."               # Ollama model to use
    temperature: float = 0.7
    max_iterations: int = 50
    planning_enabled: bool = False   # whether to run the planning phase before the loop
    llm_backend: str = "ollama"      # backend key in BackendRegistry

Built-in profiles

Profile ID Name Model Temperature Planning
secretary Personal Secretary gemma4:26b-a4b-it-q4_K_M 0.7 Yes
server_admin Server Administrator gemma4:26b-a4b-it-q4_K_M 0.2 Yes
smart_home Smart Home Assistant gemma4:26b-a4b-it-q4_K_M 0.3 Yes

All profiles have the same base tool set:

todo, scratchpad, switch_profile,
web_search, web_view, http_request,
filesystem, code_exec, terminal, ssh_exec, image_view,
memory_search, memory_forget,
reload_tools, write_tool, list_tools, tool_manual,
spawn_agent

User tools from tools/enabled.json are merged in on top of the profile's enabled_tools list.

System prompt construction

The final system prompt the LLM sees is:

{NAVI_PERSONA}

---

{profile.system_prompt}

NAVI_PERSONA is the global personality layer — loaded from settings.navi_persona or settings.navi_persona_file. It contains: personality, self-extension rules, planning/scratchpad instructions, delegation guidance, memory rules.

profile.system_prompt is the domain-specific layer: tool priorities, workflow rules, scratchpad section names, safety rules for that domain.

The system message is never stored in session.context. It is injected fresh on every LLM call. Profile switches take effect immediately.

Adding a new profile

  1. Create navi/profiles/my_profile.py: ```python from .base import AgentProfile

my_profile = AgentProfile( id="my_profile", name="My Profile", description="What this profile is for.", system_prompt="""Mode: ...

Tool priorities

  1. web_search — ...
  2. filesystem — ...

Scratchpad sections

  • findings, errors, plan

Safety rules

...""", enabled_tools=[ "todo", "scratchpad", "switch_profile", "web_search", "filesystem", "code_exec", "memory_search", "memory_forget", "reload_tools", "write_tool", "list_tools", "tool_manual", "spawn_agent", ], model="gemma4:26b-a4b-it-q4_K_M", temperature=0.5, planning_enabled=True, )

2. Register it in `navi/profiles/__init__.py`:
```python
from .my_profile import my_profile
ALL_PROFILES = [..., my_profile]

Profile switching

switch_profile tool updates session.profile_id in the DB. In run_stream(), after each tool execution batch, the agent checks if session.profile_id changed and reloads profile + tools. The switch takes full effect on the next LLM call within the same run.

Rules from the persona:

  • Don't switch for a single off-topic question.
  • Switch when the session domain clearly changes (e.g. coding → server admin).
  • Never switch back and forth repeatedly in one conversation.

Per-profile scratchpad sections

Each profile defines named sections appropriate for its domain:

Profile Scratchpad sections
secretary findings, sources, drafts
server_admin status, logs, errors, plan
smart_home state, config, errors