Skip to content

System Prompt

Michael Elliott edited this page Mar 14, 2026 · 1 revision

System Prompt Architecture

The system prompt is the most critical component of TITAN — it's the instruction set every AI model receives before processing any message. Its quality directly determines whether models reliably use tools or fall back to generating text responses.

v2026.10.27 completely redesigned TITAN's system prompt architecture based on research across Ollama, OpenAI, Anthropic, Gemini, LangChain, AutoGen, and CrewAI.


Prompt Structure (Priority Order)

The system prompt is assembled dynamically at runtime in src/agent/agent.tsbuildSystemPrompt(). Critical rules appear first.

1. ## Tool Execution — HIGHEST PRIORITY     ← NEW: ReAct + MUST/NEVER + examples
2. ## CRITICAL: Your Identity               ← TITAN branding, model ID
3. ## About You                             ← JARVIS personality
4. ## Core Capabilities                     ← tool categories
5. ## Behavior Guidelines                   ← conciseness, proactivity
6. ## Security                              ← key/secret protection
7. ## Continuous Learning                   ← accumulated patterns + strategies
8. [Adaptive Teaching]                      ← user skill level context
9. [Custom Instructions]                    ← from config.agent.systemPrompt
10. [Workspace context]                     ← AGENTS.md, SOUL.md, TOOLS.md, persona
11. [Memory context]                        ← preferences from memory store
12. [Personal context]                      ← relationship memory
13. [Knowledge graph]                       ← temporal graph memories
14. [Self-awareness]                        ← model ID, fallback info, stall detection

Why this order? LLMs prioritize earlier content in the context window. By putting tool enforcement first, we ensure every model processes "call write_file for files, call web_search for research" before its default "respond with helpful text" behavior.


Tool Execution Section (Top of Prompt)

## Tool Execution — HIGHEST PRIORITY
You are an AI agent. Your PRIMARY function is to execute tasks using tools.

ReAct Loop — follow this for EVERY task:
1. THINK: What information or action is needed? Which tool handles this?
2. ACT: Call the tool with the correct parameters
3. OBSERVE: Read what the tool returned
4. REPEAT until the task is fully complete, then give a concise summary

MUST — non-negotiable rules:
- MUST call web_search + web_fetch for ANY factual question
- MUST call write_file or edit_file when asked to create/save any file — NEVER output as text
- MUST call shell for commands, scripts, or system state checks
- MUST call tool_search if you don't see the right tool

NEVER:
- NEVER output file content as text when write_file should be called
- NEVER generate current data from training — use web_search
- NEVER tell the user to visit a URL — fetch it yourself

Examples:
❌ Asked to write a file → output content as text in reply
✓  Asked to write a file → call write_file(path="...", content="...") immediately

❌ Asked to research X → "Based on my knowledge..."
✓  Asked to research X → call web_search("X"), then web_fetch on top URLs

Task-Aware Dynamic Injection

After the base prompt is built, processMessage() detects the task type and appends specific enforcement blocks:

Pattern Injection
"write/save/create ... file/report/md" [TASK ENFORCEMENT — FILE WRITE] — MUST call write_file
"research/search/find/current/latest" [TASK ENFORCEMENT — RESEARCH] — MUST call web_search + web_fetch
"run/install/execute ... command/script" [TASK ENFORCEMENT — SHELL] — MUST call shell

When task enforcement fires, it also activates API-level tool_choice forcing on round 0 (see below).


API-Level Tool Forcing

On round 0, when task enforcement is active and tools are available, TITAN passes the tool_choice parameter to force at least one tool call regardless of the model's default behavior:

Provider Parameter Value
OpenAI / OpenAI-compatible tool_choice "required"
Ollama tool_choice "required"
Anthropic tool_choice { type: "any" }

This applies only on round 0. Subsequent rounds use the model's default ("auto").

Config flag: agent.forceToolUse: true (default). Set to false to disable.


Cloud Model Compression

When using Ollama cloud models (:cloud suffix, e.g. qwen3.5:397b-cloud) with tools, the full system prompt is compressed to avoid token limits. The compression in src/providers/ollama.ts → compressSystemPrompt() preserves in this order:

  1. Full Tool Execution section — the enforcement rules are never removed
  2. Identity section (shortened to 3 lines)
  3. "Tools Available" brief reminder
  4. "Behavior" two-line summary

Character limit: 3500 (was 2000 in v2026.10.26 — raised to ensure enforcement rules fit).


Sub-Agent System Prompts

Each sub-agent template in src/agent/subAgent.ts → SUB_AGENT_TEMPLATES has a dedicated system prompt. All 11 templates were rewritten in v2026.10.27 to include:

  1. Role definition
  2. Available tools with "when to use each" guidance
  3. MUST rules specific to this agent's tool set
  4. Output format expectation
Agent Tier Primary Tools Key Enforcement
Explorer smart web_search, web_fetch MUST call web_search first, MUST web_fetch ≥2 URLs
Coder fast shell, read_file, write_file, edit_file MUST read_file before edit, MUST write_file for all code
Browser fast browse_url, web_read, web_act MUST browse_url first, MUST read/screenshot before acting
Analyst cloud web_search, graph_search, graph_remember MUST search before analyzing, MUST graph_remember findings
Researcher cloud web_search, web_fetch, rag_search 5-step methodology, MUST cite sources
Reporter cloud read_file, write_file MUST write_file — output is a file, not text
Fact Checker smart web_search, web_fetch MUST search every claim, MUST fetch full sources
Dev Debugger smart shell, read_file, code_analyze MUST read code first, MUST verify fix with shell
Dev Tester fast shell, read_file, write_file, code_exec MUST write test files, MUST run them
Dev Reviewer cloud read_file, code_review MUST read each file, 2+ review passes
Dev Architect cloud read_file, code_analyze, write_file MUST read+analyze before proposing changes

Voice Mode Override

When channel === 'voice', a high-priority override is appended after the base prompt:

## VOICE MODE — CRITICAL (HIGHEST PRIORITY)
- Maximum 2-3 short sentences. NEVER exceed 50 words total.
- Plain spoken English only — no markdown, no bullets, no code
- Orpheus TTS emotion tags: <laugh>, <chuckle>, <sigh>, <cough>...

Customization

Config options in ~/.titan/titan.json:

{
  "agent": {
    "systemPrompt": "Additional custom instructions appended to the base prompt",
    "persona": "default",
    "forceToolUse": true
  }
}

Workspace files (loaded from ~/.titan/):

  • AGENTS.md — agent-specific instructions
  • SOUL.md — personality and tone overrides
  • TOOLS.md — tool-specific guidance

Personas — stored in assets/personas/*.md, selectable via config or /persona command.


Files

File Role
src/agent/agent.ts buildSystemPrompt() assembles the full prompt; task-aware injection in processMessage()
src/agent/subAgent.ts SUB_AGENT_TEMPLATES — 11 sub-agent prompts
src/providers/ollama.ts compressSystemPrompt() — cloud model compression
src/providers/openai.ts tool_choice: "required" on enforced rounds
src/providers/anthropic.ts tool_choice: {type: "any"} on enforced rounds
src/agent/selfAwareness.ts buildSelfAwarenessContext() — model/fallback section
src/config/schema.ts AgentConfigSchemasystemPrompt, persona, forceToolUse

Clone this wiki locally