Skip to content

Modes & Daemon

Modes are named configurations that control how a Gee operates. A mode bundles together a model, agent, autonomy level, mission, guardrails, and identity into a coherent operational profile.

SettingDescriptionExample
ModelDefault AI modelsonnet, opus, haiku
AgentDefault agent archetypecoder, reviewer, architect
AutonomyActivation level and heartbeatautonomous with cron schedule
MissionGuiding purpose statement”Monitor CI and fix broken builds”
GuardrailsSafety constraints and limitsnever/always rules, cost caps
IdentityEvolving sense of selfAccumulated experience and priorities
InstructionsBehavioral rulesCustom system prompt additions
/mode # Show current mode, browse all modes
/mode create <name> # Create a new mode
/mode switch <name> # Switch to a mode
/mode delete <name> # Delete a mode

Each mode stores its config at ~/.gee-code/modes/{name}/:

{
"name": "night-watch",
"description": "Monitors CI pipelines overnight",
"model": "sonnet",
"agent": "coder",
"instructions": "Focus on build failures. Be concise in reports.",
"autonomous": {
"level": "autonomous",
"heartbeat_interval_seconds": 3600,
"guiding_mission": "Monitor CI and fix broken builds"
}
}
LevelBehavior
autonomousFull tool access, guardrails are the only fence
semi-autonomousRead freely, write tools need approval
supervisedSame as semi, in invoker’s context
noneInteractive only (default)

Autonomous modes activate on a heartbeat:

"heartbeat_interval_seconds": 3600

Activates every N seconds.

"heartbeat_cron": "0 */2 * * *"

Standard cron syntax. Overrides interval if both are set.

  1. Daemon checks if it’s time to activate
  2. Identity and mission loaded into context
  3. Assigned objectives surfaced
  4. Unread messages injected
  5. Gee executes within guardrail constraints
  6. Identity evolves based on what happened
  7. Activation timestamp recorded

Beyond heartbeats, modes can activate in response to events:

Trigger TypeExample
GitHubNew PR opened, issue created
File SystemConfig file modified
TimeCron expressions
CustomTrigger request files

The daemon is the background process that orchestrates all autonomous activations. It manages heartbeat scheduling, trigger listeners, rate limiting, hot-reload, and graceful shutdown.

Terminal window
gee-code daemon start # Start the daemon
gee-code daemon stop # Stop it
gee-code daemon status # Check what's running

On startup, the daemon:

  1. Scans ~/.gee-code/modes/ for modes with autonomous config
  2. Creates an AutonomousModeRunner for each
  3. Wires LLM executors (so activations make real AI calls)
  4. Starts trigger listeners for file-watch and event-based activations
  5. Begins the heartbeat scheduling loop

You can pause individual modes without stopping the daemon:

Terminal window
gee-code daemon pause analyst # Pause heartbeats and triggers
gee-code daemon resume analyst # Resume normal operation

A paused mode stays registered — its config and runner persist — but heartbeats skip it and trigger listeners are stopped. Any in-flight activation is cancelled when you pause.

The daemon tracks activation timestamps per mode and enforces rate limits. If a mode activates too frequently (due to rapid triggers), excess activations are skipped with a log message. This prevents runaway costs from misconfigured triggers.

Every 60 seconds, the daemon checks for configuration changes. If you edit a mode’s mode.json while the daemon is running, the changes take effect automatically — no restart needed. Hot-reload detects:

  • Changed autonomous configs (heartbeat interval, triggers, limits)
  • New autonomous modes that appeared since startup
  • Removed modes (cleaned up gracefully)

The daemon writes activation events to ~/.gee-code/daemon_events.jsonl. Other processes (like The Terminal’s Observability panel) can watch this file for real-time visibility into what the daemon is doing:

{"event": "activation_started", "mode": "analyst", "activation_type": "heartbeat", "ts": "..."}
{"event": "activation_result", "mode": "analyst", "status": "completed", "actions_count": 12, "ts": "..."}

When the daemon starts, it optionally launches a Companion server — a local HTTP endpoint that can receive inbound webhooks from the Gee platform. This lets external events (SMS, email, webhooks) route to running Gees even when no REPL session is open. See Companion & Gateway for the full architecture.

Disable companion with:

Terminal window
GEE_CODE_COMPANION=0 gee-code daemon start

The daemon respects both session-level and global model clamping:

  • Session clamp — inherited from the REPL’s /clamp when the daemon starts
  • Global clamp (/clamp all-on) — forces every daemon activation to use the specified model
  • Per-mode default — the model in mode config is used when no clamp is active

Global clamping also adjusts iteration limits — cheaper models get higher iteration budgets so Gees can accomplish more per activation.

When a Gee is busy with a long activation, inbound messages normally wait behind the activation lock. Orchestrator mode lets the Gee respond immediately via a fast triage call — without interrupting the main work.

{
"autonomous": {
"orchestrator_mode": true
}
}

See Orchestrator Mode for the full architecture.

Designate one Gee as the default for unaddressed SMS messages:

{
"is_prime": true
}

When you text without specifying a Gee name, the message routes to the prime Gee. See Prime Gee and the SMS Routing Chain for details.

A common pattern — multiple modes for different workflows:

Gee "dev-assistant"
├── Mode: "coding" (default)
│ autonomy: none, model: opus
│ -> Interactive coding sessions
├── Mode: "reviewer"
│ autonomy: semi-autonomous, model: sonnet
│ -> Auto-reviews PRs, asks before suggesting
└── Mode: "night-watch"
autonomy: autonomous, heartbeat: every 2 hours
-> Monitors CI, fixes builds, reports status