Aleph
Architecture

Harness

Think→Act loop, state machine, stop-hooks, context budget, and emergency compaction.

Harness

The AgentHarness drives the Think → Act loop for all Gateway chat requests. It is constructed by the Orchestrator and receives pre-resolved dependencies (SessionService, ToolService, Sandbox, AiProvider).

Location: src/harness/

Migration complete: The legacy src/agent_loop/ directory was deleted in Phase 7 (2026-04-21). All agent execution — including SubagentTool — now routes through Orchestrator → Harness.


Inner Loop Diagram

┌─────────────────────────────────────────┐
│              AgentHarness                │
├─────────────────────────────────────────┤
│  ┌────────┐   ┌────────┐   ┌────────┐  │
│  │PREPARE │──▶│ THINK  │──▶│RESOLVE │  │
│  │• Budget│   │ • LLM  │   │• Parse │  │
│  │• Context│  │ • Decide│  │• Decision││
│  │• Preflight│ └────────┘   └────┬───┘  │
│  └────────┘                      │      │
│                             ┌────┴───┐  │
│                             │  ACT   │  │
│                             │• Execute│  │
│                             │• Tools  │  │
│                             └────┬───┘  │
│                                  │      │
│                             ┌────┴───┐  │
│                             │FINALIZE│  │
│                             │• Eval  │  │
│                             │• Compress││
│                             │• Decision││
│                             └────────┘  │
└─────────────────────────────────────────┘

Core Structure

pub struct AgentHarness {
    deps: HarnessDeps,              // All dependencies injected at construction
    hit_limit: AtomicBool,          // Set when context budget forces early exit
}

AgentHarness is stateless — all mutable state lives in SessionService. Dependencies are injected at construction via HarnessDeps:


State Machine

The Harness trait defines the Think→Act contract. TurnState is a simple binary outcome:

VariantMeaning
ContinueThe session should run another Think→Act turn
DoneThe session is complete; no further turns needed

The outer loop (Harness::run) repeatedly calls run_turn until it returns Done or the cancel token fires.


Source Map

FileRole
src/harness/agent.rsAgentHarness — concrete Think→Act implementation
src/harness/trait_def.rsHarness trait + TurnState + HarnessError
src/harness/deps.rsHarnessDeps — dependency bundle
src/harness/callback.rsHarnessCallback trait for event streaming
src/harness/loop_callback.rsLoopCallback / NoopCallback
src/harness/trace.rsTrace event types
src/harness/trace_sink.rsTraceSink trait for observability
src/harness/chain_context.rsChain-of-thought context management

Sleep Inhibitor

Each Think→Act turn acquires an IOPMAssertion of type PreventUserIdleSystemSleep with the reason string "Aleph agent loop". The assertion is held by an RAII InhibitorGuard whose Drop implementation releases it the moment the turn returns. Long-running agent turns can no longer be silently cut short by macOS putting the host to sleep mid-flight.

The guard is acquired at the start of run_turn in src/harness/agent.rs and released automatically when the function returns, whether it succeeds, returns an error, or is cancelled.

To verify that an assertion is active while a turn is in flight:

pmset -g assertions | grep "Aleph agent loop"

The assertion disappears from the list the moment the turn completes.

Implementation files:

  • PowerCapability trait: desktop/shared/src/traits/power.rs
  • macOS IOPMAssertion FFI: desktop/macos/src/sleep_inhibitor.rs
  • Agent loop wiring: src/harness/agent.rs::run_turn

See Also

On this page