Desktop environment for AI agents · .NET 10 · Avalonia

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
GATE · DEVELOPER ● Running
TASK
Add a MySQL replica health probe
  • Read the replication config
  • Probe lag on 3 instances
  • Write Probe.cs and its test
  • Review against the transcript
CURRENT ACTION
Reading StationCnfWriter.cs
Apply Review Reject
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 raises a decision card when the choice is genuinely yours — with the options and a recommendation.

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. When it reaches an ambiguity it cannot resolve honestly, it stops and asks — with the options laid out and a recommendation — instead of guessing and reporting success.

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

DECISION REQUIRED ● Waiting

The replica on ate-db-02 is 40 s behind. Probing it will hold a read lock for about a second.

OPTION A
Probe anyway — the lock is short
Recommended
OPTION B
Skip this instance and report it
Choose A Choose B

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