LM Studio Lab
A scratch space for testing caption prompts, schemas, and models against real media before touching caption settings.
This screen has no nav entry; reach it by typing /lm-studio. The route works and is live — its entry in the global nav is commented out, not deleted.
It is a scratch pad for captioning. Pick one real clip out of the library, choose which caption passes to run, edit the prompts, schemas, model choice and generation parameters however you like, and run it against LM Studio. Nothing on this page is saved. Not the settings, not the prompts, not the result. Close the tab and every edit is gone, which is exactly what makes it safe to experiment on production media. Once something works, reproduce it as a preset on Settings → Captioning; that is the only place these values persist.
The strip in the header — Selected Media, Connection, Available Models, Last Run Duration — is the quickest read on whether the page is ready to run.
The order to work in
- Pick one clip in the Media Picker.
- Tick the passes you want in Execution Controls. Nothing is ticked when the page loads.
- Tune the settings, prompts, and schemas that appeared for those passes.
- Run Experiment.
Two guardrails on step 4. The button is disabled outright until a clip is selected, and with a clip but no passes ticked it errors with "Select at least one caption pass before running the experiment." Both of those are the page reminding you about step 1 or step 2.
Media Picker
One clip at a time. The control is the same square check-toggle the media gallery uses for multi-select, but the lab replaces the whole selection with whatever you tick, so picking a second card drops the first. Clear in the Selected Media panel drops it outright. The chosen clip's platform, source, duration, aspect ratio, and title are echoed above the grid so you can confirm you have the right one before spending a run on it.
Three filters sit across the top:
- TODAY / YESTERDAY / ALL MEDIA
- ALL / CAPTIONED / NOT CAPTIONED
- REDDIT / INSTAGRAM / TELEGRAM, each toggled on or off independently. Turning off the last remaining source does nothing — the page refuses to leave you with no sources selected rather than showing an empty grid.
The picker never offers more than 24 clips, however wide the filters are. It starts by showing four and reveals four more each time you press the Load N more media button, which disappears once the 24 are on screen. If the clip you want is not among them, narrow the filters rather than hunting for a next page — there isn't one.
The filters and the selected clip both live in the URL, so a configured lab is a bookmarkable link. One consequence: if you change a filter so the selected clip is no longer in the visible set, the selection is dropped and the URL is rewritten without it. Set the filters first, then pick the clip.
Execution Controls
Four passes, ticked independently. Each is a separate call to LM Studio producing a separate piece of the caption:
- Subject — a structured read of the subject reference image, not the clip you picked. With no subject named in the URL the lab pulls the least-recently-used image out of the subject library, and the results section reports which one it used under Subject Image. An empty subject library means this pass is silently skipped even when it is ticked.
- Video SFW — a structured, non-explicit read of the clip's sampled frames.
- Video NSFW — the structured explicit read of the same frames: position, action, per-frame descriptions. Its fields are also the highest-confidence input to auto-tagging, so this is the pass to iterate on when Tags is not picking a position up.
- Default Description — plain prose instead of structured JSON. It becomes the Natural-Language Description in the results.
Two asymmetries follow from that, and they are the ones that trip people up:
- Default Description has no schema and no model dropdown of its own — it runs on whatever the Video SFW dropdown is set to. Changing the Video SFW model silently changes the description pass with it.
- Video SFW, Video NSFW, and Default Description share one frame extraction. Ticking any of the three triggers it, so the Video Extraction settings govern all three, including the plain-text one. Only Subject is exempt, because it never touches the video.
Ticking a pass is what makes its prompt and schema editors appear further down. With nothing ticked you still get three panels: the settings panel, an empty Schema Overrides panel showing its heading and blurb with no rows under them, and a Result Diagnostics panel holding a dashed "Run the lab once to inspect…" placeholder. That is a normal fresh load, not a page that failed to render.
Combined Output only appears when at least two of Subject, Video SFW, and Video NSFW are ticked. Default Description does not count toward that threshold, so a Default-Description-only run — or any single-pass run — never shows the panel and never produces combined text. That is the one panel whose absence is a rule rather than a bug.
LM Studio Settings
The left-hand panel. Test Connection re-checks the base URL and updates the coloured status dot; Refresh Models re-reads the model list. The page fires both automatically on load, which is why Connection reads "testing" for a moment before it settles.
Four sections:
- Connection — the base URL, Test Connection, the status dot, and Timeout (min) in whole minutes.
- Model Selection — Subject, Video SFW, Video NSFW. There is no fourth. The Default Description pass has no model picker of its own. Video SFW is hidden while the unified caption pass is enabled, since that pass replaces it, so you normally see two dropdowns rather than three; disable the unified pass to get it back. When no models have been loaded the dropdowns are disabled and read "No models available", which is a connection problem rather than a selection one.
- Generation Parameters — Temperature, Top P, and Max Tokens.
- Video Extraction — Frame Sampling, Frame Count, FPS Sample Rate and Max Duration (s), which control which frames of the clip are sent. Clustered (the default) samples at the FPS rate from the start of the clip. Spread places Frame Count frames across the clip's beginning, middle and end, ignores FPS, and treats the duration field as the span the frames are spread across.
Max Tokens and Timeout are a pair, not two independent knobs. A generation that runs long does not get truncated at the token cap and returned — it holds its slot until the timeout elapses and then fails. Keep Max Tokens low enough that the worst-case tokens-per-second still finishes inside the timeout. The persisted default of 4096 exists for that reason; the field will happily accept 32768, which at a loaded LM Studio's throughput cannot complete inside any realistic timeout.
Prompt and Schema Overrides
Editors appear per ticked pass, one preset dropdown plus one free-text box each. Leave a box exactly as its preset loaded it and the run passes the preset by name, so an untouched pass behaves exactly like production. Type into it and the run sends your text instead.
Once you have edited a box, switching its preset dropdown no longer replaces what you typed. The dropdown only loads new text into a box you have not touched — that is deliberate, so a stray change of preset cannot wipe out a prompt you have been working on, but it does mean the dropdown can end up naming a preset whose text is not what is in the box below it. The box wins on Run. Clear the box first if you want a clean switch.
Schema overrides cover the three structured passes only, since Default Description has no schema. Each has a preset dropdown with a No preset selected option and a JSON editor beneath it. Invalid JSON is rejected when you press Run, naming the editor it came from, rather than being sent as-is.
Choosing "No preset selected" for Video NSFW is a meaningful setting, not an empty one — it runs that pass with no structured schema at all, which is how you test what the model produces unconstrained. The other two passes treat it as "no override".
Result Diagnostics
The panel at the bottom of the page is always mounted; before the first run it holds a dashed "Run the lab once to inspect…" placeholder. Once a run lands it fills with everything that run returned:
- Resolved Settings — the settings actually used, which is the panel to check when a run behaves unlike production.
- Natural-Language Description — present only if Default Description ran.
- Combined Text — present only if combined output applied.
- One JSON block per pass, each labelled with the model that produced it.
- Media ID, Resolved Media ID, and Subject Image across the header of the section.
None of this is written anywhere. Copy what you want out before you leave, and re-create the winning configuration as a preset on Settings → Captioning to put it into production.