Files
autocomplete-model/daemon
HarvmasterandClaude Opus 5.5 d246fb9349
ci / build (push) Canceled after 0s
Models stage-d (default) + stage-e (next-edit companion); extension 0.6.1
- stage-d: next-line / block-close / multi-line fixes, symbols format 2, TS errors in the header.
  Held-out: 0.426 exact / 0.700 edit sim (stage-c 0.405 / 0.689); block close 0.27 -> 0.79.
- stage-e: next-edit (80% exact region rewrites, abstains on 100% of no-edit samples).
- Manifest: nextEditModel (companion) and nextEditFormat (older extensions ignore it, so they
  never use next-edit with the empty-output deletion bug).
- Daemon: next-edit served by the companion model in a second llama-server, started after the
  main model loads.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J39imRDT8L7xYbWzsVWd8A
2026-10-04 00:23:15 +00:00
..

acd: local completion daemon

Builds fill-in-the-middle prompts in exactly the format the models were trained on (it shares ../shared/ with the training pipeline) and serves completions through a llama-server it manages. Editors talk to it over localhost HTTP. Design notes: ../docs/architecture.md.

You usually don't run this yourself: the VS Code extension bundles it and runs it in managed mode. Run it standalone for external mode, for other editors, or when developing.

Running standalone

Requires Node ≥ 22.18 (runs TypeScript directly) and a llama-server binary (brew install llama.cpp on macOS, or a llama.cpp release on Linux).

npm install
npm start                       # node src/main.ts --config acd.config.json
node src/acctl.ts status        # or: mode simple|symbols|raw · model <name> · on · off
npm run smoke                   # end-to-end test (needs the models from ../models, via Git LFS)

acd.config.json uses llama-server from your PATH with -ngl 99 (Apple GPU), and the models in ../models.

  • Linux / CPU: copy it to acd.config.local.json (git-ignored), set "binary" to your llama-server and "args": ["-t", "<physical cores>"], then run node src/main.ts --config acd.config.local.json.
  • Serving another machine (e.g. an M1 Max serving a laptop): set "host": "0.0.0.0" and point the editor's serverUrl at it, using daemon.mode: "external". There's no auth, so only do this on a trusted network.
  • Start on login: acd.service is a systemd user unit.

Context modes

mode prompt models
symbols repo header + language-service symbols (imports' signatures, repo-local types), from ../shared/symbols.ts, the same code that built the training data. Requires the editor to send workspaceRoot; otherwise the request runs as simple. stage-c
simple repo name + file path header stage-c
raw plain suffix-first FIM stage-b (spm), base-0.5b (psm)

The mode and model are global to the daemon and persisted in acd.state.json. VS Code, Zed and acctl all see the same toggle.

How symbols mode stays fast:

  • Context is built in a worker thread (one TypeScript language service per workspace) and cached per anchor: the file, the enclosing top-level declaration and the import block. While you type inside one function the header is identical and the KV cache keeps hitting; the smoke test shows the same ~2 re-processed tokens per keystroke as simple.
  • When the anchor changes, the daemon waits up to symbols.waitMs for fresh context, else uses the file's previous context (stale-while-revalidate).
  • Member completions after . are off (symbols.members): every . would change the header and force a cold prefill.

this. repair (thisRepair.enabled, any mode, needs workspaceRoot): when the identifier you're typing only resolves as a member of the enclosing class, the daemon completes as if this. were there. It returns replaceBefore + filterText so the editor replaces getU with this.getUser(id).

Edit recordings: POST /v1/edits appends opted-in editor edit events to recording.dir (default recordings/, git-ignored). These are the future training data for next-edit prediction.

API

  • POST /v1/fim: { requestId?, repo, path, languageId?, prefix, suffix, prefixLineOffset?, mode?, singleLine?, maxLines? } returns { text, mode, singleLine, timings, … }. A newer request cancels the in-flight one; closing the connection cancels too.
  • GET|PUT /v1/config: { enabled, model, mode }. Changing the model restarts llama-server.
  • POST /v1/feedback: editor events, written to the local log only when telemetry.enabled.
  • POST /v1/edits: { events } from editors that opted in to edit recording.
  • The /v1/fim request may include workspaceRoot (absolute path on the daemon's machine). Responses may include replaceBefore / filterText (the this. repair) and symbols: { status: hit|fresh|stale|none, items }.
  • GET /health