Eugene Plexus's own chat app. It lets you chat with the models your Eugene install serves, and search the web while you do. It signs people in with Eugene. One person can use it with Eugene's passphrase, or a small business can use it with an account for each person.
Workbench is an app (a spoke), not part of the hub. It reaches Eugene the same way any other app does:
- one client key, used at the gateway's public OpenAI-compatible endpoints;
- sign-in with Eugene over OpenID Connect.
It holds no operator or node-enrollment credential. Node folder tools additionally use Workbench's sign-in registration and the initiating person's session, checked by Eugene for each operation. The core design is specs/docs/design/workbench-v1.md; node file helpers describe central hosting and per-person access.
Chrome, Edge and Firefox. Safari: checked with WebKit only.
See browser checks and known limits, including looping previews.
Install Workbench from Apps in Eugene's console. The install does three things:
- it makes Workbench's key;
- it registers Workbench to sign people in with Eugene;
- it uses a separate OS account where the node supports one. The core can also run on Docker, macOS and per-user installations. Its own local file and subprocess tools still require the isolated Windows/Linux service account; remote node folders run in the helper's account on their machine.
Open it from the same page.
For a central Workbench, enroll each file-serving machine as an ordinary Eugene node. In People → Files on your machines, enable file support, register existing folders, and assign each person read or text-write access. The node prepares its bundled helper automatically; no model or separate Workbench installation is needed there. Windows service and Linux system installations currently support file helpers. Select these folders per chat in Workbench; the browser needs no route to the desktop. See the setup and platform guide.
Workbench's settings are on its page in the console. One controls whether the owner may read the chats and media of the people the owner gives Workbench to (off by default). Three are for Memory: whether it is on, how many notes each person may keep, and whether notes may go to models that run outside a person's machines. Five are for documents: whether Workbench reads documents at all, the largest file it takes, how long a file may be and still be read whole, how many passages one person may keep, and whether passages of saved documents may go to models that run outside a person's machines. Three more are for search by meaning: which search model to use (Automatic, the default, picks the first one that runs on your own machines and is running now), whether the text of documents and of questions may go to a search model that runs outside your machines (off), and the most requests a minute adding meaning may make (30, so a chat never waits behind an import). Two more are for sorting what a search finds: which result sorter puts the best passages in order (Automatic, the default, picks the first one that runs on your own machines and is running now; Off leaves the passages as the search found them; a sorter outside your machines is used only if you name it and allow the text of documents to go outside), and Sort time, how long a sort may be expected to take (3 seconds: Workbench measures how fast the sorter reads, never while a question waits, and leaves the passages as found when sorting would take longer; a sort that is asked and does not answer within twice Sort time is given up on, and the sorter is left alone, whatever the size of the question, until a small test shows it answers again or Sort time is raised so that twice it is longer than the wait that was given up on).
Interactive results appear beside their answers. Open app runs a self-contained MCP App in an isolated view; forms use the local A2UI forms catalog. Both show requested server actions in a separate review with Allow once and Decline. Network/device-dependent apps keep their text fallback. This is a constrained MCP Apps renderer, not full browser conformance with the upstream sandbox model.
In an empty chat, Answer with selects normal chat, Workbench through AG-UI, or an authorized connected agent. Owners add connections and choose people in Manage agent connections. Runs support Stop, saved continuation and interrupt responses; reloading never resends a run. See the capability matrix and limits.
- Chats: answers stream as they arrive. You can Stop an answer, Try again on any answer, or edit any message. Each try and each edit is kept as a version: arrows on the message step between them, and every earlier version keeps the conversation that followed it.
- Finding chats: search chat names and browse Today, Yesterday, Previous 7 days and Older groups.
- Text drafts: unsent text survives chat switches and refreshes in the same tab. Drafts belong to the signed-in person and clear on send, deletion or sign-out. Attachments must be selected again after leaving a chat.
- Writing: the message box grows with your text. Drop files onto it or paste an image; upload progress says what is arriving and Send waits until it is ready.
- Reading and saving: Jump to latest returns to the newest answer, messages show their local time (hover for the date), and Copy confirms success or explains a blocked clipboard. Export chat saves a Markdown snapshot with text, reasoning, tool records, sources and attachment names; file contents are not included.
- Keyboard shortcuts: Ctrl+Alt+N starts a chat, Ctrl+Alt+F searches chat names, and Ctrl+Alt+M focuses the message box. On Mac, use Control+Option. The shortcuts are also listed in the page.
- Markdown and code: the model's reasoning is shown folded away.
- Attachments: images (PNG or JPEG), PDFs and audio (WAV or MP3). Each goes to a model that takes that kind of file.
- Tools: Search the web: this runs on the install's search account. When a search cannot run, the switch says why.
- MCP tools: the owner adds shared Streamable HTTP servers in Toolbox · Tools. Choose servers in a chat's settings, then approve or decline each proposed call. Credentials stay on the server. Pending approvals expire after 30 minutes; interrupted calls are never automatically repeated.
- Folder tools: use node folders assigned in Eugene's People page, or existing Workbench-host grants managed in Toolbox · Tools. Read-only is the default; text creation and editing are optional. Select folders per chat and approve each listing, read or write. File contents go to the selected model and remain in the chat.
- Memory: short notes about you that Workbench gives to the model in your chats, so you do not have to say them again. Say "Remember that I use metric units", press Remember this on any message, or write notes on the Memory page; "Forget ..." lists the notes it might mean and deletes only the one you pick. A chat's Memory chip says what the next message carries and opens a drawer with the exact text sent, what was left out and why, a switch for that chat, and Refresh memory. A chat keeps the notes it started with until you refresh them. Notes go only to models that run on your own machines unless you choose Send for this chat. Only you can read your notes: the owner cannot, even where the owner may read chats. Export them as Markdown or JSON, or delete them all.
- Documents: your own files, kept for searching. On the Documents page, add PDF, Word, Markdown, text, CSV, HTML and code files, many at once; each is read in the background and says where it stands (waiting, reading, ready, or why it was skipped). A chat's Documents chip turns searching on for that chat. Each question is searched for the words in it and, while a search model is running, for what it means, and the passages that match go to the model with the question. While a result sorter runs on your own machines and is quick enough, the best passages of both searches are put in order by it first (it reads each passage with its headings beside the question); otherwise the passages go in the order the search found them, and a sorter that is stopped or fails never stops a search. With no search model, search is by words only: the page says so, and links the owner to Eugene's console to get one (Workbench cannot download models). A document is found by its words at once and its meaning is added in the background: its row says how much is added and how long is left, or why it waits (the search model is not running, or the key is at its limit), or that no search model was running when it was read; the header says which search model is in use and where it runs, and offers Rebuild search when the model that built the search is not the one that is running. While a result sorter is putting the best passages in order, the header says so ("Searching by meaning and words, sorted by ..."), and a Result sorter notice under it says which one is in use, where it runs, how fast it reads (measured by quick tests, and from the sorts Workbench has made: it says which is most of it) and what a usual sort adds to an answer beside Sort time; when passages are not sorted it says why, in the server's words with the numbers (too slow for Sort time, one that did not answer in time and when it is asked again, one that is stopped, one that is outside your machines and not allowed), links the owner to Backends where a stopped sorter is started, and tells anyone else to ask the owner. A sorter that was never set up, or is turned off, is not mentioned. Sources under the answer lists the passages that were sent (file, page or lines, heading, whether found by words, by meaning or by both, the words they matched) and marks the ones the answer cites; it says what was sent, never what the model used. Test a question on the page shows the passages that would be sent, without asking a model, and for each one whether it was found by words, by meaning or by both, and where the sorter put it beside where words and meaning did, if one sorted them (the places, never a score), with how many passages it put in order and how long that took, or why they were not sorted (and Try one way at a time shows what each finds alone, in the order that way found it: a question that names its way is not sorted). Documents only answers from the passages alone: when nothing matches, Workbench says so itself and does not ask the model, and Ask the model anyway is there if you want it to. A long file you attach to a chat can be searched instead of read whole (Search it instead). Passages go only to models that run on your own machines unless you choose Send for this chat. Only you can read your documents: the owner cannot, even where the owner may read chats. Removing a document deletes the file, what was read from it and its entries in the search, and cannot be undone.
- Folders (in Documents): point your documents at a folder the owner gave you in Toolbox · Tools (the page lists them by name, never by where they are; Job Sites' folders cannot be added yet). Workbench only reads it: its files become documents of yours, kept in step with the folder, and a chat with Documents on finds them like any other, with Sources naming each by its folder and path. A folder is not watched: it is looked at again every few minutes (10 by default, a setting of the owner's) and when you choose Sync now, so a change can take that long to show, and a quick check misses an edit that keeps a file's size and time (Sync now with a deep check reads every file again and finds it). The folder's card says where it stands (waiting, syncing with how many files it has taken in, synced with when it was checked and when it will be next, a problem, not available, or withdrawn by the owner, which you Dismiss), how many files it has, how many are ready, being read or skipped (a first read of a big folder takes a while: the counts move as it goes), the last check, each file with its own reason when it was skipped, what was left out and why (names Workbench always ignores, hidden and temporary files, links it never follows, what a
.gitignorefile lists, folders too deep, files over a limit), and its rules: an ignore list written like a.gitignorefile (a pattern Workbench cannot use is refused in words), whether hidden files are read, and whether the folder's own.gitignorefiles are respected. Leave out on one file writes its path on the ignore list, so it does not come back. Remove folder takes its files out of your documents and never touches the folder or your access to it. Uploads and folders are counted apart. - Answers keep going with no tab open: an answer is saved as it arrives. Close the tab and come back, and it is there.
- Bins · Media: Images: make images with any image model the install serves, from a prompt or from reference images you bring in. The form offers only the settings the chosen model lists, and says where the model runs (your machines, or the account it bills). Requests run on the server, so a closed tab loses nothing. Each result shows the size asked beside the size that came back, can be sent to a new chat as a copy, and can be deleted.
- Bins · Media: Speech and Transcription: speak text in any voice the chosen model lists (or one you name, where it lists none), and play or download the clip. Turn a recording into text: choose a file, or record in the browser where the page allows a microphone (HTTPS, or on the computer Workbench runs on). A transcript shows when the model heard less than the whole clip, can be copied, and can start a new chat. Models that translate can give English instead.
- Bins · Media: Video: make a short video with any video model the install serves, from a prompt and, where the model takes one, a first frame from your bins. The form offers only the lengths and sizes the model lists. Sending asks first, with the price the provider lists (or says none is listed), because a video is paid. The job runs on the server and is listed under Work orders · Long jobs with how long it has run; Workbench keeps polling it through a restart, keeps the video the moment it is done, and shows what the provider billed. Stop ends the polling, but the provider may still make and bill the video.
Network MCP connections use HTTPS, except for loopback HTTP, with an optional bearer credential. They are shared with everyone signed into this Workbench. Tool results and arguments stay with the answer. Stopping or editing a chat does not undo actions already taken.
Local MCP servers are available to the install owner when the launcher confirms Workbench's own OS account. In Toolbox, save an absolute executable path, a JSON argument array and optional secret environment values. Start and check runs it once to discover tools. Selecting it for a chat starts a process for that answer, with approval for each call. At most four local processes can run at once; Stop and graceful shutdown close them. Failed calls are never automatically replayed.
Install the program and its dependencies separately, where Workbench's account can execute them; Workbench does not run a package installer or shell command string. On Windows use an .exe such as python.exe or node.exe, putting the script path in Arguments. Keep secrets in environment values, since process lists can show arguments. Stderr is discarded to keep third-party credential output out of shared logs.
Local servers are trusted code in Workbench's account: they can read its files, including people's chats, app credentials and granted folders. Their separate working folders are not sandboxes. Other people cannot list or use them. Per-person process isolation and OAuth sign-in to MCP servers remain later slices; see the MCP design.
Folder grants apply to Workbench's built-in file tools. The machine administrator must first give Workbench's service account access to the specific host folder; saving a grant does not change OS permissions. Windows uses the app's service identity; Linux needs a stable group and systemd configuration. Follow the folder provisioning guide.
Only the named recipient can use a grant. Removing it blocks pending calls but keeps files and prior chat results. File tools refuse links, special files, replaced folders and Workbench's private storage. Reads accept small UTF-8 text files; edits require the hash from a prior read and refuse changed content. Writes are in place: an interrupted or failed write may leave partial changes and is never automatically repeated. There are no delete, rename or execution operations.
The server is Python (FastAPI). The page is React and TypeScript, built by Vite.
uv venv --python 3.12 .venv
uv pip install --python .venv -e ".[dev]"
.venv/bin/pytest
cd web
npm ci
npm test
npm run build # writes src/eugene_plexus_workbench/static/python scripts/check-tools-sabotage.py checks that removing approval,
ownership, revocation and interrupted-call guards breaks the behavioral tests,
then restores the exact working files. Run it alone.
python scripts/check-scenes-sabotage.py does the same for the working scenes:
the scene gate, the scene beside the progress line, and the scenes' own policy.
Working scenes (Eugene at the bench while a model works) are animated SVGs
in web/public/scenes/, each listed with its phrase in web/src/lib/scenes.ts.
A scene is drawn by a language model, so web/src/scenes.test.ts gates every
file as text: no script or outside reference, a reduced-motion rule that stops
every loop, matching first and last keyframes, and at most 32 KB.
tests/test_scenes_browser.py renders each one in Chrome.
For system Chrome coverage,
build the page and set WORKBENCH_PLAYWRIGHT to a playwright-core installation
before running pytest; WORKBENCH_CHROME can override the browser executable.
The built page is gitignored on main. Eugene's app catalogue installs from a commit on the dist branch, which is main plus that build. A GitHub archive of main alone would install with no page.
To make a dist commit from a main commit:
- Check out
distbeside a cleanmain. - Replace its tree with
main's files and the build (git archiveofmain, thensrc/eugene_plexus_workbench/static/, added withgit add -f). - Write
BUILD_INFOasbuilt-from: eugene-plexus/workbench@<main commit>. - Put
src/eugene_plexus_workbench/_build.pyback asmainhas it.git archivestamps the commit into it. Left stamped, an archive ofdistwould namemain's commit instead of its own. - Commit, push
dist, and point the agent'sapps_catalogue.yamlat the new commit.
The config-trio shapes are generated from eugene-plexus/specs at the commit in SPECS_REF. Run python scripts/codegen.py to regenerate them.
The backend's interaction API v1
keeps versioned surfaces and approved action intent through restart. It reuses
chat ownership, answer branches and sign-in checks, and never retries an uncertain
external call. Schema 17 adds durable AG-UI runs and event projections after
backing up an older database. Headless backends support MCP Apps 2026-01-26,
A2UI 0.9.1 with the forms catalog, and AG-UI 1.0 in both serve and connect directions.
The AG-UI contract
defines the supported event subset, configured agents, continuation and replay.
Backend capabilities are separate from production renderer capabilities, which
remain empty until browser acceptance. The test_interactions, test_mcp_apps,
test_a2ui and test_agui* suites use real HTTP and persisted state; their
check-*-sabotage.py scripts prove the corresponding guards are tested.
Apache 2.0. Eugene's mascot and logo come from the project's website and are under the same licence, as are the working scenes drawn from them.