Models & Launch Options
List the on-device model catalog, pin a specific GGUF for your integration, and launch the Cephable desktop app with a model and port preselected for automated environments.
Automate runs on a local GGUF served by a shared llama.cpp server inside the Cephable app. Which model is loaded affects speed, quality, and how many tools the agent can juggle — so an integration that cares about reproducibility should pin one explicitly.
Inspect the catalog
curl -sS http://127.0.0.1:4317/v1/automate/models \
-H "Authorization: Bearer $CEPHABLE_AUTOMATE_KEY"
{
"object": "list",
"data": [
{
"name": "Gemma 4 S",
"family": "Gemma",
"sizeCode": "S",
"parameterCountBillions": 1,
"fileSizeMb": 850,
"supportsTools": true,
"availableForDevice": true,
"downloaded": false,
"selected": false
},
{
"name": "Gemma 4 M",
"family": "Gemma",
"sizeCode": "M",
"parameterCountBillions": 4,
"fileSizeMb": 2650,
"supportsTools": true,
"availableForDevice": true,
"downloaded": true,
"selected": true
}
],
"catalog": { "status": "ready", "modelCount": 7 }
}
A model is usable only when all three of these hold:
| Flag | Meaning if false |
|---|---|
supportsTools |
Not tool-capable, so Automate cannot use it at all |
availableForDevice |
This machine cannot run it — RAM, GPU, or OS below requirement |
downloaded |
The GGUF is not on disk. Downloads happen only in the Cephable UI; there is no download endpoint |
The catalog syncs from Cephable asynchronously after app launch. At startup, poll until catalog.status === "ready" before trying to select anything:
async function waitForCatalog(endpoint, token, timeoutMs = 120_000) {
const deadline = Date.now() + timeoutMs;
while (Date.now() < deadline) {
const body = await getJson(endpoint, token, '/v1/automate/models');
if (body.catalog.status === 'ready' && body.data.length > 0) return body.data;
await new Promise((r) => setTimeout(r, 1000));
}
throw new Error('The Cephable model catalog did not become ready');
}
Pin a model for your integration
curl -sS http://127.0.0.1:4317/v1/automate/models/select \
-H "Authorization: Bearer $CEPHABLE_AUTOMATE_KEY" \
-H "Content-Type: application/json" \
-d '{ "family": "Gemma", "sizeCode": "M" }'
The selector takes modelName, family, and sizeCode in any combination, all case-insensitive. It must resolve to exactly one catalog entry — an ambiguous selector is an error naming the candidates, which is friendlier than silently picking one:
{ "error": { "message": "Model selector is ambiguous; matches: Gemma 4 M, Gemma 4 M (tools)", "type": "invalid_request_error" } }
What selection actually does
- It sets a session preference. The user's synced account setting is untouched, and the pin is dropped when the server stops.
- It terminates a warm worker if one is running, so the next run pays a cold start (model load, several seconds to tens of seconds).
- It requires the workflow to be idle. A run in flight gives
409; a non-idle-but-not-busy workflow gives400 Cannot switch models while workflow status is …. - The first run after a switch verifies that the requested model really became active and fails loudly if it did not, rather than quietly benchmarking or automating against the wrong weights.
Select once at integration startup, not per request.
Unpin
An empty body restores whatever the app itself would have used:
curl -sS http://127.0.0.1:4317/v1/automate/models/select \
-H "Authorization: Bearer $CEPHABLE_AUTOMATE_KEY" \
-H "Content-Type: application/json" -d '{}'
Confirm what is loaded
/health reports both layers:
{
"modelName": "gemma-4-4b-it-Q4_K_M.gguf",
"automateModelSelection": { "name": "Gemma 4 M", "family": "Gemma", "sizeCode": "M", "parameterCountBillions": 4, "fileSizeMb": 2650 },
"backend": { "flavorId": "vulkan", "accelerator": "vulkan", "cpuFallback": false },
"contextSize": 16384
}
modelNameis the GGUF file name actually loaded — that is also what a run record'smodelfield contains.automateModelSelectionis the catalog entry you pinned, ornullwhen the app's own choice is in effect.backendis the llama.cpp acceleration in use.cpuFallback: truemeans GPU acceleration failed and the run degraded to CPU, which changes latency by an order of magnitude. Record it before comparing timings.contextSizeis sized from this device's RAM, so it differs machine to machine. Two runs with differentcontextSizeare not directly comparable.
Launch options
The Cephable executable accepts process-scoped overrides for the preferred model and the server port — useful for CI, test rigs, and kiosk or lab machines.
Cephable.exe --model "Gemma 4 M" --port 4321
Cephable.exe --family Gemma --size M --port 4321
# macOS
/Applications/Cephable.app/Contents/MacOS/Cephable --family Gemma --size M --port 4321
| Argument | Aliases | Meaning |
|---|---|---|
--model |
Exact catalog model name | |
--family |
Model family, e.g. Gemma |
|
--size |
--size-code |
Size code, e.g. S, M, L |
--port |
--automate-http-port |
Port the Automate server should bind first |
Both --name value and --name=value forms work. Selectors are case-insensitive and must resolve to exactly one catalog model.
Rules that matter
- They do not bypass access control. A Professional user must still enable Automate HTTP Server in Extensions. Launch arguments never enable the server, grant a license, or skip the secure-storage check.
- The access key is not accepted as a launch argument. Operating systems expose process command lines to other local processes, so passing it there would leak it. Read it from the app and pass it to your client out of band.
- They override the process, not the account. The synced model preference is unchanged; the override lasts for the running process.
- A second launch reconfigures the running instance. Cephable is single-instance: launching it again with new arguments applies them to the existing app, including rebinding the server when the port changes.
- Failures surface on
/health. If a model selector could not be applied — misspelled name, model not downloaded, not device-compatible —launchModelSelectionErrorsays why, and the app keeps its previous selection.
Waiting for the server after launch
The app takes a while to start, sync the catalog, and bind. Poll /health rather than sleeping a fixed amount:
async function waitForServer(endpoint, token, timeoutMs = 180_000) {
const deadline = Date.now() + timeoutMs;
let lastError = 'no response';
while (Date.now() < deadline) {
try {
const response = await fetch(`${endpoint}/health`, { headers: { authorization: `Bearer ${token}` } });
if (response.status === 401) throw new Error('The access key was rejected');
if (response.ok) return await response.json();
} catch (error) {
lastError = error instanceof Error ? error.message : String(error);
}
await new Promise((r) => setTimeout(r, 1000));
}
throw new Error(`Cephable did not expose the Automate server at ${endpoint}: ${lastError}`);
}
Choosing a model
| Smaller (S) | Larger (M / L) | |
|---|---|---|
| Latency | Fast; good for single-tool tasks, rewriting, classification | Slower per token, but usually fewer wasted tool calls |
| Multi-step reliability | Drifts on long chains | Holds a plan across more steps |
| Context | Same device-sized window | Same device-sized window, but consumed faster by longer reasoning |
| Fit | Short prompts, high call volume, low-power machines | Research, multi-file work, anything with branching |
Two practical notes:
- Shrink the task before shrinking the model. A well-scoped prompt on a small model beats a vague prompt on a large one, and costs a fraction of the time.
- Pin the model and record
contextSizeandbackendin anything you intend to compare over time. The model name alone does not determine performance on a given machine.