Autopilot for Delphi – Details

How does Autopilot compare with Embarcadero Kai?

They are not the same thing — and they work well together. Kai is Embarcadero’s agentic-AI add-on for RAD Studio. It writes code, compiles, and fixes compiler errors — all inside the IDE, on your source. The moment the app is built and running, Kai stops: it can’t press a button or read a label. That is the gap. Autopilot for Delphi lives on the other side of it — in the running app — and that’s exactly where Kai can’t go.

KaiAutopilot
Write code in the IDEyesno
Build, fix compiler errorsyesyes*
Drive and operate the running appnoyes
Debug / test the GUI (click, type, read state)noyes
Screenshot the running appnoyes

* Autopilot itself doesn’t compile — but it runs inside Claude Code, which writes and builds the code. So end to end, the Autopilot workflow does build and fix.

Run both and the loop closes with no human in the middle: Kai (or Claude Code) writes and fixes the code; Autopilot drives the running result and reports whether it truly works.


Everything above is what Autopilot does. Everything below is how it is built — technical detail, safe to skip.

How it works

Three small pieces and one pipe. Your app links in a tiny bridge unit; a separate server process speaks the Model Context Protocol to the AI; the two talk over a private Windows named pipe.

You add one unit and one call to your project:

uses
  Vcl.Forms,
  Autopilot.Bridge.Vcl,        // 1. add the unit (Autopilot.Bridge.Fmx for FireMonkey)
  FormMain in 'FormMain.pas' {frmMain};

begin
  Application.Initialize;
  Application.CreateForm(TfrmMain, frmMain);
  Autopilot.Bridge.Vcl.StartBridge;    // 2. start the bridge
  Application.Run;
end.

The bridge is wrapped in {$IFDEF AUTOPILOT}. You add that define to your debug build only — so release builds compile StartBridge to nothing. No thread, no pipe, no automation surface in production. Your shipped binaries are exactly as they were.

The AI sees your form’s real component tree and acts on it through a small set of typed tools (the full list is below). Because it reads and writes properties through RTTI directly, it works with any third-party control pack — DevExpress, TMS, anything — with no OCR and no fragile screen coordinates. Setup is a one-time registration of the server with your AI host — on Claude Code that’s a single line, claude mcp add autopilot -- C:\Path\To\Autopilot.Mcp.exe. From then on it auto-discovers your running app — no port to configure, no manual attach.

 

The tools the AI calls

No macro recorder, no script to maintain — under the hood it’s a small, typed toolset that the assistant calls straight from a chat session. Thirteen tools cover the whole operate-and-observe loop:

ToolWhat it does
list_treeEnumerate every form and control — names, classes, paths, text, enabled/visible state. The AI’s map of your app.
clickClick a button, or anything with an OnClick. Repeat N times in a single call; override the per-call timeout. An opt-in message mode presses a button that opens a modal dialog without blocking: the click is queued, the answer comes back at once, then dismiss_dialog closes the popup.
execute_actionFire a TAction directly — for shortcut-only actions and actions shared by several controls.
get_text / set_textRead and write Caption / Text / Lines on edits, memos and labels. Writing fires OnChange.
set_checkedToggle a checkbox or radio button; fires OnChange.
set_propertyThe Swiss-army knife: write any published property — Tag, Color, Position, ItemIndex, sets, even AI-friendly colors like clRed or #FF8000. Mistype a name and it hands back the full list of writable properties with their live values, so the AI corrects itself without another round-trip.
read_propertyRead any published property via RTTI — and what it returns is exactly what set_property accepts back.
wait_forPoll a property until it matches or times out — for async work (TTask, database queries, timers).
screenshotCapture the form as a PNG, for visual and layout checks.
attachPick a target when several apps are running. Usually unnecessary — every tool auto-attaches.
set_keep_awakeKeep the device screen on while the AI drives an Android target, so the OS doesn’t freeze the app mid-session. A no-op on Windows.
dismiss_dialogList and dismiss native OS dialogs (MessageBox, Task Dialogs, file dialogs) that the component tools can’t see — details in the next section.

The assistant bundles several of these into a single turn — find the control, type, click, then check the result — so a whole reproduce-and-verify sequence is one round-trip, not ten.

Native OS dialogs

A TForm.ShowModal dialog is an ordinary VCL/FMX form, so the component tools (click, set_text, …) drive it directly. A native OS dialog — Application.MessageBox, the Vista Task Dialog behind a default ShowMessage/MessageDlg, a common file dialog — is a raw Win32 window with no TComponent, so those tools cannot see it and return not_found. The dismiss_dialog tool reaches it through Win32 instead: it lists the dialogs that are up and dismisses one by clicking a button (by role, caption, or control id). A visible modal dialog runs a message loop, so the bridge still reaches the main thread to act even while the app looks blocked. And the click that opens the dialog doesn’t block either: the AI presses that button in message mode, gets its answer immediately, then dismisses the popup.

PopupHow the AI drives it
Your own TForm.ShowModalComponent tools — it is in Screen.Forms[]
ShowMessage / MessageDlg in a VCL-styled appComponent tools — it renders as a TForm
ShowMessage / MessageDlg, default (native Task Dialog)dismiss_dialog
Application.MessageBox, TOpenDialog / TSaveDialogdismiss_dialog

Windows targets only; against an Android FMX target dismiss_dialog reports supported:false.

What it deliberately doesn’t do

Autopilot for Delphi acts directly on your Delphi objects; it doesn’t fake Windows mouse and keyboard input. That’s a deliberate trade, and it has a flip side — bugs that only show up through the real input pipeline won’t reproduce through it. Things like:

  • Focus-change validation (OnExit, kill-focus handlers)
  • IME composition and Asian-language input
  • Keyboard accelerators that travel through the Windows message loop
  • Hover-driven UI (mouse-enter / mouse-leave)
  • Drag-and-drop started by a real mouse-down-and-move

A message-based click mode covers some of this for buttons; for full input-pipeline coverage you would pair Autopilot with a SendInput-style tool (TestComplete, Ranorex, AutoIt).

In return for that trade you get direct property access with no OCR and no fragile screen coordinates, sub-millisecond round-trips, and compatibility with any third-party control pack — because RTTI is universal.

Found a bug?

Get in touch via my About page. Every session writes a log to %TEMP%\Autopilot\<ExeName>-<PID>.log — every command in and out, plus the dispatch timings. Attach the one from a run that reproduces the problem and I’ll have what I need.

Scroll to Top