Proactive Mode (Phase 77.20)
Proactive mode lets an agent run autonomously between user messages.
Instead of waiting for a new inbound event, the runtime injects periodic
<tick> prompts and the model decides whether to do work now or call
Sleep { duration_ms, reason }.
Configuration
Enable at agent level or per binding (inbound_bindings[].proactive):
proactive:
enabled: true
tick_interval_secs: 600
jitter_pct: 25
max_idle_secs: 86400
initial_greeting: true
cache_aware_schedule: true
allow_short_intervals: false
daily_turn_budget: 200
Per-binding override replaces the full proactive block for that binding.
Sleep Tool
Sleep is the canonical way to wait in proactive mode.
Do not use shell sleep for this.
- Bounds:
duration_msis clamped to[60_000, 86_400_000]. - Wake-up: runtime injects a synthetic
<tick>with elapsed time + reason. - Interrupt: real inbound user messages cancel pending sleep immediately.
Inbound Queue Priority
Inbound events can optionally carry priority in payload:
now— highest priority (urgent interrupt)next— default priority (normal user input)later— deferred background notifications
When multiple messages are batched in the same debounce window, runtime
processes them in now > next > later order, preserving FIFO within
each priority class.
now also bypasses debounce delay and flushes immediately.
If now arrives during an in-flight turn, runtime preempts that turn and
runs the now message first.
Cache-Aware Scheduling
When cache_aware_schedule: true, runtime biases sleep duration to avoid
the Anthropic cache dead-zone:
<= 270_000ms: keep as-is (cache warm window).270_001..1_199_999ms: snap to270_000or1_200_000(nearest).>= 1_200_000ms: keep as-is.
Daily Tick Budget
daily_turn_budget limits proactive tick-driven turns per 24h window.
0means unlimited.- When exhausted, wake-ups are suppressed and re-armed using the effective tick interval.
This prevents runaway autonomous loops from burning quota.
Telemetry
Prometheus counter:
nexo_proactive_events_total{agent,event}
Events:
tick.firedsleep.enteredsleep.interruptedcache_aware.snapped
Relation to agent_turn Poller
Phase 20 agent_turn is cron-driven external scheduling.
Proactive mode is model-driven self-pacing inside a live goal.
They are complementary and can coexist across different bindings.