Profiles define the agent's identity, tools, and behaviour for a specific domain.
navi/profiles/base.py)Each profile is loaded from a directory under navi/profiles/<id>/:
config.json — all fields belowsystem_prompt.txt — domain-specific instructionssubagent_system_prompt.txt — injected into subagents spawned from this profile (optional)config.json fields| Key | Type | Default | Description |
|---|---|---|---|
id |
str | required | Unique profile identifier (matches directory name) |
name |
str | required | Human-readable name shown in UI |
description |
str | required | Longer description shown in profile picker |
short_description |
str | "" |
One-line summary injected into every profile's system prompt (cross-profile awareness) |
full_description |
dict | {} |
Structured dict: specialization, when_to_use, key_tools keys |
| Key | Type | Default | Description | |
|---|---|---|---|---|
llm_backend |
str | "ollama" |
Backend key: "ollama", "openai" |
|
model |
str or list[str] | ["gemma4:31b-cloud"] |
Model priority list — first available wins. String is accepted and auto-wrapped. | |
temperature |
float | 0.7 |
Sampling temperature for main loop calls | |
max_iterations |
int | 10 |
Hard cap on tool-calling iterations per turn | |
top_k |
int \ | None | None |
Ollama sampling top_k |
top_p |
float \ | None | None |
Ollama sampling top_p |
num_thread |
int \ | None | None |
CPU threads for local inference. None = Ollama default |
| Key | Type | Default | Description |
|---|---|---|---|
enabled_tools |
list[str] | required | Tool names available in the main loop |
subagent_tools |
list[str] | [] |
Tools available to sub-agents spawned from this profile. Falls back to enabled_tools (full list) if empty. |
spawn_agent may receive an optional profile_id. If omitted, the subagent uses the parent session's current profile. If provided, the subagent uses the selected profile's model, prompt, planning flags, and subagent_tools/enabled_tools fallback.
| Key | Type | Default | Description |
|---|---|---|---|
think_enabled |
bool | true |
Pass think=True to LLM on every call (extended reasoning). Disable for latency-sensitive profiles. |
iteration_budget_enabled |
bool | true |
Inject remaining iteration count into context so the model knows when to wrap up. |
goal_anchoring_enabled |
bool | true |
Inject a goal-reminder system message every N iterations to prevent drift. |
goal_anchoring_interval |
int | 5 |
N for goal anchoring. |
anti_stall_enabled |
bool | true |
Detect looping without todo progress and inject a hard warning. |
anti_stall_threshold |
int | 8 |
Consecutive iterations without progress before stall warning fires. |
step_validation_enabled |
bool | false |
Reserved flag — todo validation is unconditional in the current implementation. |
adaptive_replan_enabled |
bool | false |
When a todo step is marked failed, trigger a re-planning pass. Depends on step_validation_enabled. |
The planning pipeline runs before the main tool-calling loop and produces a structured execution plan. It has three phases:
DIRECT to skip to execution immediately.REFLECT: yes.TOOL / AGENT / SELF and uses adaptive plan depth.| Key | Type | Default | Description |
|---|---|---|---|
planning_enabled |
bool | false |
Run the planning pipeline on every user message (not just the first). First-message planning always runs regardless of this flag. |
planning_mandatory |
bool | false |
true — the DIRECT shortcut is never offered to the model; all three phases always run. false — the model can output DIRECT in Phase 1 to skip straight to execution. First-message planning is always forced regardless of this flag. |
planning_phase1_enabled |
bool | true |
Enable Phase 1 (task analysis). When disabled, Phase 3 runs without analysis context. |
planning_phase2_enabled |
bool | false |
Enable Phase 2 structured review. Adds one LLM call only when Phase 1 signals REFLECT: yes. |
planning_phase3_enabled |
bool | true |
Enable Phase 3 (structured execution plan). When disabled, only Phase 1 (analysis) runs. |
| Key | Type | Default | Description | |
|---|---|---|---|---|
subagent_think_enabled |
bool \ | None | None |
Extended reasoning for sub-agents. None = inherit think_enabled from parent profile. |
subagent_planning_enabled |
bool | false |
Sub-agents spawned from this profile also run the planning pipeline before their tool loop. | |
context_providers |
list[str] | [] |
Extra context providers to inject for this profile (by name). Global providers are always injected. | |
mcp_servers |
dict | {} |
MCP servers referenced by this profile. Format: {"server_name": ["group1", "group2"]} or {"server_name": ["*"]} for all tools. |
|
is_admin_only |
bool | false |
If true, profile is hidden from non-admin users in the profile list. |
| ID | Name | Models (priority order) | Temp | Planning |
|---|---|---|---|---|
secretary |
Personal Secretary | gemma4:31b-cloud → gemma4:26b-a4b-it-q4_K_M | 0.65 | Yes |
server_admin |
Server Administrator | gemma4:31b-cloud → gemma4:26b-a4b-it-q4_K_M | 0.3 | Yes |
developer |
Developer | gemma4:31b-cloud → gemma4:26b-a4b-it-q4_K_M | 0.45 | Yes |
tool_developer |
Tool Developer | gemma4:31b-cloud → gemma4:26b-a4b-it-q4_K_M | 0.35 | Yes |
discuss |
Discussion | gemma4:31b-cloud → gemma4:26b-a4b-it-q4_K_M | 0.85 | No |
modeler_3d |
3D Modeler | gemma4:26b-a4b-it-q4_K_M → gemma4:31b-cloud | 0.35 | Yes |
All profiles share a base tool set. User tools from tools/enabled.json are merged in at runtime.
The LLM sees (injected fresh on every call, never stored in session):
{persona.txt content}
---
{profile system_prompt.txt content}
persona.txt — global layer: personality, CONTEXT FIRST principle, self-extension rules, scratchpad/todo/memory instructions, delegation rules.
system_prompt.txt — domain layer: tool priorities, workflow, safety rules for this profile.
navi/profiles/my_profile/config.json (minimal example):
{
"id": "my_profile",
"name": "My Profile",
"description": "...",
"short_description": "...",
"model": ["gemma4:31b-cloud", "gemma4:26b-a4b-it-q4_K_M"],
"temperature": 0.5,
"max_iterations": 20,
"enabled_tools": ["todo", "scratchpad", "mcp:navi-web:web_search", "filesystem"],
"subagent_tools": ["todo", "filesystem", "terminal"],
"planning_enabled": true,
"planning_mandatory": false,
"planning_phase1_enabled": true,
"planning_phase2_enabled": false,
"planning_phase3_enabled": true,
"think_enabled": true,
"iteration_budget_enabled": true,
"goal_anchoring_enabled": true,
"goal_anchoring_interval": 5,
"anti_stall_enabled": true,
"anti_stall_threshold": 8,
"step_validation_enabled": false,
"adaptive_replan_enabled": false,
"subagent_planning_enabled": false
}system_prompt.txt with domain-specific instructions.subagent_system_prompt.txt.switch_profile tool updates session.profile_id in the DB. After each tool execution batch, run_stream() checks for a profile change and reloads profile + tools. Takes effect on the next LLM call.
Rules (in persona): don't switch for a single off-topic question; switch when the domain clearly changes; never switch back and forth repeatedly.