Restructure into a monorepo: models, VS Code extension, daemon, shared
- models/: GGUFs (Git LFS), manifest.json, model card, Apache-2.0 LICENSE + NOTICE - extensions/vscode/: the Local Autocomplete extension (v0.5.0, publisher harvmaster) - daemon/: acd completion daemon (bundled into the extension; also runs standalone) - shared/: prompt layout + symbol extraction shared with the training pipeline - scripts/: make-model-release.mjs, publish-extension-release.mjs (Gitea releases) - README with quick start, settings, architecture, build and release instructions; MIT license for code; CHANGELOG The default model manifest URL moves to models/manifest.json. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
# acd: local completion daemon
|
||||
|
||||
Builds fill-in-the-middle prompts in exactly the format the models were trained on (it shares
|
||||
[`../shared/`](../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](../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](https://github.com/ggml-org/llama.cpp/releases) on Linux).
|
||||
|
||||
```sh
|
||||
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`](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`
|
||||
Reference in New Issue
Block a user