Desktop environment for AI agents

You don't talk to the AI.
You give it a task.

A modern model can plan, run code, edit projects and chain actions. A chat window turns that into a terminal you hand-drive. Enactive is the environment the agent works in instead — the model is the engine, this is the workspace.

  • Local models via Ollama
  • Anthropic & OpenAI-compatible
  • Every action recorded

The desktop window, drawn from the application's own layout and labels.

Command→ Intent→ Context + Environment→ Planner→ Orchestrator→ Worker (role)→ Provider→ Tool→ Artifact→ Event→ RunRecorder

How it works

Four entities replace the message thread

Workspace → Task → Worker → Artifact. Chat stays, as a side console for quick nudges — it is no longer where the work happens.

01

A task, not a message

The unit of interaction has a real lifecycle: New → Planning → Executing → Waiting for you → Completed. You can close the laptop in the middle of it.

02

Work state, not thinking out loud

Structured progress — found 14 files → identified the bottleneck → 3 tests passed → changes ready. Never raw chain-of-thought.

03

The artifact is the centre

A run ends in a diff, a file set, a report — with Apply, Review and Reject on it. Not fifty chat bubbles you have to read.

04

You are asked only at real forks

The agent runs the plan end to end and stops where the autonomy tier says to ask — showing the whole action, never a summary of it.

What's in it

Built for agents that actually do the work

Everything below is implemented and running today, not a roadmap.

Plans are real graphs

The planner emits step dependencies. The scheduler runs steps by readiness, cascade-skips dependents when one fails, and detects cycles.

An autonomy slider you can trust

Observe → Suggest → Execute → Autonomous. Shell and PowerShell ask first; you can remember an approval for the session or for the workspace.

Workers as roles

Developer, Reviewer (read-only), Ops, Writer — each with its own tool allowlist, permission level and model. You pick a role, not a model.

The agent sees the machine

Read-only discovery of host and OS, Git branch, remote and dirty state, Docker, WSL and services — fed into the prompt and shown in the UI.

A timeline, not a chat history

Decisions and artifacts across every run fold into a persistent project memory, so the next run starts knowing what the last one did.

Inbox and background runs

Drop ten tasks in the evening. The agent runs headless, declines to guess at forks, and leaves results and questions in your Inbox.

Nothing is written behind your back

Optional staging: every write becomes a diff you Apply or Reject before it touches the disk.

A log that shows the wire

Every prompt, response, tool call and event — with a raw-wire option. Live window plus a daily file, so a bad run can be read afterwards.

Local by default

API keys are DPAPI-encrypted in settings.json. Run history, memory and approvals live in .enactive/ inside your own workspace.

The fork

Autonomous by default.
Human where it matters.

The agent scans, plans, writes and tests on its own. Where the tier says to ask, it stops and shows exactly what it is about to do — the whole command, the whole path — instead of guessing and reporting success. Some tools ask at every tier, however far the slider is pushed: deleting a file leaves an absence, and an absence is the hardest thing to notice afterwards.

That pause is the whole point of the autonomy slider, and it is the gap in the logo.

From anywhere

Start it from your phone.
It runs on your machine.

Sign in to the gateway — remote.enactive.dev, or one you deploy — from any browser. The desktop application connects outward to it: nothing listens on your computer, and no port is opened. The task runs through the same engine as one typed into the app.

End-to-end encrypted. What you write and what your computer reports back is encrypted on your own devices and on your computer; the gateway stores and forwards ciphertext it cannot read. A computer is paired with a code you carry to it yourself, a phone is added with a one-time link or QR, and every command is sealed with a key the service never holds — so the service cannot start a task, answer a permission or read a result.

A permission appears on the task's own card, so you answer it next to what you asked for. Both ends are asked at once and the first answer wins: sitting down at the computer always works, whatever the phone is doing.

  • Sign in with GitHub or Google; the keys stay on your computer and your devices
  • Remove a device and the computer changes its key: that device reads nothing new
  • No shell from the web, at any tier
  • The whole action, before you allow it

How remote access works ↗ What the service can and cannot see ↗ Connect to gateway ↗

Team of models

A team, not a model picker

Configure any number of providers and bind a model to each phase of a run. One local model doing everything is just the simplest case of the same setup.

Plan

A reasoner turns the intent into a dependency graph and rates every step trivial, normal or complex.

Execute

Steps route themselves by that rating: trivial to a light model, normal to the worker's own, complex to the heavy one.

Review

Each step is judged against the real tool transcript — not the model's summary of it. On a fail, the step is retried with the feedback.

Ollama — native, per-run num_ctx Anthropic OpenAI-compatible OpenRouter · Groq · a second Ollama…

The awkward parts are handled for you: local <think> is off by default, Anthropic's temperature is dropped for models that reject it, max_tokens is auto-sized to each model's real cap, a truncation guard stops a half-written tool call from looping, and writes can be verified by reading the file back.

Architecture

Light on dependencies, on purpose

Seven projects on .NET 10. Core, Providers, Tools, Agents and the console host pull in zero external NuGet packages. Only storage and the Avalonia UI have dependencies at all.

  • Core — domain and abstractions only: Intent, Plan and PlanStep as a DAG, Worker, Decision, Permissions, Memory, Inbox. No transport types.
  • Providers — OpenAI-compatible, Ollama native and Anthropic behind one factory, with logging and a wire tap.
  • Tools — files, run_command, run_powershell, git and docker, each gated by permission level.
  • Workspace — run stores in SQLite, MySQL or JSON; artifact staging; memory; inbox; the environment probe.
  • Agents — Orchestrator, Planner, DagScheduler, the evidence-aware Reviewer, BackgroundRunner.
  • App.Console and App.Ui — a headless host and the Avalonia desktop UI.
App.Ui Avalonia desktop App.Console headless host Agents Orchestrator · Planner · DagScheduler · Reviewer Providers the models Tools the machine Workspace what happened Core domain model + abstractions · zero external packages every layer depends downward, and nothing depends on a host