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 | 20 |
Hard cap on tool-calling iterations per turn |
| 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 if empty. |
| 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 |
After each todo step is marked done, run a lightweight LLM check: "did the result satisfy the goal?" Adds ~1 LLM call per step. |
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_planning_enabled |
bool | false |
Sub-agents spawned from this profile also run the planning pipeline before their tool loop. |
| 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", "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.