Profiles define the agent's identity, tools, and behaviour for a specific domain.
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
| 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.
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.
navi/profiles/my_profile.py: ```python from .base import AgentProfilemy_profile = AgentProfile( id="my_profile", name="My Profile", description="What this profile is for.", system_prompt="""Mode: ...
...""", 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]
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:
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 |