Repository navigation
One shared daemon per user, and masking on the OpenAI route - #89
Merged
Merged
Conversation
Every Redrob app that runs on this engine started one of its own: Cowork and Office spawned `redrob serve`, Design, Cut, CAD and Browser spawned `redrob acp`, so a person with three apps open ran three engines. docs/LOCAL-ENGINE-API.md section 3 described the alternative; this builds it. `redrob serve --register` is the daemon. It draws a secret per start, writes ~/.redrob/run/server.json (0600: id, version, url, port, pid, secret), and exits once nobody has been attached for --idle-exit minutes (default 10) or another daemon has taken the record over. `redrob service start|status|stop|restart` drives it by hand; `start --json` prints the record for a caller in another language. `redrob acp --attach` makes the ACP face a thin client of the daemon instead of an engine of its own. Attachments are counted at /api/clients (attach, heartbeat, detach, list), a new protocol group with its generated client and SDK bindings; an app whose heartbeats stop is dropped after 90 s, so a crashed app cannot pin the daemon. `/experimental/capabilities` grows `sharedDaemon`. `@redrob-labs/sdk/daemon` gives JavaScript apps `connectOrStart()` (a file read and a health check on the fast path; `redrob service start --json` only when there is no healthy daemon), `attach()` with the heartbeat built in, and `resolveRedrobBin()` with the documented resolution order. Separately, `POST /v1/chat/completions` now goes through the same PII masker as the agent runner. It called the provider directly, so a downstream app on this route had no masking at all while the switch said on. One vault per request: the caller sends real values, the provider sees placeholders, the answer is put back, streamed or assembled; the model tier asks the configured local model for names exactly as the runner does. Verified by hand with a dev daemon: service start/status/stop, reuse of a running daemon, attach, heartbeat, detach, 401 on a wrong secret, idle exit after the window with the record removed, and `acp --attach` answering ACP initialize while the engine pid is the daemon's. Tests: redrob 724 pass (daemon registry + clients registry, chat/completions masking, httpapi exercisers 223/223 in all three modes with the four new scenarios), core 1043 pass, sdk 1 pass, turbo typecheck 18/18.
its-janghoon
added a commit
that referenced
this pull request
Oct 13, 2026
Every job checked out `develop` by name when it started. A merge landing between dispatch and the tag step (#89 landed two minutes after today's release dispatch) meant the binaries were built from one commit and the tag pointed at another. The version job now records the commit it computed from, and the build and publish jobs check out that sha, so a release is one commit from version to tag. The tag push is by explicit ref and works from the detached checkout.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Builds section 3 of
docs/LOCAL-ENGINE-API.md: one shared engine per user, and closes a masking gap on the OpenAI-compatible route.Daemon
redrob serve --register: per-start secret,~/.redrob/run/server.json(0600: id, version, url, port, pid, secret), exits when nobody has been attached for--idle-exitminutes (default 10, 0 = stay up) or when another daemon takes the record overredrob service start|status|stop|restart;start --jsonprints the record for a non-JS caller (the launcher)redrob acp --attach: the ACP face becomes a thin client of the daemon instead of running an engine of its own/api/clients(new protocol group): attach, heartbeat, detach, list withidleForMs/idleExitAfterMs; attachments without a heartbeat for 90 s are dropped/experimental/capabilitiesgrowssharedDaemon: { version: 1 }@redrob-labs/sdk/daemon:connectOrStart(),attach()(heartbeat built in),currentDaemon(),resolveRedrobBin()docs/LOCAL-ENGINE-API.mdupdated to describe what is builtMasking
POST /v1/chat/completionsnow goes through the sameMaskas the agent runner. It called the provider directly before, so an app on this route had no masking while the switch said on. One vault per request; streamed and assembled answers are both put back; the model tier uses the configured local model as the runner does.Verified
By hand against a dev daemon (
REDROB_RUN_DIRin scratch):service start-> record with pid;/api/health200, attach/heartbeat/detach/list 200/200/204/404, wrong secret 401; a secondservice startreused the pid; idle exit after the 1-minute window with the record removed;acp --attachanswered ACPinitializewith the engine pid being the daemon's, not the ACP process's; SDKconnectOrStart+attachfrom a separate process.Tests
test/daemon.test.ts,test/server/chat-completion-mask.test.ts; help-text snapshot updated for the new flags)test:httpapiexercisers: 223/223 in coverage, auth and effect modes (4 new scenarios)bun turbo typecheck18/18Follow-ups (other repos)
Design engine-only, launcher engine card, cowork/office
connectOrStart, browser/cut/cadacp --attach.