| name | foxctl Daemon |
| description | Agent daemon architecture, exec_mode routing, and LLM engine selection for reactive vs autonomous agents. |
Agent Daemon Engine Selection
The agent daemon routes to different execution engines based on exec_mode.
Engine Routing
exec_mode = "reactive" (default)
└── LLMChatEngine via companion.Service
- Provider: cerebras (default)
- Simple request/response
- Conversation memory (L0/L1/L2)
exec_mode = "autonomous" | "proactive"
└── LLMChatEngine via companion.Service
- Tool calling loop
- Multi-step reasoning
- Same provider support as reactive
Quick Reference
| Mode | Engine | Default Provider | Tool Loop |
|---|
reactive | LLMChatEngine | cerebras | No |
autonomous | LLMChatEngine | cerebras | Yes |
proactive | LLMChatEngine | cerebras | Yes |
Autonomous vs Proactive: When to Use
Autonomous Mode
Trigger: Responds to incoming messages (mailbox polling).
Use when:
- Agent should wait for tasks/questions
- Work is request-driven (human or other agent sends work)
- Research agents that answer queries
- Coder agents that implement assigned tasks
foxctl agent spawn --name "Researcher" --exec-mode autonomous
foxctl agent run <agent-id>
foxctl agent ask <agent-id> --question "Research the auth flow" --wait
Proactive Mode
Trigger: Self-initiates work based on schedule or conditions.
Use when:
- Agent should work without being asked
- Scheduled/periodic tasks (health checks, summaries)
- Background workers (indexing, cleanup)
- Monitoring agents (watch for conditions, alert)
foxctl agent spawn --name "Indexer" --exec-mode proactive
foxctl agent run <agent-id>
Decision Matrix
| Scenario | Mode | Reason |
|---|
| "Answer questions about codebase" | autonomous | Wait for questions |
| "Index all files every hour" | proactive | Self-scheduled work |
| "Implement task when assigned" | autonomous | Wait for assignment |
| "Monitor logs for errors" | proactive | Continuous watching |
| "Review PR when requested" | autonomous | Wait for request |
| "Generate daily summaries" | proactive | Self-scheduled |
Spawning Agents
Chat Companion (Reactive)
foxctl agent spawn \
--name "Luna" \
--role companion \
--exec-mode reactive \
--llm-provider cerebras \
--llm-model "llama-3.3-70b" \
--system-prompt @prompt.txt
foxctl agent run <agent-id>
foxctl agent ask <agent-id> \
--question "Hello!" \
--conversation-id "user-session-1" \
--wait
Autonomous Agent
foxctl agent spawn \
--name "Coder" \
--role coder \
--exec-mode autonomous \
--llm-provider openrouter \
--llm-model "anthropic/claude-sonnet-4-20250514"
foxctl agent run <agent-id>
Context Budget Control
Prevent runaway context accumulation with --max-context-tokens:
foxctl agent spawn \
--role researcher \
--prompt "Analyze the entire codebase" \
--exec-mode autonomous \
--max-iterations 25 \
--max-context-tokens 30000
Context Tracking
The engine logs per-iteration context to stderr:
[CONTEXT] iter=5 msgs=13 prompt_tokens=12820 completion_tokens=1676 total=14496 finish=stop
[CONTEXT] iter=6 msgs=15 prompt_tokens=31040 ...
[CONTEXT] budget exceeded: 31040 > 30000 limit, stopping
When budget is exceeded:
- Session stops with
StopReasonContextBudget
- Session status set to
error
- Any partial assistant response is captured
Session Continuation
Resume previous agent sessions with follow-up prompts:
foxctl agent resume <session-id> --prompt "Based on your findings, tell me more about X"
How It Works
- Turn Persistence: Each user/assistant turn is saved to
session_turns table during execution
- Resume Loading: Previous turns are loaded and included as "PREVIOUS CONVERSATION:" context
- Session Linking: New session linked to original via
session_edges (edge_type: "continues")
Turn Persistence
Agent sessions automatically persist turns:
session_id, turn_index, role, content_preview, tool_calls, tokens_used, timestamp
Use Cases
- Continue research after reviewing initial findings
- Ask follow-up questions about agent's analysis
- Refine tasks based on agent's output
- Chain multiple research phases
Provider Defaults
For reactive agents, resolution order:
agentRecord.LLMProvider - Agent-specific
opts.LLMProvider - Daemon flag
"cerebras" - Fallback default
For cerebras model:
agentRecord.LLMModel - Agent-specific
opts.LLMModel - Daemon flag
"llama-4-scout-17b-16e-instruct" - Default
Environment Variables
CEREBRAS_API_KEY=csk-xxx
OPENROUTER_API_KEY=sk-or-xxx
ANTHROPIC_API_KEY=sk-ant-xxx
OPENAI_API_KEY=sk-xxx
GEMINI_API_KEY=xxx
GROQ_API_KEY=gsk-xxx
Companion Memory (Reactive Only)
When exec_mode: reactive, companion memory is available:
| Layer | Window | Content |
|---|
| L0 (Vivid) | 24-48h | Full turns |
| L1 (Recent) | 7-14 days | Day summaries |
| L2 (History) | Permanent | Distilled context |
Enable via --enable-companion-memory or auto-enabled for role: companion.
Common Issues
"unsupported LLM provider" errors
The configured LLM provider is not supported or missing its API key.
Fix:
sqlite3 ~/.foxctl/storage/agents.db \
"UPDATE agents SET exec_mode='reactive' WHERE id='$AGENT_ID'"
foxctl agent spawn --exec-mode autonomous --llm-provider openrouter --llm-model "anthropic/claude-sonnet-4-20250514"
Memory not injected for companion
Check daemon logs for memory_enabled: false.
Fix: Run with --enable-companion-memory or ensure role is companion.
Code Locations
| Component | File |
|---|
| Engine routing | internal/agent/daemon/daemon.go:237 |
| Companion service | internal/context/companion/service.go |
| LLMChatEngine | internal/runtime/engine/llmchat_engine.go |
| Message handlers | internal/agent/daemon/handlers.go |
Related Skills
foxctl-agents - Multi-agent coordination
foxctl-memory - Memory system (named_memory, not companion)