Repository navigation
Engine API
LexiEngine serves one resident text model through /v1/chat/completions, /v1/completions, and /v1/responses. GET /v1/models lists its declared HTTP names. Declaring names does not load additional models, change the weights, or permit arbitrary client-supplied names.
lexi-engine serve -m /models/model.gguf \
--alias main --alias client-main \
--chat-template-file /models/chat.jinja \
--chat-template-kwargs '{"reasoning_effort":"xhigh","enable_thinking":true}' \
--reasoning-format auto \
--temp 1.0 --top-p 0.95 --top-k 20 --min-p 0 --n-predict 2048
--alias NAME is repeatable. The first name is the resident model's public ID; additional names are accepted as exact matches and listed separately by GET /v1/models. Omitting model from a supported request selects the resident model. Names that were not declared remain a 400 with requested model is not loaded. The default name, if no alias is given, is the model identity normally reported by the loader. Aliases are not a second model and cannot be used to bypass authorization.
--chat-template-file PATH overrides the tokenizer.chat_template embedded in the GGUF. The file must be valid UTF-8, nonempty, no more than 256 KiB, and syntactically parseable by the sandboxed template renderer. The server validates it before listening and refuses a malformed or unreadable file. This option affects chat prompt rendering and chat input-token counting; it does not replace the model tokenizer or weights.
--chat-template-kwargs JSON accepts a JSON object of server-default template variables. Chat request chat_template_kwargs overrides matching defaults; reserved message/BOS/EOS keys and invalid value types remain rejected. For example, a template that consumes reasoning_effort can receive "xhigh" from these variables. An arbitrary variable has an effect only when the chosen template actually uses it. There is no separate mechanism that forces a model to generate hidden reasoning.
Sampling defaults apply to requests that omit the respective field: --temp (0–2), --top-p (0–1), --top-k (0–100000), --min-p (0–1) and --n-predict (1–131072). Explicit request settings take precedence, including explicit zero values; request generation limits and context ceilings are still enforced. Without these switches, existing server sampling defaults remain unchanged.
--reasoning-format auto is the default. For chat output that opens <think>...</think>, LexiEngine puts the thought text in choices[0].message.reasoning_content and the visible answer alone in choices[0].message.content. Streaming chat emits the corresponding delta.reasoning_content and delta.content frames. Delimiters split across generation events are held back so they do not appear in either field. When generation stops before </think>, content is empty. The previously supported thought-channel template also continues to be separated.
--reasoning-format none disables this output separation and preserves the raw generated text in content, including thought delimiters. This is an output-format selection, not a switch to disable reasoning in the model. To disable the template's thinking mode, use enable_thinking:false when the template supports it.
Example nonstreaming response excerpt:
{
"choices": [{
"index": 0,
"message": {
"role": "assistant",
"reasoning_content": "intermediate text",
"content": "final answer"
}
}]
}The reasoning separation applies to the native chat-completions route; non-chat compatibility endpoints retain their own output contracts. Structured/tool outputs continue to be verified before client-visible structured events are emitted. A template may produce other, currently unsupported reasoning formats; they are not inferred or silently relabeled. None of these options guarantees a particular model capability, performance, or device-backend qualification.
A chat request may carry reasoning_effort (none, minimal, low, medium, high, xhigh). For a model whose chat template has a thinking switch, any level other than none turns thinking on and none turns it off. For a model whose template cannot think, a level other than none is answered with 501: the engine does not invent reasoning.
An assistant message in the history may carry the reasoning_content it was returned with. It is accepted and left out of the prompt: an earlier turn's thinking is not replayed to the model. On any other role the field is refused. A tool message may carry the function's name beside its tool_call_id; the id is what pairs it with its call.
When the chat template in use renders tools itself (most current models' templates do), the request's tools, earlier assistant tool_calls and tool results are given to the template in its own terms, so the model sees its trained format. Calls are read in the JSON form (<tool_call>{"name":...,"arguments":{...}}</tool_call>) and in the function form (<tool_call><function=NAME><parameter=KEY>VALUE</parameter></function></tool_call>); in the function form a value is text when the tool's schema says the parameter is a string and is otherwise read as JSON when it is JSON. With a template that has no tool support, and for a request that forces one named tool, the engine uses its own tool prompt.
Every call is verified against its tool's schema before it is returned. Output that only looks like a call is returned as the assistant's text, unless tool_choice required a call, in which case it is an error.
Schemas. A tool marked "strict": true must use a closed object schema with all properties required, and is refused otherwise. A tool that is not strict may use ordinary JSON Schema: an object without additionalProperties, default, a nullable anyOf, pattern, format, numeric and length bounds, $ref. What the engine cannot enforce while decoding is widened to the nearest thing it can, never narrowed, with one exception that follows common practice: an object that lists properties and says nothing about others accepts only the listed ones. The model is shown the schema as the client wrote it.
--queue-wait SECONDS (default 0) makes a generation request wait up to that long for a free slot instead of being answered 429 inference_busy at once. A client that sends two requests at the same moment to a one-slot server then has both answered, one after the other.
LexiSuite · Local OS / Kernel / Engine / Panel · Development / testing; not production-qualified
Getting Started · Security · Troubleshooting · Release Notes · Licence
Verify release checksums, finish first-boot enrollment on a trusted network, and respect the current proprietary licence.
- Home
- Getting Started
- Install from USB
- Write a stick
- Install to an internal disk
- Install on a computer you already use: Linux, macOS, Windows
- Updating
- Ternary models (experimental)
- First Boot
- Secure Boot
- Kernels
- Hardware
- Overview / Home
- Navigation and Help
- Models
- Instances
- LexiChat
- Builds and Engines
- Optimizer
- Fit Lab
- Benchmarks and Evals
- Training
- Decisions
- TokenGate
- Inference Fabric
- Media Generation
- Agents and MCP
- Power and Hardware
- Network and Access
- Storage, Backup and Updates
- Files, Terminal and Passwords
- Diagnostics
- Fleet
- Virtual Machines
- LexiOS and Secure Boot
- macOS