A guide to the desktop client, written for the person running the machine. It covers every screen and panel you use day to day, in the order you meet them.
This whole guide is one Markdown file, rendered two ways:
docs/guide/GUIDE.md.F1, or Help → User Guide),
which opens this file and jumps straight to the section for whatever
screen you’re on — like Settings → Serial.Press F1 again after moving to another screen and the panel follows you.
The < Back button at the top of the panel returns to the previous
section.
The window is the same everywhere: a column of activity buttons down the left, your working screen in the middle, movable panels around it, a menu bar on top and a status bar underneath.
The sidebar switches between the things you do, one button each. A thin line splits it in two: the screens that are always live above it, and the pair that follows the active model below it.
| Button | What it is |
|---|---|
| Sort | The Sort dashboard — where sorting happens. |
| Models | The model library. |
| Community | The community catalogue. Shown only while signed in. |
| (separator line) | Below it, the two ways a classifier is taught. |
| Train | The Train screen — teaching a local model of your own. |
| AI Config | The AI Config screen — the equivalent step when an HTTP server does the recognising: teaching it what to look for. |
| (separator line) | Below it, the app itself rather than a way of working. |
| Settings | Everything you configure once and rarely touch again. |
Train and AI Config are always both there, and exactly one of them is in use at a time — which one follows the active model (see Models):
Hover either button and the tooltip says which of those you are in. A dimmed button still works — it is the screen behind it that explains the state, and carries a button to the Models page to change it. Never a dead end.
Along the bottom, from left to right:
F1), Check for updates…, Export
support package…, About and License.Four panels can sit around your working screen. Each one can be moved, tabbed together with another, torn off into its own floating window, or closed:
Moving a panel: drag it by its tab — the small labelled tab at the edge of the panel, not its title. As you drag, blue drop indicators appear showing where it can land: the four edges of the window, or the middle of another panel to tab the two together. Drop it outside the window and it becomes a floating window you can put on a second monitor.
Getting a panel back: View → Re-dock panels returns every open panel to where it started, un-floated. Use it any time a panel ends up somewhere you didn’t intend — it always works, which dragging one back does not.
Closing and re-opening: the ✕ on a panel closes it; its entry in the View menu switches it back on. Your arrangement is remembered and restored the next time you start the app.
Live traffic between the app and the board — every line it sends and every line the board answers, in the order it happened. It is the first place to look when the machine does something unexpected.
Up and Down walk back through what
you have sent before.A grid of tiles, one per sorted case: the cropped image, the headstamp, the confidence, the bin it went to, and a running case number.
Tiles never scroll or move. When the grid is full the newest case overwrites the oldest tile in place, and a coloured border trails the most recent few so you can see where “now” is. That is deliberate — it means you can watch one position and see cases go past, instead of chasing a scrolling list.
The panel holds however many tiles fit it, and it recounts whenever its size changes: widen the window or drag the panel wider and there are more columns; narrow it and the tiles that no longer fit are dropped, oldest first. Nothing is ever hidden behind a scrollbar — what you can see is all of it, which is what makes watching one position work.
Zoom (at the bottom of the panel, 50–200%) sets the tile size, and feeds the same count: bigger tiles are easier to read across a bench, smaller tiles mean more of them fit. Click any tile to open that case’s image full size.
The whole list of themes in one place. Click one and the app repaints immediately, so you can try them against the room’s lighting without leaving what you were doing. Edit theme… opens the theme editor.
This is the same list as Settings → Theme; whichever you use, the other follows.
The Sort activity (the sidebar’s top button) is where sorting actually happens. It combines the current case, the slot layout and the run controls on one screen.
On a fresh machine — nothing connected and nothing routed to a slot yet — this screen shows a short panel with buttons straight to Settings → Serial and Settings → Camera instead of an empty grid.
The left-hand panel shows the last captured and cropped headstamp — exactly the image the classifier was given — with what it made of it underneath: the headstamp it matched and how confident it was. A confidence below the confidence floor is coloured as a warning, and that case goes to the Catch-All. Only the current case is shown here; the running record is in the Classification History panel.
Show live camera above the panel adds the live camera feed as a smaller second panel below the crop. It is off by default — the feed is a setup aid, not what an operator watches during a run — and while it is off no frame is fetched or drawn. If the camera isn’t running, clicking the feed takes you to Settings → Camera.
Every slot on the machine gets a card, arranged in a grid. Slot 0 is the Catch-All, for anything unclassified, below the confidence floor, or not routed to a slot; the rest are your bins. A card shows:
Above the grid: Sorted this run counts every case this run has sorted, Reset counts zeroes the counters (the grid’s and the per-bin ones) without touching your assignments, and the template picker names the layout the cards are showing.
Click any card except Catch-All to open its assignment editor. Tick a headstamp to route it to that slot; unticking sends it back to the Catch-All. Outside of package mode a headstamp can only be assigned to one slot at a time — ticking it here moves it off whichever slot it was in before, and the row tells you which one that was. A filter box narrows a long headstamp list by name.
The Template picker on the slot grid’s header row holds the active sorting template — a named snapshot of the whole slot layout, so one model can carry several bin arrangements (“Range brass” vs. “Match prep”) and switch between them. + creates one (optionally copied from the current layout); ✎ renames or deletes the active one.
You never have to save a template: the active one follows your edits as you make them. Switching templates replaces every slot assignment at once, so the whole picker is blocked while a run is in progress — stop first. Standard and package mode keep separate template lists, because their layouts mean different things.
⚙ Run options on the strip at the foot of the page holds everything that changes how a run behaves:
The strip at the foot of the page, with the green Start at the far right:
If the board stops responding while a run is going — the USB cable knocked out, the board losing power, the adapter re-enumerating — the run stops and a message says so. The serial indicator in the status bar turns red at the same moment, and the Serial Monitor records what went wrong. The app does not reconnect by itself and does not offer to resume: once the link is gone, where the wheel is and which case is about to drop are no longer known, and carrying on from a guess is how a case ends up in the wrong bin. Fix the cable, then reconnect from Settings → Serial and press Start again.
Without a board connected, Start and Manual feed are greyed out and say so. Otherwise starting is refused, with a message explaining why, if the AI Config API key or model name is unset, the active model’s checkpoint is missing, PyTorch isn’t installed yet for a local model, the model needs a newer PyTorch than this machine has (see below), or a moderator note is waiting to be read.
“This model needs a newer PyTorch.” A model can only be read by the version of PyTorch it was trained with, or a newer one — never an older one. So a model trained on someone else’s up-to-date machine, or on yours before an older PyTorch was installed, may refuse to load here. The message names both versions: the one the model needs and the one you have. Update PyTorch when the app offers to, and it will load. Nothing about this is recoverable by retrying, and a model that says this has not been damaged — it is simply newer than the software trying to open it.
Turning on Package mode in Run options switches the grid to batch counting against the one Batch size you set, shown as “count / target” on every slot card. A slot that reaches the target stops taking that headstamp; once every slot for a given headstamp is full, the run halts and asks you to empty bins and reset counters. A slot card’s ⟲ Reset button empties just that bin’s counter without stopping the run, so it can keep filling.
When the active model came from the Community and you are signed in, the app checks in with its publisher each time you open the Sort screen. Two things can come back, and neither stops a run in progress:
If the check can’t reach the server, nothing appears and the app behaves exactly as it does offline.
The Train screen is the loop that builds a training set: feed a case, capture it, label it, save it — and, when you have enough images, train a model from them.
Train is always in the sidebar, but it needs a local model of your own to work on. When the active model isn’t one, the button is dimmed and the page says which of the two cases you are in:
Either way the page carries a button straight to the model library.
The same holds the other way round for AI Config, which is dimmed whenever a local model is active: clicking it opens its own page, where — in place of the server form — a panel names the model doing the classifying and offers the same jump to the model library. Both buttons stay in the sidebar in every mode — what changes is which one is live.
The left column reads top to bottom in the order you work:
PyTorch is offered here, never required: capturing and labelling images is exactly the work you do before there is anything to predict with. Declining costs you only the predicted-label convenience, and you won’t be asked again this session.
The right half lists every headstamp and how many images are on disk for it — your training set, straight from the folder. Drag the divider to give it more width and the list reflows into more columns, which is what makes a model with a hundred-odd headstamps readable.
Clicking a headstamp in this list saves the captured case under that label and immediately feeds the next one — the fastest way to work through a tray of mixed brass.
The Training strip at the foot of the page turns the images above into a model:
The console opens with what the run is using: the PyTorch version, whether CUDA was found, which GPU (and how much memory it has) or that it is training on the CPU, then every setting the run was given. That block is the first thing to quote when a run is slower than expected or a result looks wrong.
Every run is also written to a file, so the console closing doesn’t lose it:
training-<date>.log in the logs folder under your data folder (File →
Open data folder), and the console’s first line says exactly where. The last
few runs are kept. Two shortcuts for sending one on:
training.log, with your folder paths replaced by placeholders.Training needs PyTorch. If it isn’t installed, the app offers to install it here.
The alternative to a local model: classification is sent to an OpenAI-compatible HTTP server, and this screen is where that server — and the headstamps it may answer with — is set up. It is Train’s mirror in the sidebar: live whenever classification runs over HTTP, dimmed when a local ConvNeXt model does the work.
Two things can put classification on HTTP, and this page serves both:
Activate a local ConvNeXt model and this screen swaps its form for a panel naming the model that is classifying instead, with a button straight to the Models page. Select Use AI Config — or an OpenAI model — there to come back; the server settings are still exactly as you left them.
The model library. Everything the app knows how to classify with is a row in this table, plus one synthetic row for AI Config mode.
The table lists each model’s name, whether it is active, its cartridge, type (yours or a community model), the mode it was built as — a ConvNeXt size, or OpenAI for a model that classifies over an HTTP server — how many training images it has, whether it has been trained, and when. Click a column heading to sort by it. An OpenAI model has nothing to train: activate it and the AI Config page becomes the place its server settings and headstamps live.
The Active column marks the model the app currently classifies with: exactly one row reads ● ACTIVE in the theme’s action colour, and every other row’s Active cell is blank. To change it, select a row and press Activate at the bottom right.
Above the table: filters by cartridge and type, a search box, and New cartridge, New model and Import….
The “Use AI Config” row sits at the top of the list, whenever the filters and the search box leave it there. Activating it puts the app in AI Config mode — classification goes to the HTTP server configured on the AI Config screen instead of a local model. It is not a model, so Edit, Delete, Export and the rest stay greyed out while it is selected.
Everything on the bar under the table acts on the selected row. Delete sits alone on the far left and Activate on the far right, so the destructive one and the primary one can never be neighbours:
Import… reads a model ZIP back in, after a notice that a model file can execute code — import only from authors you trust. If the archive carries a community ID you already have installed, the app asks whether to update the installed one in place — keeping its slot assignments, sorting templates and your name for it — or to import it as a separate copy; anything else lands as a new model. A ZIP you import stays yours: importing your own model onto a new machine leaves it trainable.
Import and export both run in the background; a model with its images can be large.
Published models, shared by other users. Signing in is the only thing in the app that needs an account — everything else works signed out.
The table lists each model with its cartridge, version, what the archive includes (model, images, or both), headstamp and image counts, size, publish date, author, and its State against your library: Available, Update available, or Installed.
Select a row and the two buttons under the table follow its state. The right-hand one is the primary, and it says what the state makes possible:
| Button | Action |
|---|---|
| Download model | Download and install it, after a notice that a model file can execute code — download only from authors you trust. |
| Update model | Update your installed copy in place, or take this version as a separate copy; it asks which. |
| Already installed | Nothing to do — this version is the one you have. |
| Remove | On the far left, and live only for an installed, current model: delete your local copy. The catalogue entry stays, and the primary goes back to Download model. |
Select a second model and press Download while one is still running and it queues behind the first, with the status showing “(2 of 3)” as it works through them. Selecting a queued model shows where it sits in the queue, and the one being fetched reads Downloading….
A model you install this way is managed by its publisher: it can’t be trained here, and updates from them install over it cleanly. The Sort screen tells you when a newer version exists — see community model notices.
Share a model… publishes one of your own models to the community. It appears only for accounts the server grants the contributor role. Sharing does not make the model foreign: your copy stays yours and stays trainable.
The Settings activity groups everything you configure once and rarely touch again, behind a section list. Most settings here save as you change them, with no separate Save step. The exception is the Camera page, where the device and resolution are committed by Apply.
Picks which camera the Sort dashboard’s preview and the classifier both read from.
Nothing here grabs a camera on its own; both actions are yours. The current device and resolution are shown beneath the controls.
Connects the app to the sorting machine over the board’s UART protocol.
Board init settings covers the machine’s tunables — feed and sort speed, homing offsets, motor current, debounce timing and the camera LED level — with Get config from board / Push to board to read or write them. The Sort arm group jogs the arm to a slot or homes it, for testing wiring before a real run. Airdrop configuration holds the three timing values (pre-drop delay, signal duration, post-drop delay), plus the switch that turns it on, for boards fitted with an airdrop mechanism.
Tunes how a captured frame becomes the 480×480 headstamp image the classifier sees. Capture takes a frame and shows it beside the processed result, and every detection or primer change re-processes that same frame — so you tune against one case instead of re-feeding for every adjustment.
These settings belong to the active model, not to the app: case diameter and primer size are properties of the cartridge, so switching models brings its own values back. A model that has never been tuned inherits whatever is currently set, so nothing is lost when you activate one for the first time.
Picks the colour theme. The same list is in the Themes panel, which is the easier place to try several.
Edit theme… opens the theme editor: it starts from the theme you are currently using and gives you a colour picker per role with a live preview. Save & apply writes back to a theme you made (renaming it moves it rather than copying), makes a new one when you started from a built-in, and leaves the editor open so you can keep adjusting — Close ends the session; Create new… saves under a name you pick, and a built-in is never overwritten either way. A theme can also be exported to a file and imported on another machine.
Copies your setup out of an installation of the Windows app (AI Brass Sorter) so you do not have to build it again here. Nothing in the Windows app is changed, moved or deleted — everything is copied, and that installation keeps working exactly as it did.
If the Windows app is installed in the usual place, this page finds it on its
own; otherwise choose the folder yourself — the one containing Data and
training. The same offer appears once, automatically, the first time you
start this app on a computer that has the Windows app on it.
You tick what comes across, in a tree:
Pick the models you actually want. A Windows install that has been in use for a while usually holds models you have no interest in carrying forward, so every model is its own tick. Select all / Select none are there so choosing two out of fifteen is two clicks rather than thirteen, and the line under the tree totals what you have chosen — models, images and trained model files — before you start.
Images, headstamps and the trained model file all belong to a model, so they sit under it: untick a model and its whole branch goes with it. There is no way to bring a model’s images across without the model itself, because they land in its folder. A model showing a half-filled tick is one where you have kept some parts and not others.
Anything this installation does not have is left out or greyed out rather than offered as a tick that would import nothing — a model with no images has no Training images row at all.
Each model’s row also says what importing it would do to your library here: either new model here, or updates ‘…’ naming the model it would refresh instead of duplicating.
A few things are worth knowing before you run it:
Running the import a second time is safe. A model already brought across is updated in place rather than duplicated, your slot assignments and sorting templates survive, and images already copied are skipped. The import never takes over an active model you have already chosen here.
That also means you can import in passes — bring two models over, sort with them, then come back for more. And a model whose trained model file you declined the first time gets it on a later run if you tick it then.
If a Windows model happens to share its name with a model you already have here,
the imported one is named … (2) rather than leaving you with two rows you
cannot tell apart. Your existing model is not touched.
F1, or Help → User Guide, opens this guide in a panel at the section
for the screen you are on. It is a normal panel: dock it beside
your work while learning something, close it after.
Help → Export support package… collects your current configuration into a plain-text report — the app version and platform, the active model, run options, training configuration, image processing, serial and camera settings, and the AI Config setup.
Copy to clipboard gives you the text to paste on the community Discord
when asking for help. Save package… writes a ZIP holding the same report,
a machine-readable config.json, and — if you have trained a model — the most
recent run’s log as training.log.
It is safe to share: the API key is reported only as “set” or “not set”,
nothing is read from the sign-in cache, and file paths are shown relative to
the data folder, so your home directory never appears. The training log gets
the same treatment: your folder paths are replaced by <data>, <app> and
<home> before it goes in.
The app checks for a new release shortly after it starts and, if there is one, offers it in the status bar. Help → Check for updates… asks immediately.
The dialog shows the release notes and a Download & install button. Downloading only stages the update — nothing is replaced until you restart, and the button becomes Restart now when it is ready. Choose a different version… lists every published release, including older ones, and optionally pre-releases (which the automatic check never offers). You can turn the automatic check off in the same dialog.