Files
LocalAI/swagger/swagger.yaml
T
mudler-agentandEttore Di Giacinto 2cadf319a0 feat(realtime): LFM3-Audio speech-to-speech on llama.cpp, remove liquid-audio (#12958)
* chore(backends): remove the liquid-audio Python backend

The backend targets liquid-audio, which loads LFM2 checkpoints only.
Remove its directory, the gallery file and the LFM2.5-Audio model
entries, the library and generated backend gallery entries, the
backend matrix and CI job, the Makefile targets and the golden test
fixtures that listed it.

Assisted-by: Claude:claude-haiku-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* refactor(config): drop liquid-audio from capabilities, importers and UI

With the liquid-audio backend gone, remove its capability entry, its
importer, its artifact-gate entry and the realtime_audio heuristic
that only matched that backend. realtime_audio is now set only
through known_usecases. Update the Talk and fine-tuning pages, the
docs and the swagger text that named the backend.

Assisted-by: Claude:claude-haiku-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* chore(llama-cpp): bump llama.cpp to e486a4b5

Move the llama.cpp pin to e486a4b559617dc88bf79978996f6c670b6bbc9d,
the master head of 2026-10-28. It contains the LFM3-Audio support
(ggml-org/llama.cpp#31257) and the realtime server split
(ggml-org/llama.cpp#31269).

The score task patch is regenerated against the new pin. It applies
with git apply and with patch -p1, with no offset and no fuzz. Its
hunks in server-task.h and server-context.cpp were rebased by hand
next to SERVER_TASK_TYPE_REALTIME and the control dispatch.

The C++ backend was built on CPU for this change: the llama, mtmd and
server-context libraries and the grpc-server binary link.

Assisted-by: Claude:claude-haiku-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* feat(llama-cpp): compile server-realtime.cpp into grpc-server

server-context.cpp includes server-realtime.h, and its realtime slot
type is defined in server-realtime.cpp. Upstream compiles that file
into the server library. The gRPC server is one translation unit, so
it must include the file too, or the link fails.

The include is guarded by __has_include. Forks that predate the
realtime split do not ship the file, so they keep building as before.

Assisted-by: Claude:claude-haiku-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* chore(llama-cpp): probe realtime and TTS voice support in prepare.sh

prepare.sh writes llama_compat.h from probes on the checkout. Add two:
LOCALAI_HAS_REALTIME (SERVER_TASK_TYPE_REALTIME in server-task.h) and
LOCALAI_HAS_TTS_VOICE (set_voice in mtmd-helper.h). The probes let the
gRPC server choose the realtime and voice code paths per checkout, so
forks without them keep compiling.

Assisted-by: Claude:claude-haiku-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* feat(llama-cpp): advertise speech recognition and speech-to-speech

llama-cpp now registers the AudioTranscription and AudioToAudioStream
RPCs, with the transcript and realtime_audio usecases. The default
usecase stays chat, so a plain GGUF is still a chat model. The
backend implements the RPCs in a follow-up change; until then the
calls return UNIMPLEMENTED.

Assisted-by: Claude:claude-haiku-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* feat(config): add pipeline.any_to_any for speech-to-speech models

A realtime_audio model that serves the whole speech loop itself sets
pipeline.any_to_any. The flag is off by default, so chained pipelines
and existing realtime_audio configs are unchanged. The realtime_audio
heuristic stays explicit: a llama-cpp model is never a Talk-page model
unless known_usecases says so.

Assisted-by: Claude:claude-haiku-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* feat(config): read the audio encoder and speech-to-speech projector flags

Add HasAudioEncoderProjector for clip.has_audio_encoder and
HasSpeechToSpeechProjector, which requires the LFM3 audio encoder
family together with the gen-audio decoder. Qwen3-TTS sets both encoder
flags too, so the flags alone cannot tell it apart from LFM3.

Assisted-by: Claude:claude-haiku-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* feat(importer): import LFM3-Audio projectors as speech-to-speech

An mmproj that carries the LFM3 audio encoder and the gen-audio decoder
now imports with known_usecases realtime_audio, chat, transcript and
tts, pipeline.any_to_any: true, the parallel:2 option and the tokenizer
template. Other gen-audio projectors keep the TTS-only result, Qwen3-TTS
included. The probe runs against a local HTTP server in the tests.

Assisted-by: Claude:claude-haiku-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* feat(llama-cpp): named-voice TTS and the LFM3 ASR prompt

Models without a speaker reference (LFM3-Audio) take a named voice
through their "tts" chat template instead of a reference file. The
request is validated with needs_reference=false, the prompt is rendered
with common_chat_get_tts_prompt(), and the voice is set on the gen-audio
input. Qwen3-TTS Base keeps the reference-file rule. The branch is
guarded by LOCALAI_HAS_TTS_VOICE, so forks without named voices keep the
old behaviour.

Transcription takes its prompt from common_chat_get_asr_prompt(). LFM3
gets a system turn that names the language and an empty user turn.
Qwen3-ASR's preset is unchanged: fixed user text, no system turn, and a
caller prompt is still appended after a newline. The preset call is
guarded by a new LOCALAI_HAS_ASR_PRESET probe.

The pure parts sit in tts_request_options.h and transcription_prompt.h,
with standalone tests run by backend/cpp/run-unit-tests.sh.

Add the test-extra-backend-llama-cpp-lfm3 target. It runs the tts,
ttsstream and transcription specs against LFM3-Audio GGUF weights. It is
a manual run and is not wired into CI.

Assisted-by: Claude:claude-haiku-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* test(e2e): mock AudioToAudioStream and pending realtime S2S specs

The mock backend serves AudioToAudioStream deterministically: session
created, commit with RMS, a tool call on the first turn with tools, then
transcript pieces and paced 24 kHz tone frames, with response.cancel
ending a reply as cancelled.

The realtime S2S specs cover the mock and real-weights variants. They
skip until the /v1/realtime S2S path lands, so the mock suite stays
green in CI.

Assisted-by: Claude:claude-haiku-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* feat(llama-cpp): speech-to-speech AudioToAudioStream on the realtime slot

Implement AudioToAudioStream on upstream's realtime slot, so a model
that answers after the audio (LFM3-Audio) can hold a conversation over
the existing duplex RPC. The proto schema does not change: tools travel
in the config, tool calls leave as function_call_arguments.done and tool
results arrive as a function_call_output item.

realtime_session.h keeps what needs no model: the turn text derived
from the chat template (with a tool turn), the conversation state, a
filter that keeps <tool_call> blocks out of the transcript and drops
audio produced inside them, and the translation of slot results into
events. grpc-server.cpp wires it to the slot with control tasks and
parses calls with the parser the chat template selects.

The unit test uses a fake renderer. A ctest-only check renders the real
LFM3 template and compares the slot text with the full render.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* feat(gallery): add the LFM3-Audio-2B entries

Two llama-cpp entries for LiquidAI/LFM3-Audio-2B-GGUF, the Q4_K_M
default (lfm3-audio-2b) and the Q8_0 build (lfm3-audio-2b-q8), both
with the Q8_0 audio projector. Each declares pipeline.any_to_any and the
realtime_audio, chat, transcript and tts usecases the importer writes
for an LFM3 projector, with parallel:2 and the tokenizer template. The
Q4 entry lists the Q8 one as a variant.

File sizes and sha256 come from the Hugging Face API for the pinned
repo revision. Speaker reference files and the VAD model are not part
of the entries: VAD stays optional.

Assisted-by: Claude:claude-haiku-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* docs: describe LFM3-Audio speech-to-speech and its gallery entries

Adds a speech-to-speech section to the Realtime API page (any_to_any
configuration, VAD versus manual commit, tools, transcripts, barge-in,
limits), a pipeline.any_to_any row, a llama.cpp speech-to-speech row in
the compatibility table, and LFM3-Audio mentions on the TTS and ASR
pages. The feature is marked experimental: the behaviour follows the
backend session contract and has not been run with real weights.

Assisted-by: Claude:claude-haiku-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* feat(realtime): run any-to-any models on AudioToAudioStream

A realtime_audio model with pipeline.any_to_any now opens one duplex
stream to the backend and keeps it for the session, replacing the
"any-to-any models not implemented" branch. The chained pipeline is
unchanged.

The endpoint forwards input audio (with a pre-roll from speech start
when a VAD model is set, otherwise every chunk and a client commit),
sends response.create, and turns the backend's events into the usual
realtime events: audio and transcript deltas, tool calls through the
existing function_call items, and a single response.done. A function
call output is forwarded before the next response. Barge-in sends
response.cancel ahead of the new speech and stops forwarding audio at
once. The user's speech is transcribed on the side and reported on the
user item; a failure there does not touch the response.

Server VAD is on only when pipeline.vad is set. Classifier mode,
compaction, streaming.llm, voice gating, sound detection and
semantic_vad are rejected for these models.

The mock backend now matches the llama.cpp contract (session.updated,
the cancel error when idle) and its VAD reports the loud stretches of
the audio, so the S2S e2e specs run a VAD turn. The specs are enabled.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* test(e2e): add the real-weights realtime S2S variant and the gRPC s2s spec

The realtime S2S specs now check reply audio on real models: duration,
loudness, clipping, and keywords found in the model transcript or in a
separate ASR of the output audio. run-realtime-lfm3.sh stages the llama-cpp
and sherpa-onnx backends, the LFM3-Audio files and the sherpa VAD, ASR
and TTS models, then runs the real variant. It is manual and never part of
CI: `make test-realtime` still filters out real-models.

The backend suite gains an s2s capability (spoken turn, tool call, tool
result, spoken answer over AudioToAudioStream) and optional TTS duration
and RMS bounds plus a transcript keyword check, all enabled for
test-extra-backend-llama-cpp-lfm3.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* test(e2e): expect the idle-cancel error from the mock S2S

The mock now answers a response.cancel with no reply running with
response_cancel_not_active, as the llama.cpp backend does. The cancel
spec still treated that cancel as a no-op and read the error as extra
data after the stream ended.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* feat(talk): show any-to-any models as one speech-to-speech model

/api/pipeline-models lists a pipeline.any_to_any model with any_to_any
set and its optional VAD. A realtime_audio model that is not any-to-any
is listed only when it has the four pipeline slots, since the session
takes the chained path for it.

The Talk page shows a speech-to-speech model as one model: no four-slot
view, the VAD slot only when a VAD model is set, and the female and male
voices offered. Without a VAD model the server does not detect turns, so
the page offers Done speaking, which sends input_audio_buffer.commit and
then response.create. Text-only replies stream through
response.output_text.delta and .done.

self_contained stays in the response for clients built before any_to_any.

Assisted-by: Claude:claude-haiku-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix(realtime): refuse a llama-cpp realtime model without pipeline.any_to_any

llama.cpp has no VAD, transcription or TTS RPCs, so filling the empty
pipeline slots with the model name failed later with UNIMPLEMENTED.
Fail at session start and name the missing setting instead.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix(realtime): hold manual-commit S2S audio until the commit

In manual-commit mode the endpoint streamed every appended chunk to the
backend, so input_audio_buffer.clear only emptied the Go buffer while the
model kept the audio, and idle audio filled its context between turns.
Keep the audio in the input buffer and send it, behind pending text and
tool-result items, when the client commits or asks for a response.

Frames and controls now go through one ordered write queue, so no gRPC
send happens under the audio buffer lock. A tool result created while a
VAD turn is open is refused with a clear error. When the stream ends
outside a response the session reports it and closes, and a bare EOF
from Send reports the status that Recv holds.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* test(e2e): drop the S2S readiness gate and stale comments

The gate was always true. Some comments referred to work items that
readers of the repository cannot see.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* docs(realtime): add the liquid-audio migration note and the clear semantics

Say that the Python liquid-audio backend is gone, which gallery entries
replace it and that LFM2.5-Audio has no replacement. Describe what
input_audio_buffer.clear drops for speech-to-speech sessions now that
manual-commit audio is held back until the commit.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix(talk): do not promise turn detection when no VAD model is set

The idle note said the server notices when you stop talking. A
speech-to-speech model without a VAD model needs Done speaking, so the
note now says that.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* test(e2e): make the mock S2S backend keep the llama-cpp session limits

The mock accepted what the real backend refuses and hid two endpoint bugs.
It now treats output_modalities from the config as a fixed session mode and
picks the default per response from the tools set at that time. A fixed text
plus audio mode with tools reads the tool call out loud. After the first
commit or message, session.update of instructions, voice or tools is an
error that does not belong to a response, committing an empty buffer is an
error, and response.create while a reply runs is refused. Errors of a
refused response.create carry response_scoped in their meta.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix(realtime): leave the S2S output mode to the backend unless the client sets one

The stream config sent text plus audio when the session had no tools yet.
The llama-cpp backend keeps a mode from the config as a fixed session mode,
and tools added later by session.update never cleared it. The model then
read tool calls out loud. Send output_modalities only when the client chose
them. The backend picks the default of each response from the tools it has
when the response starts.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* feat(llama-cpp): mark the realtime errors that answer a response.create

The error event now carries response_scoped: true when it ends the request
for a response (a refused response.create, a failed commit made by it, or
a stream failure). Other errors, such as a refused session.update or a
commit of an empty buffer, are not about a response and one that runs
keeps generating. The client needs the difference to know whether a
response.done is still coming.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix(realtime): end an S2S response only on the errors that belong to it

Every backend error ended the response in flight, although the backend
also reports errors about other things (a refused session.update, a commit
of an empty buffer) and goes on generating. The rest of the reply was lost
and the next response.create met either a refusal or the leftover events of
the old reply. End the response only on an error marked response_scoped,
forward the others to the client and keep waiting for response.done. Drop
the events buffered by an earlier response when a new one starts, and skip
the commit of a turn that forwarded no audio.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix(realtime): run the S2S input transcription detached from the commit slot

The commit waited for the side transcription of the user audio while it
held the commit slot, and response.create waits for that slot. The ASR
latency was added before every reply, and on a backend with few slots a
busy ASR task could stall the reply. The model already has the audio, so
run the transcription detached under the session context and release the
slot at once. The transcript is still reported on the user item.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* test(realtime): do not pin the place of the input transcript in the S2S order

The transcript of the user audio is reported on the side and may land
before or after the first response events. Check the order of the response
events without it.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix(realtime): stop an S2S reader leak and a cancel that waits on the write queue

The reader waited on a channel it closes itself when the events buffer was
full, so it outlived the session after a turn ended on an error or timed
out. It now also stops when the session closes.

Stopping a response sent the cancel through the write queue and waited for
it before the grace timer started. With backpressure on the stream the wait
never ended and nothing read the events meanwhile. The timer now starts
first and the cancel is only queued.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* feat(realtime): let a chained pipeline run without a VAD model

A pipeline that names no pipeline.vad failed to build, because the
VAD slot was always loaded, and a new session still started with
server_vad. The slot is now optional for chained pipelines as it
already is for any-to-any models: the session starts with turn
detection off and the client commits each turn. Turning server_vad on
for such a session is refused, and a switch to a pipeline without a
VAD drops turn detection.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* feat(gallery): add LFM3-Audio VAD and chained-pipeline entries

Add lfm3-audio-2b-vad and -q8-vad (any-to-any with silero-vad-ggml as
the turn detector), and lfm3-audio-2b-pipeline, -pipeline-vad and the
-q8 forms (the model chained through its own transcription, chat and
speech slots, with and without the VAD). The gallery has no
dependencies between models, so the VAD entries state that
silero-vad-ggml must be installed first.

Drop the variants list from lfm3-audio-2b: it let the installer pick
the larger Q8 build on any host with enough memory, so a plain install
of the Q4 entry did not get Q4. All entries are now independent. Tests
cover the entry shapes, the single-build install and their acceptance
by the realtime endpoint.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* test(e2e): run the realtime specs for any-to-any and chained shapes

The realtime specs covered one any-to-any model with a VAD. They now run
for any-to-any and for a chained pipeline, each with and without a VAD,
on the mock backend in CI. VAD-less shapes also check that turn
detection starts off and that server_vad is refused. The manual
real-weights script writes one config per shape that mirrors the gallery
entries and runs the four shapes in turn (LFM3_MATRIX picks a subset).

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* docs(realtime): document the LFM3-Audio VAD and chained-pipeline entries

List the eight LFM3-Audio gallery entries, explain that silero-vad-ggml
must be installed before the -vad entries, describe the chained pipeline
on one model and the behaviour of a pipeline without a VAD, and
describe the shape matrix of the e2e specs.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* test(realtime): wait for the detached input transcription in the S2S specs

The input transcription runs in its own goroutine, so the transcription
completed and failed events can arrive after the response ends. Poll for
them instead of reading the event list right after the response.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix(realtime): release the S2S stream before running server-side tool calls

A response held the stream slot until it returned, and it ran the tool
calls from inside that scope. A server-side tool starts a follow-up
response on the same stream, which then waited for the slot its parent
still held, so the client never got response.done. Run the tool calls
once the slot is free; the event order is unchanged.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix(realtime): end an S2S session whose stream dies, and stop queuing after close

A stream that died during a response left the session open: later
requests failed one by one and VAD frames kept being forwarded. The
response now ends the session through the transport, and enqueue drops
requests once the session is closed so the write queue cannot grow.

The writer is now the only caller of Send and of CloseSend. close()
used to call CloseSend while the writer could be inside Send, which
gRPC does not allow.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix(realtime): close the open S2S turn when the VAD stops

Switching turn detection to manual in the middle of a VAD turn left the
turn forwarding, and the next client commit sent the whole buffer a
second time. Stopping the VAD now commits the forwarded audio on the
backend and drops it from the input buffer.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix(realtime): keep a tool result pending while an S2S user turn is open

The check that refuses a tool result during a user turn ran when the
item arrived, but the item was forwarded later, and the result was
marked as sent before the backend took it. If the user spoke in
between, the backend refused it and it was never retried. The result is
now claimed and queued under the audio lock only when no turn is open,
and otherwise stays pending for the next commit or response.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix(talk): empty the input buffer for models without a VAD

Without voice detection the microphone fills the server's input buffer
for the whole session, so Done speaking committed idle silence and the
echo of the previous reply. Clear the buffer when the session starts and
when a reply ends.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix(importer): keep an existing parallel option on LFM3-Audio imports

The speech-to-speech import added parallel:2 even when the options
already carried another parallel value. Use the same check as the
hardware defaults, which also covers n_parallel.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix(talk): list chained pipelines that have no VAD

/api/pipeline-models required a VAD for a chained pipeline, so the
VAD-less LFM3-Audio pipeline entries never showed up on the Talk page.
Any pipeline with transcription, LLM and speech slots now qualifies.
The Talk page treats every model without a VAD as manual-turn, and the
session sheet says so for chained pipelines too.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* chore(llama-cpp): bump llama.cpp to 0ac1a7fd

Move the llama.cpp pin to 0ac1a7fd35c127a18c0cbc6c57d12e256a6a385b,
the master head of 2026-10-29. It contains tool calls in the realtime
server (ggml-org/llama.cpp#31287).

The score task patch is regenerated so that it applies with no offset
and no fuzz.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix(functions): keep a null tool argument null

A tagged parameter whose text was "null" came out as an empty string:
unmarshalling JSON null into a string succeeds and leaves it empty, so
the value was taken for a string. Check the first byte of the JSON
value instead. A parameter with the text "null" now becomes JSON null,
as in llama.cpp.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* feat(functions): add an lfm3 XML format preset

The LFM3 chat template writes a call as <tool_call>, <function=NAME>,
one <parameter=KEY> block per argument, then the closing tags. The
qwen3-coder format has the same shape and auto-detection already found
it, but xml_format_preset: lfm3 was not a known name.

Add the preset, with tests for one call, a call without arguments, two
calls, string and non-string values (numbers, booleans, null, arrays,
objects), a call between text, and unfinished input.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* feat(realtime): parse tool calls with the chat template, as upstream

Since ggml-org/llama.cpp#31287 the realtime server handles tools with
the parser and grammar of the chat template. Do the same in the
speech-to-speech stream instead of a hard-coded tag filter and a parse
of the whole text at the end.

- Each response gets a common_chat_session with the tools of the
  session and parallel calls. Its grammar and preserved tokens go into
  the sampling of the response, so the slot keeps the call tokens in
  the text and constrains the call.
- The text of the response is fed to the session piece by piece
  (task_result_state::update_chat_msg). Content deltas become the
  transcript; tool-call deltas are collected into one
  function_call_arguments.done per call at the end. Audio after the
  start of a call is dropped.
- A tool_choice of auto, none or required is accepted in the params of
  the config, in session.update and in response.create, with the
  response overriding the session.
- The tool turn is derived from a conversation in which the assistant
  called a tool, like upstream, not from a plain reply.
- response.done carries raw_text, everything the model wrote with the
  call markup, for a caller that parses it another way. If the parser
  throws, the rest of the response is content and the raw text is the
  way out.

ToolCallFilter is no longer used and goes in the next commit.

The unit tests cover the splitter contract (content, call deltas, the
final piece, whole characters only). realtime_chat_check feeds
LFM3-format text through the session in pieces of 1, 7 and all bytes
and checks the call, the transcript and the grammar.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* refactor(realtime): drop the tool-call text filter

The parser of the chat template now splits content from tool calls, so
ToolCallFilter, which looked for the literal <tool_call> tags, has no
caller. Remove it with its tests. Every case it covered (a call
between text, split tags, several calls, an unfinished call, text after
a call) is handled by the parser, and realtime_chat_check runs the
LFM3 format through it in pieces of different sizes.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* feat(realtime): fall back to the raw text for S2S tool calls

For an any-to-any model, the calls the backend parsed still win. When
there are none and the request had tools, parse the raw text that
response.done now carries the way the chained pipeline parses the text
of its LLM (CleanupLLMResult, ParseFunctionCall, ParseTextContent), so
a call format the backend parser does not know can still be served
with function.xml_format_preset or the other function settings of the
model. The content around the calls replaces the streamed transcript
only if the config captures it, as in the chained path.

Also pass tool_choice to the backend: the session mode with the stream
config and with session.update, and the mode of a response.create
override with that event. A named function cannot be forced, so it is
not sent.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* test(e2e): carry raw_text in the mock S2S response.done

Match the llama-cpp session: with tools set, response.done has raw_text,
the call markup of the LFM3 template for a tool turn and the transcript
for any other reply.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix(functions): parse tool blocks that have text between them

The iterative XML parser stopped at the first scope block that was
preceded by text, so "<tool_call>A</tool_call> then <tool_call>B" gave
one call. Skip text between blocks once a call was found; text before
the first block still ends the parse as before. Blocks that follow each
other, or only whitespace, already worked.

Tests cover three calls back to back and with text between them, with
the lfm3 preset and with auto-detection. They also pin the current
reading of argument values: the parser has no tool schema, so a value
such as 42 or true is read as JSON even when the schema types it as a
string.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* feat(gallery): read LFM3-Audio tool calls with the lfm3 preset

Set function.xml_format_preset: lfm3 on the eight LFM3-Audio-2B entries
and in the config the importer writes for a speech-to-speech projector,
so the server parses the call format of the LFM3 chat template when the
backend returns no call (and in the chained pipeline entries, which use
the regular chat path). gallery/index.yaml is regenerated from the
library.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* docs(realtime): describe how S2S tool calls are read

Replace the description of the hard-coded tag filter with the parser
and grammar of the chat template, tool_choice, and the raw-text
fallback in the server. Document function.xml_format_preset, and set it
in the real-weights e2e model configs like the gallery entries do.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix(functions): keep earlier calls when a later block does not parse

After a valid call, text that holds the opening tag again (a prose
mention, a markdown example, a malformed second block) made the parser
treat it as a new block, fail, and return no calls at all. Remember the
state after each complete block and fall back to it when a later one
fails: the calls found so far are kept, parsing stops there and the
remaining text stays in the content.

Text skipped between two valid blocks now goes to the content instead of
being dropped, so StripToolCallMarkup keeps it.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix(realtime): do not drop audio after a tool call started

In mixed mode the speech for text written before a call can still be
pending when the call starts, so dropping every audio frame after the
first call delta cut the speech while its transcript was sent. The
llama.cpp server never drops audio when it reads a result; do the same.
If a model speaks the call markup aloud, that is model behaviour to
observe on real weights, not something to filter here.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix(realtime): flush held-back text when a response is cancelled

The parser got is_partial=true on a cancelled response, so text it held
back (a possible start of a tag) never reached the transcript. The llama.cpp
server parses a cancelled response with is_partial=false; do the same. A
cancelled response still makes no tool call. The path where the parser
throws already sends the text as content and needs no change.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* test(realtime): stop the fake S2S stream from sending after Close

The barge-in spec failed now and then with a data race and "send on
closed channel": its script pushes audio from a goroutine, and the
session closes the stream while that goroutine still runs. A push now
does nothing once the stream is closed, and Close waits for a push in
flight. The production close order is right: the writer closes the
stream only after it stops sending.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix(realtime): align the S2S tool-call fallback with the backend

Four gaps in how the Go side reads the tool calls of an any-to-any reply:

- With tool_choice none (the response value wins over the session value)
  the backend builds no tool parser, yet the raw-text fallback still
  turned a call the model wrote into a function_call item. Skip it.
- Without a capture regex the fallback never cleaned the transcript, so the
  stored item and transcript.done kept the raw call markup. When the call
  is XML, use the text left after the markup is cut out; a reply that is
  only a call now has an empty transcript.
- A named function as tool_choice mapped to nothing, so the backend kept
  the previous mode. Refuse it with an error in session.update and
  response.create.
- A response-level tools list changed what the fallback looked for, but
  the backend only has the tools of the session. Use those in both.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* docs(realtime): say how S2S tool_choice and response tools behave

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix(e2e): use the real llama-cpp backend in the real realtime run

The suite always registered the mock backend under the name llama-cpp, so
a run with REALTIME_S2S_MODEL set never reached the llama-cpp backend
found in REALTIME_BACKENDS_PATH. Register the mock only when that run is
off.

The real run converts the input audio with ffmpeg. Check for it in the
suite and in run-realtime-lfm3.sh before any download or backend start,
with a message that says what to install, and list it as a prerequisite
in the script header and the Makefile target.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* test(realtime): cover the tools path of a client session.update to the S2S backend

A tool call that never came back from an any-to-any model raised the
question whether the tools of the session reach the backend at all. Add a
spec that sends the session.update of the real-weights e2e (flat
Responses API tool, no session type) and checks that the backend gets
the tool in the chat-completions form.

Log the number of tools sent when the stream opens and when a
session.update carries them, so a run log shows it without reading the
wire. The "No tools received" line of the llama-cpp backend does not
show it: the server prints it for the input transcription request, which
has no tools by design.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* test(e2e): interrupt the chained pipeline reply while it is in flight

With unary stages, the default of the lfm3 pipeline gallery entries, the
chained pipeline synthesizes the whole reply and sends it as one audio
delta right before response.done. The barge-in spec waited for that
delta and then rendered the interruption with the TTS, so the first
response was already done when the speech started and ended completed
instead of cancelled. Real runs on a GPU showed it with both
quantizations.

For a pipeline, start the interruption at response.created, which comes
before the LLM and TTS stages. Render the interruption audio before the
first utterance is sent, so nothing sits between the reply and the
interruption. The any-to-any shape still waits for the first audio
delta, which that backend streams while it generates.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* test(e2e): accept a number word and its homophone in the spoken-answer check

The check that the reply audio says what the transcript says needs a
shared word of 4+ letters. A short answer failed it: the model wrote
"Four" and the ASR heard "for". Compare numbers in one spoken form, so
digits, number words and their homophones match each other. A homophone
only counts when the other text has the number itself, so "for" on both
sides still shares nothing and the check does not pass on a stop word.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix(llama-cpp): ask LFM3-Audio for function calls when a realtime session has tools

The default system prompt of a realtime session was "Respond with
interleaved text and audio." whatever the tools. Under that prompt
LFM3-Audio answers in words ("I'll check the weather ...") and never
writes the call. The model card, and the llama.cpp realtime example
client, use "Respond with function calls, and interleaved text and
audio." when the session has tools, and the model then calls the tool.

Pick the default by the tools of the session, and treat the plain default
that the LocalAI server sends back as no choice: it follows the tools too,
also when they arrive with a session.update before the first audio. A
prompt the client wrote is kept as it is.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix(realtime): transcribe the input of an any-to-any turn between responses

The input transcript of a speech-to-speech turn ran at the same time as
the reply, on the same model. llama.cpp serves both from one context: the
realtime slot wants embeddings on, the chat slot of the transcript wants
them off, and each flip makes it reserve its compute buffers again. In a
GB10 run that was two reserves of about 175 ms per step, the reply fell to
2.6 tokens per second and the transcript to 380 ms per token, until the
transcript was done.

When pipeline.transcription is the model of the stream, run the transcript
after the response, or before one that is not started yet, and keep
responses out while it runs. A separate transcription model still runs in
parallel.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix(realtime): send the input transcript of an any-to-any turn before its reply

The previous change moved the same-model transcript after the response.
A client that reads until response.done then never saw
conversation.item.input_audio_transcription.completed: the transcript
was made (the log shows it) but sent after the end of the window.

Run it in line with the commit instead. A VAD turn transcribes and then
responds. A client response.create already waits for the commit slot, so
it starts once the transcript is out. The transcript event now comes
before any output of the response of its turn, for a manual commit and for
a VAD turn, and never overlaps the response on the llama.cpp context. A
transcription model of its own still runs in parallel.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* feat(realtime): transcribe the input of an any-to-any model only when asked

The stream answers from the audio, so the transcript of the input is for
the client only. On the model of the stream it is costly: llama.cpp
serves the transcript request and the realtime stream from one context
and rebuilds its compute buffers on every step while both are active.
On a GB10 that was 26 to 29 reserves of about 175 ms per turn, against 0
to 1 on the llama.cpp server, and the reply ran at a few tokens per
second.

An any-to-any model no longer fills pipeline.transcription with its own
name. Without it the session does not transcribe the input; with another
model it does, in parallel with the reply; with the model itself named it
does, before the reply. The reply transcript always comes from the stream.
The gallery entries set none, so they get the fast path.

The mock configs and run-realtime-lfm3.sh name a transcription model, so
the real-weights spec still covers the input transcript.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix(realtime): end a response as cancelled when a barge-in lands during the LLM call

The chained pipeline cancels the response context on a barge-in. When that
happens while the model is generating, the backend call fails with the
context error, and the response ended as failed: an error event and no
response.done. A client that waits for the terminal of the interrupted
response then waits forever. On a GB10 the q4 model answered before the
barge-in arrived, so only the slower q8 model showed it: the spec read
events for 30 s and timed out.

When the context is cancelled, a failed Predict call or a failed result is
a cancel, as the TTS step and the streamed LLM path already treat it. The
response ends with response.done{cancelled} and no error.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* test(e2e): wait for the input transcript that comes from a model of its own

An any-to-any model now gets its input transcript from a separate ASR
that runs next to the reply. The reply is often over first, so a spec that
stops reading at response.done saw no transcript in the VAD shape. Keep
reading, up to 30 s, until the transcript arrives. The contract is that it
comes, not when.

Add a guard spec for what the input transcription is handed: the whole
turn, in a WAV that says the rate it was recorded at (the session rate for
a client commit, 16 kHz for a VAD turn).

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* test(e2e): check the errors of Close in the realtime specs

golangci-lint (errcheck) flagged the unchecked Close of the websocket
connections, the response body and the fake stream. Use the
`defer func() { _ = x.Close() }()` form the other e2e specs use.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* test(e2e): write the mock S2S specs with Ginkgo and drop the env read

forbidigo only allows Ginkgo/Gomega specs and no os.Getenv outside the
sanctioned places. Convert the mock S2S tests to Describe/It with a suite
bootstrap (the package had none), with the same 11 cases. The mock no
longer reads MOCK_S2S_FRAMES: only these specs set it, so the reply length
is a package variable they change per spec and restore afterwards.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

---------

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Co-authored-by: Ettore Di Giacinto <mudler@localai.io>
2026-10-29 22:06:41 +01:00

11359 lines
332 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
basePath: /
definitions:
addons.AddonError:
properties:
blockedBy:
description: |-
BlockedBy is the unresolved operation that blocks the write. It is
present only with type outcome_blocked, and only for the owner role of
the resource.
type: string
code:
description: Code repeats the HTTP status. It is absent from outcome_unknown
responses.
type: integer
message:
description: Message describes the failure and never carries owner details.
type: string
operationId:
description: |-
OperationID is the original operation, which is the proposal ID for a
proposal call. It is present only with type outcome_unknown or
proposal_unavailable.
type: string
type:
description: |-
Type is addon_error, outcome_unknown when a mutation may have run,
proposal_unavailable when a proposal call could not be served and the
same call can be repeated by the same proposal ID after reading it, or
outcome_blocked (403) when another operation on the resource has an
unresolved outcome and the caller is the resource's owner role. The
resource management routes add sharing_disabled (409, local-owner mode
has no named users to share with), stale (409, the generation or the
revision the caller saw is out of date), operation_conflict (409, the
operation ID was used for another request and nothing was applied),
invalid_request (400, for
example a missing deletion confirmation or an unsupported operation),
quota_reached (403) and not_selected (404, no resource is selected for
the conversation).
example: outcome_unknown
type: string
type: object
addons.AddonErrorResponse:
properties:
error:
$ref: '#/definitions/addons.AddonError'
type: object
addons.ConfirmRequest:
properties:
digest:
description: Digest is the digest of the proposal as it was displayed.
type: string
type: object
addons.RecoveryBackupRequest:
properties:
operationId:
description: |-
OperationID identifies the request. Repeating it returns the backup it
made and makes no second one.
type: string
type: object
addons.RecoveryDeleteBackupRequest:
properties:
backupId:
type: string
operationId:
type: string
type: object
addons.RecoveryDeleted:
properties:
deleted:
type: string
type: object
addons.RecoveryPruneRequest:
properties:
operationId:
type: string
type: object
addons.RecoveryPruned:
properties:
removed:
items:
type: string
type: array
type: object
addons.RecoveryPurgeRequest:
properties:
confirm:
description: Confirm is the add-on's ID, typed.
type: string
operationId:
type: string
scope:
$ref: '#/definitions/recovery.PurgeScope'
type: object
addons.RecoveryRestoreRequest:
properties:
backupId:
type: string
confirm:
description: Confirm is the add-on's ID, typed.
type: string
mapping:
additionalProperties:
type: string
description: |-
Mapping names the current account that takes the data of a backup made
in another ownership mode, as {"local-owner": "<account id>"}. It is
explicit: there is no wildcard and no default.
type: object
operationId:
type: string
type: object
addons.RecoveryVerifyRequest:
properties:
backupId:
type: string
operationId:
type: string
type: object
addons.ResolveRequest:
properties:
digest:
description: Digest is the digest of the proposal as it was displayed.
type: string
reason:
description: Reason is why the owner stops waiting. Required, at most 512
characters.
type: string
type: object
addons.UpdateCheckRequest:
properties:
operationId:
description: OperationID identifies the request and is the confirmation header.
example: check-notes-1
type: string
type: object
addons.UpgradeRequest:
properties:
candidateDigest:
description: CandidateDigest is the digest of the candidate the check resolved.
example: sha256:fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210
type: string
expectedDigest:
description: ExpectedDigest is the digest of the installed package the caller
saw.
example: sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
type: string
generation:
description: Generation is the installed generation the caller saw, when it
knows it.
example: 1
type: integer
operationId:
description: |-
OperationID is the identity of the upgrade: repeat it to replay safely
and, after an outcome_unknown answer, poll operation-status with it. The
same transition under another operation ID is refused.
example: upgrade-notes-1
type: string
type: object
apps.AdminView:
properties:
canStart:
type: boolean
canStop:
type: boolean
managementUrl:
description: ManagementURL opens the management view of the addon.
example: /app/addons?manage=notes
type: string
type: object
apps.App:
properties:
admin:
allOf:
- $ref: '#/definitions/apps.AdminView'
description: Admin is present only for administrators.
description:
example: Keep notes.
type: string
descriptions:
additionalProperties:
type: string
type: object
enabled:
description: |-
Enabled is the durable desired state. Health is State, a separate
observation: an enabled app can be failed.
type: boolean
generation:
description: |-
Generation is the installed generation. A Start or Stop request must
carry the value that was listed; a stale value is denied.
example: 3
type: integer
hasUI:
description: HasUI is true when the addon contributes any UI.
type: boolean
icon:
description: |-
Icon is a same-origin URL of the verified immutable icon of this
generation. It is absent when the manifest declares none.
example: /api/addons/apps/notes/icon?generation=3
type: string
id:
description: |-
ID is the addon identifier and Name its stable machine name. They are
the same in version one: the receipt records no separate catalog name.
example: notes
type: string
launchMode:
example: always
type: string
mainPage:
description: |-
MainPage is the path the Open action navigates to. It is present only
for an enabled addon whose manifest declares a main page that is one of
its pages.
example: /app/addons/notes/home
type: string
name:
example: notes
type: string
state:
description: |-
State is running, starting, failed or stopped: the observation of the
process, never an update.
enum:
- running
- starting
- failed
- stopped
example: running
type: string
title:
description: |-
Title and Description are the default-language text of the manifest.
Titles and Descriptions carry every language when the manifest
localizes the text, keyed by BCP 47 tag; they are absent otherwise.
example: Notes
type: string
titles:
additionalProperties:
type: string
type: object
toolCount:
type: integer
toolDefinitions:
description: |-
ToolDefinitions are the model-facing definitions the manifest declares:
the argument schema and the kind of each tool. The host serves them to
chat from the verified manifest; the add-on process is never asked.
items:
$ref: '#/definitions/contract.ToolDefinition'
type: array
tools:
description: |-
Tools are the tool names of the manifest, at most 32. ToolCount is the
full number. The manifest carries no tool descriptions.
items:
type: string
type: array
ui:
allOf:
- $ref: '#/definitions/apps.UIView'
description: |-
UI describes what the shell loads for this app. It is present only for
an enabled addon with a UI whose installed package has a sha256 digest.
update:
description: |-
Update is update-pending when the owner's cached update check says an
update is available for the installed package. It is a separate
observation from State and is absent otherwise: an unchecked, failed
or up to date add-on has none. The list never reaches a library.
enum:
- update-pending
example: update-pending
type: string
version:
example: 1.2.3
type: string
type: object
apps.ChatActionView:
properties:
component:
example: SummaryPanel
type: string
icon:
description: |-
Icon is a host icon name, or the empty string when the action uses the
packaged icon of the app (see the icon of the app).
example: sparkles
type: string
id:
description: ID is the manifest identifier of the action.
example: summarize
type: string
label:
description: |-
Label is the default-language text; Labels carries every language when
the manifest localizes it.
example: Summarize
type: string
labels:
additionalProperties:
type: string
type: object
packagedIcon:
description: PackagedIcon is true when the action draws the packaged app icon.
type: boolean
placement:
description: Placement is composer or message.
enum:
- composer
- message
example: composer
type: string
tool:
description: |-
Tool is the own tool the action calls, or Component the exported
component it opens. Exactly one is set.
example: summarize
type: string
type: object
apps.List:
properties:
apps:
items:
$ref: '#/definitions/apps.App'
type: array
type: object
apps.SlotView:
properties:
component:
example: NotesSettings
type: string
id:
example: notes-nav
type: string
slot:
enum:
- chat.composer.actions
- chat.message.actions
- app.nav
- settings.sections
example: settings.sections
type: string
type: object
apps.StartRequest:
properties:
generation:
description: Generation is the installed generation the caller saw in the
list.
example: 3
type: integer
operationId:
description: |-
OperationID names the lifecycle operation. Repeating it never runs the
change twice and, after an outcome_unknown answer, it is the identifier
to poll.
example: start-notes-1
type: string
type: object
apps.UIView:
properties:
actions:
description: |-
Actions are the chat actions that declare a placement and a target.
Slots and Renderers are the other declared contributions. The manifest
was validated at install: every tool named here is a tool of the addon,
every slot is a host slot and every icon is a host icon name or the
packaged icon. The host draws them only while the addon is enabled and
usable by the caller.
items:
$ref: '#/definitions/apps.ChatActionView'
type: array
chatActions:
items:
type: string
type: array
css:
description: CSS are the URLs of the declared style sheets.
items:
type: string
type: array
entry:
description: |-
Entry is the URL of the packaged ES module. Every asset URL names the
package digest, so a new package is a new URL.
example: /api/addons/notes/assets/0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef/ui.js
type: string
navigation:
items:
type: string
type: array
pages:
description: |-
Pages, Navigation and ChatActions are the identifiers the manifest
declares. The host decides where each one is shown.
items:
type: string
type: array
renderers:
items:
$ref: '#/definitions/contract.Renderer'
type: array
sdk:
allOf:
- $ref: '#/definitions/contract.VersionRange'
description: SDK is the range of host SDK versions the module accepts.
slots:
items:
$ref: '#/definitions/apps.SlotView'
type: array
type: object
auth.WebSocketTicketResponse:
properties:
expires_at:
type: string
ticket:
type: string
type: object
backendlib.Update:
properties:
digest:
type: string
installedDigest:
type: string
installedVersion:
description: InstalledVersion and InstalledDigest are what metadata.json pins.
type: string
name:
description: Name is the backend name.
type: string
signed:
description: |-
Signed says the library requires a signature, so the install of the
update has a verifying step.
type: boolean
sourceId:
description: SourceID is the library the backend came from.
type: string
version:
description: |-
Version and Digest are the build the library lists now. Version is what
an install of the update names.
type: string
type: object
builtin.Entry:
properties:
adminOnly:
type: boolean
feature:
type: string
icon:
type: string
id:
type: string
kind:
$ref: '#/definitions/builtin.Kind'
mainPath:
type: string
titleKey:
type: string
type: object
builtin.Kind:
enum:
- page
type: string
x-enum-varnames:
- KindPage
catalog.Kind:
enum:
- addon
- backend
- model
- all
type: string
x-enum-varnames:
- KindAddon
- KindBackend
- KindModel
- QueryAllKinds
catalog.RefreshState:
properties:
checkedAt:
type: string
count:
type: integer
failed:
description: |-
Failed is true when the latest fetch failed; the previous releases are
not served in that case.
type: boolean
lastSuccess:
type: string
skipped:
description: Skipped and SkippedKinds are as in RefreshResult.
type: integer
skippedKinds:
items:
type: string
type: array
type: object
catalog.VerificationPolicy:
properties:
identity:
type: string
identityRegex:
description: |-
IdentityRegex is an anchored pattern for the signer identity, used
instead of Identity so that master and tagged builds both verify. Only a
library that serves backends may use it; an add-on install refuses it.
type: string
issuer:
type: string
requireSignature:
type: boolean
type: object
config.Gallery:
properties:
artifact_verification:
allOf:
- $ref: '#/definitions/config.GalleryVerification'
description: |-
ArtifactVerification overrides Verification only for the gallery OCI artifact.
Backend images keep their separate Verification policy.
library:
description: |-
Library says the URL is a model library (the shared library entry
shape), not a gallery index.
type: boolean
mirrors:
description: |-
Mirrors are tried in order when URL cannot be fetched. They are a
fallback for availability, not a load-balancing pool: the primary is
always preferred, and a mirror is only consulted after the one before
it fails. Any URI the gallery loader understands works here
(https://, github:, file://, oci://).
items:
type: string
type: array
name:
type: string
url:
type: string
verification:
$ref: '#/definitions/config.GalleryVerification'
type: object
config.GalleryVerification:
properties:
identity:
type: string
identity_regex:
type: string
issuer:
type: string
issuer_regex:
type: string
not_before:
description: NotBefore is an RFC3339 timestamp. Empty disables the time check.
type: string
source_repository:
description: |-
SourceRepository is an https URL compared exactly against the
certificate's source-repository extension. Empty skips the check.
type: string
type: object
config.TTSVoice:
properties:
gender:
type: string
language:
type: string
name:
type: string
type: object
contract.OutputDescription:
properties:
handle:
type: string
mediaType:
type: string
name:
type: string
size:
type: integer
type: object
contract.Receipt:
properties:
operationId:
type: string
result:
$ref: '#/definitions/contract.Result'
revision:
$ref: '#/definitions/contract.Revision'
state:
$ref: '#/definitions/contract.ReceiptState'
type: object
contract.ReceiptState:
enum:
- pending
- committed
- rejected
- unknown
type: string
x-enum-varnames:
- ReceiptPending
- ReceiptCommitted
- ReceiptRejected
- ReceiptUnknown
contract.Renderer:
properties:
component:
type: string
kind:
type: string
tool:
type: string
type: object
contract.Request:
properties:
action:
type: string
addonId:
type: string
arguments:
type: object
generation:
type: integer
operationId:
type: string
resourceId:
type: string
type: object
contract.Result:
properties:
outputs:
items:
$ref: '#/definitions/contract.OutputDescription'
type: array
payload:
type: object
type: object
contract.Revision:
properties:
data:
type: integer
schema:
type: integer
type: object
contract.ToolDefinition:
properties:
description:
description: Description is plain text for the model.
type: string
inputSchema:
description: |-
InputSchema is the JSON schema of the arguments object. It is an
object schema with explicit properties, additionalProperties false at
the top level and the keywords the host allows only.
type: object
kind:
description: Kind is read, write, schema or create.
type: string
name:
description: Name is one of capabilities.tools.
type: string
type: object
contract.VersionRange:
properties:
max:
type: integer
min:
type: integer
type: object
failover.ChainState:
enum:
- primary
- fallback
- degraded
type: string
x-enum-varnames:
- ChainPrimary
- ChainFallback
- ChainDegraded
failover.ChainStatus:
properties:
active:
type: string
active_since:
type: string
name:
type: string
pinned:
type: string
state:
$ref: '#/definitions/failover.ChainState'
targets:
items:
$ref: '#/definitions/failover.TargetStatus'
type: array
type: object
failover.Kind:
enum:
- local
- remote
type: string
x-enum-varnames:
- KindLocal
- KindRemote
failover.TargetState:
enum:
- healthy
- down
- recovering
- missing
type: string
x-enum-varnames:
- StateHealthy
- StateDown
- StateRecovering
- StateMissing
failover.TargetStatus:
properties:
consecutive_ok:
type: integer
kind:
$ref: '#/definitions/failover.Kind'
last_error:
type: string
last_probe:
type: string
model:
type: string
state:
$ref: '#/definitions/failover.TargetState'
warm:
type: boolean
type: object
functions.Function:
properties:
description:
type: string
name:
type: string
parameters:
additionalProperties: {}
type: object
strict:
type: boolean
type: object
functions.Item:
properties:
properties:
additionalProperties: {}
type: object
type:
type: string
type: object
functions.JSONFunctionStructure:
properties:
$defs:
additionalProperties: {}
type: object
anyOf:
items:
$ref: '#/definitions/functions.Item'
type: array
oneOf:
items:
$ref: '#/definitions/functions.Item'
type: array
type: object
functions.Tool:
properties:
function:
$ref: '#/definitions/functions.Function'
type:
type: string
type: object
gallery.File:
properties:
filename:
type: string
sha256:
type: string
uri:
type: string
type: object
gallery.GalleryBackend:
properties:
alias:
type: string
backend:
description: |-
Backend is the resolved backend engine for this model (e.g. "llama-cpp").
Populated at load time from overrides, inline config, or the URL-referenced config file.
type: string
capabilities:
additionalProperties:
type: string
type: object
description:
type: string
files:
description: AdditionalFiles are used to add additional files to the model
items:
$ref: '#/definitions/gallery.File'
type: array
gallery:
allOf:
- $ref: '#/definitions/config.Gallery'
description: Gallery is a reference to the gallery which contains the model
icon:
type: string
installed:
description: Installed is used to indicate if the model is installed or not
type: boolean
license:
type: string
mirrors:
items:
type: string
type: array
name:
type: string
sha256:
description: |-
SHA256 is the expected sha256 of the backend tarball at URI / Mirrors.
Empty disables the integrity check; OCI URIs carry their own digest.
type: string
size:
description: |-
Size is an optional hardcoded model size string (e.g. "500MB", "14.5GB").
Used when the size cannot be estimated automatically.
type: string
tags:
items:
type: string
type: array
uri:
type: string
url:
type: string
urls:
items:
type: string
type: array
version:
type: string
type: object
gallery.Metadata:
properties:
backend:
description: |-
Backend is the resolved backend engine for this model (e.g. "llama-cpp").
Populated at load time from overrides, inline config, or the URL-referenced config file.
type: string
description:
type: string
files:
description: AdditionalFiles are used to add additional files to the model
items:
$ref: '#/definitions/gallery.File'
type: array
gallery:
allOf:
- $ref: '#/definitions/config.Gallery'
description: Gallery is a reference to the gallery which contains the model
icon:
type: string
installed:
description: Installed is used to indicate if the model is installed or not
type: boolean
license:
type: string
name:
type: string
size:
description: |-
Size is an optional hardcoded model size string (e.g. "500MB", "14.5GB").
Used when the size cannot be estimated automatically.
type: string
tags:
items:
type: string
type: array
url:
type: string
urls:
items:
type: string
type: array
type: object
gallery.ModelStorage:
properties:
files:
items:
type: string
type: array
missing:
items:
type: string
type: array
name:
type: string
shared_bytes:
type: integer
size_bytes:
type: integer
type: object
gallery.NodeDriftInfo:
properties:
digest:
type: string
node_id:
type: string
node_name:
type: string
version:
type: string
type: object
gallery.StorageFile:
properties:
missing:
type: boolean
models:
items:
type: string
type: array
path:
description: Path is relative to the models directory.
type: string
size_bytes:
type: integer
type: object
gallery.StorageIndex:
properties:
errors:
description: |-
Errors carries per-config failures (malformed YAML, path escapes),
reported rather than fatal so one broken config cannot blank the
whole report.
items:
type: string
type: array
files:
items:
$ref: '#/definitions/gallery.StorageFile'
type: array
models:
items:
$ref: '#/definitions/gallery.ModelStorage'
type: array
total_bytes:
type: integer
type: object
gallery.UpgradeInfo:
properties:
available_digest:
type: string
available_version:
type: string
backend_name:
type: string
installed_digest:
type: string
installed_version:
type: string
node_drift:
description: |-
NodeDrift lists nodes whose installed version or digest differs from
the cluster majority. Non-empty means the cluster has diverged and an
upgrade will realign it. Empty in single-node mode.
items:
$ref: '#/definitions/gallery.NodeDriftInfo'
type: array
reason:
description: |-
Reason says why the backend is flagged when version and digest alone
would not flag it: the backend failed a request in a way that shows it
is older than the server. Empty for ordinary version or digest upgrades.
type: string
type: object
gallery.Variant:
properties:
model:
description: Model is the name of a gallery entry that declares no variants
of its own.
type: string
type: object
galleryop.NodeProgress:
properties:
current:
type: string
error:
type: string
file_name:
type: string
node_id:
type: string
node_name:
type: string
percentage:
type: number
phase:
type: string
status:
type: string
total:
type: string
type: object
galleryop.OpStatus:
properties:
cancellable:
description: Cancellable is true if the operation can be cancelled
type: boolean
cancelled:
description: Cancelled is true if the operation was cancelled
type: boolean
current_bytes:
type: integer
deletion:
description: Deletion is true if the operation is a deletion
type: boolean
downloaded_size:
type: string
file_name:
type: string
file_size:
type: string
gallery_element_name:
type: string
message:
type: string
nodes:
description: |-
Nodes is the per-node breakdown for a fanned-out backend install.
Populated by DistributedBackendManager (per-node terminal status)
and by the Phase 2 progress bridge (per-byte ticks). The
/api/operations handler surfaces this so the UI can render an
expandable per-node view of an in-flight install.
items:
$ref: '#/definitions/galleryop.NodeProgress'
type: array
phase:
type: string
processed:
type: boolean
progress:
type: number
total_bytes:
type: integer
type: object
gateway.ApplyResourceRequest:
properties:
arguments:
description: |-
Arguments are the tool's own arguments without the resource, which the
path names, and without the tool, which Tool names.
type: object
generation:
description: Generation is the installed generation the caller listed.
example: 3
type: integer
operationId:
description: |-
OperationID names the change. Repeating it with the same request
returns the same receipt and never applies twice; after an
outcome_unknown answer it is what to repeat.
example: apply-1
type: string
revision:
allOf:
- $ref: '#/definitions/contract.Revision'
description: |-
Revision is the revision the caller read. A moved revision is a stale
denial and nothing is changed.
tool:
description: Tool is a write or schema tool the add-on declares.
example: rows-insert
type: string
type: object
gateway.ApplyResult:
properties:
operationId:
type: string
requestHash:
description: |-
RequestHash binds the operation ID to the request: the SHA-256 of the
resource, the tool and the canonical arguments. A lookup of the
operation reports it, so a client can tell its own request from
another one that used the same ID.
example: 3f786850e387550fdab836ed7e6dc881de23001b3f786850e387550fdab836ed
type: string
resourceId:
type: string
result:
description: |-
Result is what the add-on's receipt reported, for example the count
and the identifiers of the changed rows.
type: object
revision:
allOf:
- $ref: '#/definitions/contract.Revision'
description: Revision is the revision after the change.
type: object
gateway.Artifact:
properties:
addonId:
description: AddonID and Generation name the addon build that produced the
result.
type: string
createdAt:
type: string
expiresAt:
description: ExpiresAt is when the artifact stops being served and is removed.
type: string
generation:
type: integer
id:
description: |-
ID is the host-generated opaque identifier. It is the only handle a
client ever holds for the file.
type: string
mediaType:
type: string
name:
description: |-
Name is the sanitized attachment name and MediaType the safe media type
the download is served with.
type: string
operationId:
description: OperationID is the operation of the request that produced the
output.
type: string
principal:
description: |-
Principal is the user who requested the result. Only this user can read
or download the artifact.
type: string
reason:
description: |-
Reason says why a transfer failed or was cancelled. It never carries
addon text.
type: string
size:
description: Size is the exact number of bytes of a complete artifact.
type: integer
sources:
description: |-
Sources are the resources the bytes were produced from. Every one of
them must still be readable by the principal at completion and at each
download.
items:
$ref: '#/definitions/gateway.ArtifactResource'
type: array
state:
$ref: '#/definitions/gateway.ArtifactState'
type: object
gateway.ArtifactResource:
properties:
addonId:
type: string
resourceId:
type: string
type: object
gateway.ArtifactState:
enum:
- transferring
- complete
- failed
- cancelled
type: string
x-enum-varnames:
- ArtifactTransferring
- ArtifactComplete
- ArtifactFailed
- ArtifactCancelled
gateway.BlockingProposal:
properties:
action:
type: string
addonId:
type: string
ageSeconds:
description: |-
AgeSeconds is how long the outcome has been unresolved, counted from
the hand-over to the addon.
type: integer
createdAt:
type: string
digest:
description: Digest is what the owner names to resolve the proposal.
type: string
effects:
$ref: '#/definitions/gateway.ProposalEffects'
expiresAt:
type: string
id:
description: ID is the proposal identifier, which is its operation identifier.
type: string
proposerId:
description: ProposerID is the user who proposed the operation.
type: string
reason:
description: Reason says why the outcome is unresolved.
type: string
resolution:
allOf:
- $ref: '#/definitions/gateway.ProposalResolution'
description: Resolution is present once the owner stopped waiting.
resourceId:
type: string
state:
allOf:
- $ref: '#/definitions/gateway.ProposalState'
description: State is executing, outcome-unknown or abandoned-unknown.
type: object
gateway.CreateResourceRequest:
properties:
addonId:
description: AddonID names the add-on whose resource is created.
example: tables
type: string
arguments:
description: |-
Arguments are the create arguments the add-on's create tool takes, for
example the name. They are validated against its tool definition.
type: object
generation:
description: Generation is the installed generation the caller listed.
example: 3
type: integer
operationId:
description: |-
OperationID names the creation. Repeating it never creates a second
resource and, after an outcome_unknown answer, it is what to repeat.
example: create-budget-1
type: string
type: object
gateway.DeleteResourceRequest:
properties:
confirm:
description: |-
Confirm must equal the display name of the resource exactly: the person
types it to confirm. Deletion removes the data and every grant, cannot
be undone and is never a chat operation.
example: Budget
type: string
generation:
example: 3
type: integer
operationId:
example: delete-1
type: string
revision:
$ref: '#/definitions/contract.Revision'
type: object
gateway.DeleteResult:
properties:
deleted:
description: |-
Deleted is true once the add-on confirmed that the data is gone and
the grants were removed.
type: boolean
resourceId:
type: string
type: object
gateway.Grant:
properties:
displayName:
example: Bob
type: string
role:
enum:
- viewer
- editor
example: viewer
type: string
userId:
description: UserID is the immutable account identifier of the grantee.
example: 4f1c
type: string
type: object
gateway.GrantList:
properties:
grants:
items:
$ref: '#/definitions/gateway.Grant'
type: array
resourceId:
type: string
type: object
gateway.OperationStatus:
properties:
operationId:
type: string
requestHash:
example: 3f786850e387550fdab836ed7e6dc881de23001b3f786850e387550fdab836ed
type: string
state:
description: State is pending, committed, rejected or unknown.
enum:
- pending
- committed
- rejected
- unknown
type: string
tool:
description: |-
Tool and RequestHash name the request the operation ID was first
used for, as the host recorded it when it dispatched the change (kind
apply only). They are absent when the host no longer holds the
request, for example after a restart. Compare RequestHash with the
hash of your own request before you believe a committed state.
example: rows-insert
type: string
type: object
gateway.PendingList:
properties:
proposals:
description: |-
Proposals are the caller's own proposals that still wait for a human
decision, newest first. A proposal of another user is never listed.
items:
$ref: '#/definitions/gateway.Proposal'
type: array
type: object
gateway.Proposal:
properties:
action:
type: string
addonId:
type: string
arguments:
description: |-
Arguments are the canonical stored arguments. They are the only
arguments that can ever be submitted for this proposal.
type: object
blocked:
description: |-
Blocked reports that another operation on the resource has an
unresolved outcome, so confirming is denied until it is resolved. The
operation itself belongs to its proposer and is shown only to the
resource's owner role, in the unresolved listing and in the denial.
type: boolean
createdAt:
type: string
digest:
description: Digest binds a confirmation to exactly what was shown.
type: string
effects:
$ref: '#/definitions/gateway.ProposalEffects'
expiresAt:
type: string
generation:
type: integer
id:
description: |-
ID is the proposal identifier. It is the operation identifier of the
stored operation, so a lost reply is always resolved by the same ID.
type: string
operationId:
type: string
reason:
description: Reason says why a proposal is cancelled, expired or rejected.
type: string
receipt:
allOf:
- $ref: '#/definitions/contract.Receipt'
description: Receipt is present once the runtime answered.
resolution:
allOf:
- $ref: '#/definitions/gateway.ProposalResolution'
description: |-
Resolution is present once the resource owner stopped waiting for an
unresolved outcome. It stays after a late receipt is recorded.
resourceId:
type: string
revision:
allOf:
- $ref: '#/definitions/contract.Revision'
description: |-
Revision is the schema and data revision the preview saw. The runtime
refuses the apply when it moved.
state:
$ref: '#/definitions/gateway.ProposalState'
type: object
gateway.ProposalEffects:
properties:
count:
description: Count is the exact number of effects the operation would have.
type: integer
sample:
description: |-
Sample is a bounded excerpt of the effects, or the whole preview summary
when the addon did not separate one.
type: object
type: object
gateway.ProposalList:
properties:
proposals:
items:
$ref: '#/definitions/gateway.BlockingProposal'
type: array
type: object
gateway.ProposalResolution:
properties:
actorId:
description: ActorID is the resource owner who acknowledged the unknown outcome.
type: string
at:
description: At is when the acknowledgement was recorded.
type: string
reason:
description: Reason is the owner's stated reason.
type: string
type: object
gateway.ProposalState:
enum:
- pending
- cancelled
- expired
- executing
- applied
- rejected
- outcome-unknown
- abandoned-unknown
type: string
x-enum-varnames:
- ProposalPending
- ProposalCancelled
- ProposalExpired
- ProposalExecuting
- ProposalApplied
- ProposalRejected
- ProposalOutcomeUnknown
- ProposalAbandoned
gateway.RelayRequest:
properties:
digest:
description: |-
Digest names the installed package an asset belongs to: the lower-case
hex of its sha256. Only the kind "asset" uses it.
type: string
handle:
type: string
kind:
type: string
request:
$ref: '#/definitions/contract.Request'
type: object
gateway.RenameResourceRequest:
properties:
generation:
example: 3
type: integer
name:
example: Budget 2027
type: string
operationId:
example: rename-1
type: string
revision:
allOf:
- $ref: '#/definitions/contract.Revision'
description: |-
Revision is the revision the caller listed. A moved revision is a
stale denial and nothing is changed.
type: object
gateway.ResourceInfo:
properties:
addonId:
example: tables
type: string
id:
description: ID is the opaque resource identifier.
example: r0123456789abcdef0123456789abcde
type: string
name:
description: |-
Name is the display name the add-on reported. It is empty when the
add-on could not answer in time.
example: Budget
type: string
owner:
description: |-
Owner is the display name of the owner, shown to people the resource
is shared with. It is empty in local-owner mode.
example: Alice
type: string
revision:
allOf:
- $ref: '#/definitions/contract.Revision'
description: |-
Revision is the schema and data revision the listing saw. It is
present for the owner role and goes back with a rename or a delete.
role:
description: 'Role is the caller''s own role: viewer, editor or owner.'
enum:
- viewer
- editor
- owner
example: owner
type: string
sharedWith:
description: |-
SharedWith is the number of people the resource is shared with. It is
present for the owner role only.
example: 2
type: integer
type: object
gateway.ResourceList:
properties:
addonId:
example: tables
type: string
generation:
description: |-
Generation is the installed generation the listing saw. Rename, delete
and create carry it; a stale tab is denied.
example: 3
type: integer
noun:
description: Noun is the singular word the add-on uses for its resources.
example: database
type: string
operations:
description: Operations lists the management operations the add-on supports.
items:
enum:
- create
- rename
- delete
type: string
type: array
resources:
items:
$ref: '#/definitions/gateway.ResourceInfo'
type: array
sharing:
description: Sharing is false in local-owner mode, where nothing can be shared.
type: boolean
truncated:
description: Truncated says more resources exist than the bound lists.
type: boolean
type: object
gateway.Selection:
properties:
addonId:
example: tables
type: string
conversationId:
example: chat-1
type: string
name:
example: Budget
type: string
resourceId:
example: r0123456789abcdef0123456789abcde
type: string
role:
enum:
- viewer
- editor
- owner
type: string
type: object
gateway.SelectionRequest:
properties:
resourceId:
description: |-
ResourceID is the resource to use in the conversation. The caller must
hold at least the viewer role on it now.
example: r0123456789abcdef0123456789abcde
type: string
type: object
gateway.SetGrantRequest:
properties:
operationId:
description: |-
OperationID is optional. It is returned with outcome_unknown, and the
change is safe to repeat.
example: grant-1
type: string
role:
description: Role is viewer or editor. The owner role cannot be granted.
enum:
- viewer
- editor
example: viewer
type: string
type: object
gateway.UserList:
properties:
users:
items:
$ref: '#/definitions/gateway.UserRef'
type: array
type: object
gateway.UserRef:
properties:
displayName:
example: Bob
type: string
id:
example: 4f1c
type: string
type: object
library.Info:
properties:
authReference:
type: string
conflict:
description: Conflict explains how this source clashes with another one, when
it does.
type: string
default:
type: boolean
enabled:
description: |-
Enabled is what the host does with the source: false for a source that
is turned off, removed, or a shipped default while the official
libraries are off. Suspended tells the last case apart.
type: boolean
format:
type: string
id:
type: string
kind:
$ref: '#/definitions/catalog.Kind'
mirrors:
description: Mirrors are the fallback addresses of the source, in order.
items:
type: string
type: array
name:
type: string
policy:
$ref: '#/definitions/catalog.VerificationPolicy'
refresh:
$ref: '#/definitions/catalog.RefreshState'
removed:
type: boolean
suspended:
type: boolean
url:
type: string
type: object
localai.APIInstructionResponse:
properties:
description:
type: string
name:
type: string
swagger_fragment:
additionalProperties: {}
type: object
tags:
items:
type: string
type: array
type: object
localai.AliasInfo:
properties:
name:
type: string
target:
type: string
type: object
localai.BackendLibraryInstallRequest:
properties:
name:
description: Name is the backend name of the entry.
type: string
sourceId:
description: SourceID is the library the entry comes from.
type: string
version:
description: Version is the version or the channel of the entry.
type: string
type: object
localai.BrandingResponse:
properties:
favicon_url:
type: string
instance_name:
type: string
instance_tagline:
type: string
logo_horizontal_url:
type: string
logo_url:
type: string
type: object
localai.FailoverChainsResponse:
properties:
chains:
items:
$ref: '#/definitions/failover.ChainStatus'
type: array
type: object
localai.FailoverPinRequest:
properties:
target:
type: string
type: object
localai.GalleryBackend:
properties:
force:
description: |-
Force reinstalls the backend even when it is already installed and
runnable. Off by default so apply stays idempotent for supervising
apps that ensure their backend on every boot.
type: boolean
id:
type: string
type: object
localai.GalleryModel:
properties:
backend:
description: |-
Backend is the resolved backend engine for this model (e.g. "llama-cpp").
Populated at load time from overrides, inline config, or the URL-referenced config file.
type: string
config_file:
additionalProperties: {}
description: config_file is read in the situation where URL is blank - and
therefore this is a base config.
type: object
description:
type: string
files:
description: AdditionalFiles are used to add additional files to the model
items:
$ref: '#/definitions/gallery.File'
type: array
gallery:
allOf:
- $ref: '#/definitions/config.Gallery'
description: Gallery is a reference to the gallery which contains the model
icon:
type: string
id:
type: string
installed:
description: Installed is used to indicate if the model is installed or not
type: boolean
license:
type: string
name:
type: string
overrides:
additionalProperties: {}
description: Overrides are used to override the configuration of the model
located at URL
type: object
size:
description: |-
Size is an optional hardcoded model size string (e.g. "500MB", "14.5GB").
Used when the size cannot be estimated automatically.
type: string
tags:
items:
type: string
type: array
url:
type: string
urls:
items:
type: string
type: array
variant:
description: |-
Variant installs one specific build of an entry that declares variants,
named as it appears in the entry's `variants` list (see the `variants`
and `auto_variant` fields of the gallery listing). Leave it empty to let
LocalAI auto-select the largest build this host can actually run.
type: string
variants:
description: |-
Variants is an optional, UNORDERED list of alternative builds of the same
model (other backends such as MLX or vLLM, other quantizations) that the
installer may pick instead of this entry's own payload. Authoring is
deliberately dumb: name the models, and the selector works out which one
this host should get.
The entry itself is always the last resort, so an entry carrying variants
stays a complete, installable entry and older LocalAI releases, which drop
this key, install it exactly as before.
items:
$ref: '#/definitions/gallery.Variant'
type: array
type: object
localai.LibrarySourcesResponse:
properties:
officialLibraries:
type: boolean
sources:
items:
$ref: '#/definitions/library.Info'
type: array
type: object
localai.ModelExportsStatus:
properties:
model_exports:
description: |-
ModelExports is false only when this instance does not see the models
path of the add-on owner. It is the same value as the model_exports key
of GET /api/features.
type: boolean
type: object
localai.ModelResponse:
properties:
config: {}
config_revision:
type: string
details:
items:
type: string
type: array
error:
type: string
filename:
type: string
message:
type: string
pending_cleanup:
type: integer
success:
type: boolean
type: object
localai.MotionSessionInfo:
properties:
frames:
type: integer
id:
type: string
model:
type: string
poses:
type: integer
profile:
type: string
time_origin:
type: string
upload_accepted:
type: integer
upload_dropped:
type: integer
type: object
localai.MotionSessionRequest:
properties:
model:
type: string
profile:
type: string
time_origin:
type: string
type: object
localai.MotionTicketRequest:
properties:
origin:
type: string
type: object
localai.TTSModelVoices:
properties:
model:
type: string
voices:
items:
$ref: '#/definitions/config.TTSVoice'
type: array
type: object
localai.TTSVoicesResponse:
properties:
data:
items:
$ref: '#/definitions/localai.TTSModelVoices'
type: array
type: object
localai.UpdateMaxReplicasPerModelRequest:
properties:
value:
description: Value is the new per-model replica cap on this node. Must be
>= 1.
type: integer
type: object
localai.UpdateVRAMBudgetRequest:
properties:
value:
description: Value is the VRAM cap ("80%" or "12GB"). Empty string clears
the cap.
type: string
type: object
localai.VoiceProfileListResponse:
properties:
data:
items:
$ref: '#/definitions/voiceprofile.Profile'
type: array
type: object
middleware.TraceBucket:
properties:
count:
type: integer
errors:
type: integer
start:
type: string
type: object
middleware.TraceSummary:
properties:
buckets:
items:
$ref: '#/definitions/middleware.TraceBucket'
type: array
errors:
type: integer
p95_ms:
type: integer
total:
type: integer
window_hours:
type: integer
type: object
model.BackendLogLine:
properties:
stream:
description: '"stdout" or "stderr"'
type: string
text:
type: string
timestamp:
type: string
type: object
modeladmin.VRAMRequest:
properties:
context_size:
type: integer
gpu_layers:
type: integer
kv_quant_bits:
type: integer
model:
type: string
type: object
modeladmin.VRAMResponse:
properties:
context_length:
type: integer
context_note:
type: string
model_max_context:
type: integer
size_bytes:
type: integer
size_display:
type: string
vram_bytes:
type: integer
vram_display:
type: string
type: object
nodes.NodeModel:
properties:
address:
description: gRPC address for this replica's backend process
type: string
backend_type:
description: e.g. "llama-cpp"; used by reconciler to replicate loads
type: string
cleanup_attempts:
type: integer
cleanup_error:
type: string
cleanup_next_retry_at:
type: string
config_revision:
type: string
created_at:
type: string
effective_options_hash:
type: string
id:
type: string
in_flight:
description: number of active requests on this replica
type: integer
last_used:
type: string
loading_by:
description: frontend ID that triggered loading
type: string
model_name:
type: string
node_id:
type: string
replica_index:
type: integer
state:
description: staging, loading, loaded, unloading, idle
type: string
updated_at:
type: string
type: object
proto.MemoryUsageData:
properties:
breakdown:
additionalProperties:
format: int64
type: integer
type: object
total:
type: integer
type: object
proto.SpeakerEncoder:
properties:
dimension:
type: integer
family:
description: embedding space of the encoder; empty when the backend cannot
tell
type: string
identity:
description: sha256 of loaded GGUF bytes
type: string
type: object
proto.StatusResponse:
properties:
memory:
$ref: '#/definitions/proto.MemoryUsageData'
speaker_encoder:
allOf:
- $ref: '#/definitions/proto.SpeakerEncoder'
description: trusted metadata from the loaded server encoder, never request
data
state:
$ref: '#/definitions/proto.StatusResponse_State'
type: object
proto.StatusResponse_State:
enum:
- 0
- 1
- 2
- -1
format: int32
type: integer
x-enum-varnames:
- StatusResponse_UNINITIALIZED
- StatusResponse_BUSY
- StatusResponse_READY
- StatusResponse_ERROR
proto.VADResponse:
properties:
segments:
items:
$ref: '#/definitions/proto.VADSegment'
type: array
type: object
proto.VADSegment:
properties:
end:
type: number
start:
type: number
type: object
recovery.BackupInfo:
properties:
addonId:
type: string
created:
type: string
digest:
type: string
files:
type: integer
id:
type: string
mode:
description: Mode and Version are the ownership mode and package version it
holds.
type: string
pinned:
description: Pinned is set while the backup is the recovery copy of an upgrade.
type: boolean
reason:
type: string
size:
type: integer
verification:
type: string
verified:
type: boolean
version:
type: string
type: object
recovery.BackupReceipt:
properties:
addonId:
type: string
created:
type: string
digest:
type: string
files:
type: integer
id:
type: string
mode:
description: Mode and Version are the ownership mode and package version it
holds.
type: string
pinned:
description: Pinned is set while the backup is the recovery copy of an upgrade.
type: boolean
reason:
type: string
size:
type: integer
verified:
type: boolean
version:
type: string
type: object
recovery.PurgeReceipt:
properties:
addonId:
type: string
at:
type: string
resources:
type: integer
scope:
$ref: '#/definitions/recovery.PurgeScope'
warnings:
items:
type: string
type: array
type: object
recovery.PurgeScope:
properties:
backups:
description: Backups are the backups of the add-on.
type: boolean
data:
description: |-
Data is the add-on's data directory and the owner's records of its
resources, grants and conversation selections.
type: boolean
recoveryCopies:
description: |-
RecoveryCopies are the data copies that restores and failed upgrades
set aside.
type: boolean
type: object
recovery.RestoreReceipt:
properties:
actor:
type: string
addonId:
type: string
at:
type: string
backupCreated:
type: string
backupId:
type: string
lostWrites:
description: |-
LostWrites counts the operations applied after the backup. Their
effects are gone from the data.
type: integer
policy:
$ref: '#/definitions/recovery.RestoreReport'
previousCopy:
description: |-
PreviousCopy names the directory that holds the data that was replaced.
It stays until an administrator purges it.
type: string
warnings:
items:
type: string
type: array
type: object
recovery.RestoreReport:
properties:
grantsDropped:
type: integer
grantsRestored:
type: integer
historyTruncated:
description: |-
HistoryTruncated says the record of lowered access may have lost
entries older than the backup, so no grant of the backup was restored.
type: boolean
proposalsCancelled:
description: |-
ProposalsCancelled and ProposalsUnknown are the proposals of the add-on
that no longer can be confirmed, and the ones whose outcome is looked up
by receipt and never applied again.
type: integer
proposalsUnknown:
type: integer
resourcesRestored:
type: integer
resourcesSkipped:
items:
type: string
type: array
revoked:
description: |-
Revoked counts grants dropped or lowered because access was taken away
after the backup.
type: integer
type: object
recovery.RetentionView:
properties:
keep:
type: integer
maxAgeSeconds:
type: integer
type: object
recovery.Status:
properties:
addonId:
type: string
backups:
items:
$ref: '#/definitions/recovery.BackupInfo'
type: array
lastRestore:
$ref: '#/definitions/recovery.RestoreReceipt'
mode:
description: 'Mode is the ownership mode of the owner: named-user or local-owner.'
type: string
operations:
description: |-
Operations lists the operation IDs whose result is recorded, so a
caller that lost an answer can see that its request ran.
items:
type: string
type: array
phase:
description: Phase is the phase of an upgrade or restore in progress.
type: string
previousCopies:
description: PreviousCopies counts the data copies a restore set aside.
type: integer
reason:
type: string
recoveryBackup:
description: RecoveryBackup names the copy to restore from.
type: string
retention:
allOf:
- $ref: '#/definitions/recovery.RetentionView'
description: Retention is the policy applied to the backups.
state:
type: string
type: object
schema.APIError:
properties:
code: {}
message:
type: string
param:
type: string
type:
type: string
type: object
schema.AnimationInput:
properties:
data:
type: string
type:
type: string
type: object
schema.AnthropicContentBlock:
properties:
content: {}
id:
type: string
input:
additionalProperties: {}
type: object
is_error:
type: boolean
name:
type: string
signature:
type: string
source:
$ref: '#/definitions/schema.AnthropicImageSource'
text:
type: string
thinking:
type: string
tool_use_id:
type: string
type:
type: string
type: object
schema.AnthropicImageSource:
properties:
data:
type: string
media_type:
type: string
type:
type: string
type: object
schema.AnthropicMessage:
properties:
content: {}
role:
type: string
type: object
schema.AnthropicRequest:
properties:
max_tokens:
type: integer
messages:
items:
$ref: '#/definitions/schema.AnthropicMessage'
type: array
metadata:
additionalProperties:
type: string
type: object
model:
type: string
stop_sequences:
items:
type: string
type: array
stream:
type: boolean
system:
type: string
temperature:
type: number
thinking:
allOf:
- $ref: '#/definitions/schema.AnthropicThinkingParam'
description: |-
Thinking gates extended-thinking output. We only surface thinking
content blocks when the client explicitly opts in, matching Anthropic's
API where thinking is off unless requested.
tool_choice: {}
tools:
items:
$ref: '#/definitions/schema.AnthropicTool'
type: array
top_k:
type: integer
top_p:
type: number
type: object
schema.AnthropicResponse:
properties:
content:
items:
$ref: '#/definitions/schema.AnthropicContentBlock'
type: array
id:
type: string
model:
type: string
role:
type: string
stop_reason:
type: string
stop_sequence:
type: string
type:
type: string
usage:
$ref: '#/definitions/schema.AnthropicUsage'
type: object
schema.AnthropicThinkingParam:
properties:
budget_tokens:
type: integer
type:
description: '"enabled" | "disabled"'
type: string
type: object
schema.AnthropicTool:
properties:
description:
type: string
input_schema:
additionalProperties: {}
type: object
name:
type: string
type: object
schema.AnthropicUsage:
properties:
input_tokens:
type: integer
output_tokens:
type: integer
type: object
schema.BackendMonitorRequest:
properties:
model:
type: string
type: object
schema.BackendResponse:
properties:
id:
type: string
status_url:
type: string
type: object
schema.Choice:
properties:
delta:
$ref: '#/definitions/schema.Message'
finish_reason:
type: string
index:
type: integer
logprobs:
$ref: '#/definitions/schema.Logprobs'
message:
$ref: '#/definitions/schema.Message'
text:
type: string
type: object
schema.CompressionMetadata:
properties:
compressed_tokens:
type: integer
compressor:
type: string
dropped_turns:
type: integer
original_tokens:
type: integer
overflow_recoveries:
type: integer
summary_tokens:
type: integer
type: object
schema.ConvTokenUsage:
properties:
completion:
type: integer
prompt:
type: integer
total:
type: integer
type: object
schema.Conversation:
properties:
addonToolIds:
items:
type: string
type: array
addonTools:
type: boolean
clientMCPServers:
items:
type: object
type: array
contextSize:
type: integer
createdAt:
type: integer
history:
items:
type: object
type: array
id:
type: string
localaiAssistant:
description: |-
LocalAIAssistant wires the chat to the in-process admin MCP server
(the LocalAI Assistant mode of the Chat page).
type: boolean
mcpMode:
type: boolean
mcpResources:
items:
type: string
type: array
mcpServers:
items:
type: string
type: array
metadata:
additionalProperties:
type: string
type: object
model:
type: string
name:
type: string
reasoningEffort:
description: |-
ReasoningEffort is the chat's reasoning_effort choice ('' = model config,
'none' also hides reasoning traces).
type: string
systemPrompt:
type: string
temperature:
type: number
tokenUsage:
$ref: '#/definitions/schema.ConvTokenUsage'
topK:
type: number
topP:
type: number
updatedAt:
type: integer
version:
description: |-
Version is assigned by the server: 1 on the first save, +1 on every
later write including the delete. Clients use a non-zero version to
tell a conversation the server has seen from a never-synced draft.
Ignored on input.
type: integer
type: object
schema.ConversationBulkRequest:
properties:
conversations:
items:
$ref: '#/definitions/schema.Conversation'
type: array
type: object
schema.ConversationBulkResponse:
properties:
count:
type: integer
skipped:
items:
type: string
type: array
status:
type: string
type: object
schema.ConversationList:
properties:
conversations:
items:
$ref: '#/definitions/schema.Conversation'
type: array
deleted:
items:
$ref: '#/definitions/schema.ConversationTombstone'
type: array
type: object
schema.ConversationTombstone:
properties:
deletedAt:
description: Unix milliseconds
type: integer
id:
type: string
version:
type: integer
type: object
schema.DecisionAnswer:
properties:
choice:
description: Choice preserves the selected string or boolean value. Swagger
2 uses a loose object placeholder for this union.
type: object
confidence:
type: number
name:
type: string
probabilities:
items:
$ref: '#/definitions/schema.DecisionProbability'
type: array
probability:
type: number
score:
type: number
type:
type: string
type: object
schema.DecisionChoice:
properties:
description:
type: string
value:
description: Value is a string or boolean choice. Swagger 2 uses a loose object
placeholder for this union.
type: object
type: object
schema.DecisionLevel:
properties:
description:
type: string
label:
type: string
type: object
schema.DecisionProbability:
properties:
label:
type: string
probability:
type: number
value:
description: Value is a string or boolean for choices, or a zero-based integer
for score levels. Swagger 2 uses a loose object placeholder for this union.
type: object
type: object
schema.DecisionQuestion:
properties:
choices:
items:
$ref: '#/definitions/schema.DecisionChoice'
type: array
instructions:
type: string
levels:
items:
$ref: '#/definitions/schema.DecisionLevel'
type: array
name:
type: string
type:
type: string
type: object
schema.DecisionUsage:
properties:
input_tokens:
type: integer
input_tokens_details:
additionalProperties:
type: integer
type: object
output_tokens:
type: integer
output_tokens_details:
additionalProperties:
type: integer
type: object
total_tokens:
type: integer
type: object
schema.DecisionsRequest:
properties:
input:
description: Input is a text string or an array of user messages. Swagger
2 uses a loose object placeholder for this union.
type: object
model:
type: string
questions:
items:
$ref: '#/definitions/schema.DecisionQuestion'
type: array
safety_identifier:
type: string
type: object
schema.DecisionsResponse:
properties:
answers:
items:
$ref: '#/definitions/schema.DecisionAnswer'
type: array
model:
type: string
usage:
$ref: '#/definitions/schema.DecisionUsage'
type: object
schema.DepthRequest:
properties:
dst:
description: optional output directory for exports (glb/colmap)
type: string
exports:
description: 'requested exports: "glb", "colmap"'
items:
type: string
type: array
image:
description: URL or base64-encoded image to analyze
type: string
include_confidence:
description: return the per-pixel confidence map (DualDPT)
type: boolean
include_depth:
description: return the per-pixel depth map
type: boolean
include_points:
description: back-project to a 3D point cloud (DualDPT)
type: boolean
include_pose:
description: return camera extrinsics/intrinsics (DualDPT)
type: boolean
include_sky:
description: return the per-pixel sky map (mono models)
type: boolean
model:
type: string
points_conf_thresh:
description: keep points with confidence >= this threshold
type: number
type: object
schema.DepthResponse:
properties:
confidence:
description: width*height row-major confidence (DualDPT)
items:
type: number
type: array
depth:
description: width*height row-major metric depth
items:
type: number
type: array
export_paths:
description: paths written for the requested exports
items:
type: string
type: array
extrinsics:
description: 12 floats, 3x4 row-major (world-to-camera)
items:
type: number
type: array
height:
type: integer
intrinsics:
description: 9 floats, 3x3 row-major
items:
type: number
type: array
is_metric:
description: depth is in metric units
type: boolean
num_points:
description: number of 3D points
type: integer
point_colors:
description: base64-encoded num_points*3 uint8 rgb
type: string
points:
description: num_points*3 xyz, world space
items:
type: number
type: array
sky:
description: width*height row-major sky map (mono)
items:
type: number
type: array
width:
type: integer
type: object
schema.Detection:
properties:
class_name:
type: string
confidence:
type: number
height:
type: number
mask:
description: base64-encoded PNG segmentation mask
type: string
width:
type: number
x:
type: number
"y":
type: number
type: object
schema.DetectionRequest:
properties:
boxes:
description: Box coordinates as [x1,y1,x2,y2,...] quads
items:
type: number
type: array
image:
description: URL or base64-encoded image to analyze
type: string
model:
type: string
points:
description: 'Point coordinates as [x,y,label,...] triples (label: 1=pos,
0=neg)'
items:
type: number
type: array
prompt:
description: Text prompt (for SAM 3 PCS mode)
type: string
threshold:
description: Detection confidence threshold
type: number
type: object
schema.DetectionResponse:
properties:
detections:
items:
$ref: '#/definitions/schema.Detection'
type: array
type: object
schema.DetokenizeRequest:
properties:
model:
type: string
tokens:
description: token IDs to convert back to text
items:
type: integer
type: array
type: object
schema.DetokenizeResponse:
properties:
content:
description: detokenized text
type: string
type: object
schema.DiarizationResult:
properties:
duration:
type: number
language:
type: string
num_speakers:
type: integer
segments:
items:
$ref: '#/definitions/schema.DiarizationSegment'
type: array
sounds:
description: |-
Sounds is present only when the request set include_sounds. An empty
list then means the model ran and heard no event; omitzero keeps a nil
list (not requested) out of the payload while an empty one stays.
items:
$ref: '#/definitions/schema.DiarizationSound'
type: array
speaker_profiles:
$ref: '#/definitions/schema.SpeakerProfiles'
speakers:
items:
$ref: '#/definitions/schema.DiarizationSpeaker'
type: array
task:
type: string
type: object
schema.DiarizationSegment:
properties:
end:
type: number
id:
type: integer
label:
type: string
name:
description: |-
Name is the registered speaker this segment was matched to, and NameScore
the cosine similarity of the match. Both are omitted when the backend did
not identify the speaker. Speaker stays the normalized SPEAKER_NN label.
type: string
name_score:
type: number
speaker:
type: string
start:
type: number
text:
type: string
type: object
schema.DiarizationSound:
properties:
confidence:
type: number
end:
type: number
label:
type: string
start:
type: number
type: object
schema.DiarizationSpeaker:
properties:
id:
type: string
label:
type: string
name:
type: string
segment_count:
type: integer
total_speech_duration:
type: number
type: object
schema.ElevenLabsSoundGenerationRequest:
properties:
bpm:
type: integer
caption:
type: string
do_sample:
type: boolean
duration_seconds:
type: number
expansion_model:
type: string
instrumental:
description: 'Simple mode: use text as description; optional instrumental
/ vocal_language'
type: boolean
keyscale:
type: string
language:
type: string
lyrics:
type: string
model_id:
type: string
params:
additionalProperties:
type: string
type: object
prompt_influence:
type: number
text:
type: string
think:
description: Advanced mode
type: boolean
timesignature:
type: string
vocal_language:
type: string
type: object
schema.ErrorResponse:
properties:
error:
$ref: '#/definitions/schema.APIError'
type: object
schema.FaceAnalysis:
properties:
age:
type: number
antispoof_score:
type: number
dominant_emotion:
type: string
dominant_gender:
type: string
dominant_race:
type: string
emotion:
additionalProperties:
format: float32
type: number
type: object
face_confidence:
type: number
gender:
additionalProperties:
format: float32
type: number
type: object
is_real:
description: Liveness fields — see FaceVerifyResponse for why these are pointers.
type: boolean
race:
additionalProperties:
format: float32
type: number
type: object
region:
$ref: '#/definitions/schema.FacialArea'
type: object
schema.FaceAnalyzeRequest:
properties:
actions:
description: subset of {"age","gender","emotion","race"}
items:
type: string
type: array
anti_spoofing:
type: boolean
img:
type: string
model:
type: string
type: object
schema.FaceAnalyzeResponse:
properties:
faces:
items:
$ref: '#/definitions/schema.FaceAnalysis'
type: array
type: object
schema.FaceEmbedRequest:
properties:
img:
type: string
model:
type: string
type: object
schema.FaceEmbedResponse:
properties:
dim:
type: integer
embedding:
items:
type: number
type: array
model:
type: string
type: object
schema.FaceForgetRequest:
properties:
id:
type: string
model:
type: string
store:
type: string
type: object
schema.FaceIdentifyMatch:
properties:
confidence:
type: number
distance:
type: number
id:
type: string
labels:
additionalProperties:
type: string
type: object
match:
description: true when distance <= threshold
type: boolean
name:
type: string
type: object
schema.FaceIdentifyRequest:
properties:
img:
type: string
model:
type: string
store:
type: string
threshold:
description: optional cutoff on distance
type: number
top_k:
type: integer
type: object
schema.FaceIdentifyResponse:
properties:
matches:
items:
$ref: '#/definitions/schema.FaceIdentifyMatch'
type: array
type: object
schema.FaceRegisterRequest:
properties:
embedding:
items:
type: number
type: array
img:
type: string
labels:
additionalProperties:
type: string
type: object
model:
type: string
name:
type: string
registered_at:
description: original enrollment time when replaying a saved embedding
type: string
store:
description: vector store model; empty = local-store default
type: string
type: object
schema.FaceRegisterResponse:
properties:
id:
type: string
name:
type: string
registered_at:
type: string
type: object
schema.FaceVerifyRequest:
properties:
anti_spoofing:
type: boolean
img1:
type: string
img2:
type: string
model:
type: string
threshold:
type: number
type: object
schema.FaceVerifyResponse:
properties:
confidence:
type: number
distance:
type: number
img1_antispoof_score:
type: number
img1_area:
$ref: '#/definitions/schema.FacialArea'
img1_is_real:
description: |-
Liveness fields are only populated when the request set
anti_spoofing=true. Pointers keep them fully absent from the
JSON response otherwise, so callers can tell "not checked"
apart from "checked and fake" (which would collapse to zero
values with plain bool+omitempty).
type: boolean
img2_antispoof_score:
type: number
img2_area:
$ref: '#/definitions/schema.FacialArea'
img2_is_real:
type: boolean
model:
type: string
processing_time_ms:
type: number
threshold:
type: number
verified:
type: boolean
type: object
schema.FacialArea:
properties:
h:
type: number
w:
type: number
x:
type: number
"y":
type: number
type: object
schema.ForecastRequest:
properties:
clip_nonnegative:
description: null = model default
type: boolean
max_context:
description: cap on history used; 0 = model default
type: integer
model:
type: string
prediction_length:
description: steps to forecast
type: integer
quantiles:
description: levels to return; default 0.1, 0.5, 0.9
items:
type: number
type: array
series:
items:
$ref: '#/definitions/schema.ForecastSeries'
type: array
symmetric_averaging:
description: null = model default
type: boolean
type: object
schema.ForecastResponse:
properties:
data:
items:
$ref: '#/definitions/schema.ForecastSeriesResult'
type: array
model:
type: string
object:
type: string
prediction_length:
type: integer
quantile_levels:
items:
type: number
type: array
type: object
schema.ForecastSeries:
properties:
id:
description: echoed back in the matching result
type: string
known_categorical:
description: 'KnownCategorical is [C][T+H]: integer category codes for the
future too.'
items:
items:
format: float64
type: number
type: array
type: array
known_covariates:
description: 'KnownCovariates is [C][T+H]: numeric covariates known for the
future too.'
items:
items:
format: float64
type: number
type: array
type: array
past_categorical:
description: 'PastCategorical is [C][T]: integer category codes for the past.'
items:
items:
format: float64
type: number
type: array
type: array
past_covariates:
description: 'PastCovariates is [C][T]: numeric covariates known only for
the past.'
items:
items:
format: float64
type: number
type: array
type: array
target:
description: '[V][T] or [T], null = missing'
items:
items:
format: float64
type: number
type: array
type: array
type: object
schema.ForecastSeriesResult:
properties:
id:
type: string
index:
description: position of the series in the request
type: integer
variates:
items:
$ref: '#/definitions/schema.ForecastVariate'
type: array
type: object
schema.ForecastVariate:
properties:
index:
type: integer
values:
description: 'Values is [Q][H]: Values[q][h] is quantile_levels[q] at step
h.'
items:
items:
format: float32
type: number
type: array
type: array
type: object
schema.FunctionCall:
properties:
arguments:
type: string
name:
type: string
type: object
schema.GalleryResponse:
properties:
estimated_size_bytes:
type: integer
estimated_size_display:
type: string
estimated_vram_bytes:
type: integer
estimated_vram_display:
type: string
status:
type: string
uuid:
type: string
type: object
schema.InputTokensDetails:
properties:
image_tokens:
type: integer
text_tokens:
type: integer
type: object
schema.Item:
properties:
b64_json:
type: string
index:
type: integer
object:
type: string
url:
description: Images
type: string
type: object
schema.JINADocumentResult:
properties:
document:
$ref: '#/definitions/schema.JINAText'
index:
type: integer
relevance_score:
type: number
type: object
schema.JINARerankRequest:
properties:
backend:
type: string
documents:
items:
type: string
type: array
model:
type: string
query:
type: string
top_n:
type: integer
type: object
schema.JINARerankResponse:
properties:
model:
type: string
results:
items:
$ref: '#/definitions/schema.JINADocumentResult'
type: array
usage:
$ref: '#/definitions/schema.JINAUsageInfo'
type: object
schema.JINAText:
properties:
text:
type: string
type: object
schema.JINAUsageInfo:
properties:
prompt_tokens:
type: integer
total_tokens:
type: integer
type: object
schema.Job:
properties:
audios:
description: List of audio URLs or base64 strings
items:
type: string
type: array
completed_at:
type: string
created_at:
type: string
error:
description: Error message if failed
type: string
files:
description: List of file URLs or base64 strings
items:
type: string
type: array
id:
description: UUID
type: string
images:
description: |-
Multimedia content (for manual execution)
Can contain URLs or base64-encoded data URIs
items:
type: string
type: array
parameters:
additionalProperties:
type: string
description: Template parameters
type: object
result:
description: Agent response
type: string
started_at:
type: string
status:
allOf:
- $ref: '#/definitions/schema.JobStatus'
description: pending, running, completed, failed, cancelled
task_id:
description: Reference to Task
type: string
traces:
description: Execution traces (reasoning, tool calls, tool results)
items:
$ref: '#/definitions/schema.JobTrace'
type: array
triggered_by:
description: '"manual", "cron", "api"'
type: string
videos:
description: List of video URLs or base64 strings
items:
type: string
type: array
webhook_error:
description: Error if webhook failed
type: string
webhook_sent:
description: Webhook delivery tracking
type: boolean
webhook_sent_at:
type: string
type: object
schema.JobExecutionRequest:
properties:
audios:
description: List of audio URLs or base64 strings
items:
type: string
type: array
files:
description: List of file URLs or base64 strings
items:
type: string
type: array
images:
description: |-
Multimedia content (optional, for manual execution)
Can contain URLs or base64-encoded data URIs
items:
type: string
type: array
parameters:
additionalProperties:
type: string
description: Optional, for templating
type: object
task_id:
description: Required
type: string
videos:
description: List of video URLs or base64 strings
items:
type: string
type: array
type: object
schema.JobExecutionResponse:
properties:
job_id:
description: unique job identifier
type: string
status:
description: initial status (pending)
type: string
url:
description: URL to poll for job status
type: string
type: object
schema.JobStatus:
enum:
- pending
- running
- completed
- failed
- cancelled
type: string
x-enum-varnames:
- JobStatusPending
- JobStatusRunning
- JobStatusCompleted
- JobStatusFailed
- JobStatusCancelled
schema.JobTrace:
properties:
arguments:
additionalProperties: {}
description: Tool arguments or result data
type: object
content:
description: The actual trace content
type: string
timestamp:
description: When this trace occurred
type: string
tool_name:
description: Tool name (for tool_call/tool_result)
type: string
type:
description: '"reasoning", "tool_call", "tool_result", "status"'
type: string
type: object
schema.KnownBackend:
properties:
auto_detect:
type: boolean
description:
type: string
installed:
description: |-
Installed is true when the backend is currently present on disk — i.e. it
appears in gallery.ListSystemBackends(systemState). Importer-registered or
curated pref-only backends default to false unless they also show up on
disk. The import form uses this to warn users that submitting an import
may trigger an automatic backend download.
type: boolean
modality:
type: string
name:
type: string
type: object
schema.LogprobContent:
properties:
bytes:
items:
type: integer
type: array
id:
type: integer
logprob:
type: number
token:
type: string
top_logprobs:
items:
$ref: '#/definitions/schema.LogprobContent'
type: array
type: object
schema.Logprobs:
properties:
content:
items:
$ref: '#/definitions/schema.LogprobContent'
type: array
type: object
schema.LogprobsValue:
properties:
enabled:
description: true if logprobs should be returned
type: boolean
type: object
schema.Message:
properties:
content:
description: The message content
function_call:
description: A result of a function call
name:
description: The message name (used for tools calls)
type: string
reasoning:
description: Reasoning content extracted from <thinking>...</thinking> tags
type: string
role:
description: The message role
type: string
tool_call_id:
type: string
tool_calls:
items:
$ref: '#/definitions/schema.ToolCall'
type: array
type: object
schema.Model3DAnimationRequest:
properties:
inputs:
additionalProperties:
$ref: '#/definitions/schema.AnimationInput'
type: object
model:
type: string
params:
additionalProperties:
type: string
type: object
response_format:
type: string
type: object
schema.Model3DRequest:
description: 3D asset generation request body. Generation is image-conditioned
properties:
background:
description: 'background handling: auto|keep|black|white'
type: string
cfg_scale:
description: classifier-free guidance scale (backend default 7.5)
type: number
image:
description: 'conditioning image: URL, base64, or data URI (required)'
type: string
model:
type: string
params:
additionalProperties:
type: string
description: backend-specific generation parameters
type: object
quality:
description: 'mesh pipeline: auto|coarse|512|1024'
type: string
response_format:
description: output format (url or b64_json)
type: string
seed:
description: random seed; <=0 picks a random seed
type: integer
step:
description: flow sampling steps (backend default 12)
type: integer
texture_steps:
description: texture flow sampling steps (backend default 12)
type: integer
type: object
schema.ModelCapabilities:
properties:
capabilities:
description: |-
Capabilities are canonical usecase strings (e.g. chat, vision, transcript,
tts, embeddings, image, video) plus the modifiers "tools" and "thinking".
items:
type: string
type: array
context_size:
description: |-
ContextSize is the effective context window in tokens the backend will
run with: the configured context_size, or the default when unset. 0 means
the value is unknown (e.g. a loose file with no config). Clients can use
this to size their context budget for auto-compaction and pruning.
type: integer
id:
type: string
input_modalities:
description: InputModalities is the subset of {text,image,audio,video} the
model accepts.
items:
type: string
type: array
object:
type: string
output_modalities:
description: OutputModalities is the subset of {text,image,audio,video} the
model produces.
items:
type: string
type: array
three_d_operations:
items:
$ref: '#/definitions/schema.ThreeDOperation'
type: array
upscale_scale:
type: integer
type: object
schema.ModelCapabilitiesResponse:
properties:
data:
items:
$ref: '#/definitions/schema.ModelCapabilities'
type: array
object:
type: string
type: object
schema.ModelLoadCancelRequest:
properties:
job_id:
type: string
type: object
schema.ModelLoadCancelResponse:
properties:
current_job_id:
type: string
job_id:
type: string
model:
type: string
retry_after:
type: integer
state:
type: string
type: object
schema.ModelLoadRequest:
properties:
model:
type: string
type: object
schema.ModelLoadResponse:
properties:
loaded:
description: |-
Loaded lists the model names actually resident in memory after the call.
For a pipeline model these are its sub-models, not the pipeline name.
items:
type: string
type: array
message:
description: Message is a short human-readable status ("model loaded", or
an error).
type: string
type: object
schema.ModelLoadingStatus:
properties:
bytes_sent:
type: integer
cancel_requested:
description: CancelRequested is true when an administrator cancelled the attempt.
type: boolean
eta_seconds:
description: |-
ETASeconds is omitted rather than guessed until enough bytes have moved
for the observed rate to mean anything. A confidently wrong ETA on a
twenty-minute wait is worse than none.
type: integer
file_index:
type: integer
job_id:
description: |-
JobID names the load attempt. A cancel must quote it: it is the
precondition that keeps a cancel from hitting a replacement attempt.
type: string
last_error:
description: LastError is the cause of a failed attempt.
type: string
lease_expires_in:
description: |-
LeaseExpiresIn is the seconds left on the owner's lease. It is negative
when the lease already ran out, which means the owner is gone.
type: integer
model:
type: string
node:
type: string
progress:
type: number
retry_after:
description: RetryAfter is the seconds until a new load may start, for a failed
attempt.
type: integer
state:
type: string
stop_deadline:
type: string
stopping:
description: |-
Stopping is true while the remote work of a failed attempt is not yet
confirmed ended. StopDeadline is when the model is released regardless.
type: boolean
total_bytes:
type: integer
total_files:
type: integer
type: object
schema.ModelsDataResponse:
properties:
data:
items:
$ref: '#/definitions/schema.OpenAIModel'
type: array
object:
type: string
type: object
schema.ModerationRequest:
properties:
input:
items:
type: string
type: array
model:
type: string
type: object
schema.ModerationResponse:
properties:
id:
type: string
model:
type: string
results:
items:
$ref: '#/definitions/schema.ModerationResult'
type: array
type: object
schema.ModerationResult:
properties:
categories:
additionalProperties:
type: boolean
type: object
category_applied_input_types:
additionalProperties:
items:
type: string
type: array
type: object
category_scores:
additionalProperties:
format: float64
type: number
type: object
flagged:
type: boolean
type: object
schema.MultimediaSourceConfig:
properties:
headers:
additionalProperties:
type: string
description: Custom headers for HTTP request (e.g., Authorization)
type: object
type:
description: '"image", "video", "audio", "file"'
type: string
url:
description: URL to fetch from
type: string
type: object
schema.NodeData:
properties:
id:
type: string
lastSeen:
type: string
name:
type: string
serviceID:
type: string
tunnelAddress:
type: string
type: object
schema.ORAnnotation:
properties:
end_index:
type: integer
start_index:
type: integer
title:
type: string
type:
description: url_citation
type: string
url:
type: string
type: object
schema.ORContentPart:
properties:
annotations:
description: REQUIRED for output_text - must always be present (use [])
items:
$ref: '#/definitions/schema.ORAnnotation'
type: array
detail:
description: low|high|auto for images
type: string
file_data:
type: string
file_url:
type: string
filename:
type: string
image_url:
type: string
logprobs:
description: REQUIRED for output_text - must always be present (use [])
items:
$ref: '#/definitions/schema.ORLogProb'
type: array
refusal:
type: string
text:
description: REQUIRED for output_text - must always be present (even if empty)
type: string
type:
description: input_text|input_image|input_file|output_text|refusal
type: string
type: object
schema.ORError:
properties:
code:
type: string
message:
type: string
param:
type: string
type:
description: invalid_request|not_found|server_error|model_error|too_many_requests
type: string
type: object
schema.ORFunctionTool:
properties:
description:
type: string
name:
type: string
parameters:
additionalProperties: {}
type: object
strict:
description: Always include in response
type: boolean
type:
type: string
type: object
schema.ORIncompleteDetails:
properties:
reason:
type: string
type: object
schema.ORInputTokensDetails:
properties:
cached_tokens:
description: Always include, even if 0
type: integer
type: object
schema.ORItemField:
properties:
arguments:
type: string
call_id:
description: Function call fields
type: string
content:
description: string or []ORContentPart for messages
encrypted_content:
description: Provider-specific encrypted content
type: string
id:
description: Present for all output items
type: string
name:
type: string
output:
description: Function call output fields
role:
description: Message fields
type: string
status:
description: in_progress|completed|incomplete
type: string
summary:
description: Reasoning fields (for type == "reasoning")
items:
$ref: '#/definitions/schema.ORContentPart'
type: array
type:
description: message|function_call|function_call_output|reasoning|item_reference
type: string
type: object
schema.ORLogProb:
properties:
bytes:
items:
type: integer
type: array
logprob:
type: number
token:
type: string
top_logprobs:
items:
$ref: '#/definitions/schema.ORTopLogProb'
type: array
type: object
schema.OROutputTokensDetails:
properties:
reasoning_tokens:
description: Always include, even if 0
type: integer
type: object
schema.ORReasoning:
properties:
effort:
type: string
summary:
type: string
type: object
schema.ORReasoningParam:
properties:
effort:
description: '"none"|"low"|"medium"|"high"|"xhigh"'
type: string
summary:
description: '"auto"|"concise"|"detailed"'
type: string
type: object
schema.ORResponseResource:
properties:
background:
type: boolean
completed_at:
description: 'Required: present as number or null'
type: integer
created_at:
type: integer
error:
allOf:
- $ref: '#/definitions/schema.ORError'
description: Always present, null if no error
frequency_penalty:
type: number
id:
type: string
incomplete_details:
allOf:
- $ref: '#/definitions/schema.ORIncompleteDetails'
description: Always present, null if complete
instructions:
type: string
max_output_tokens:
type: integer
max_tool_calls:
description: nullable
type: integer
metadata:
additionalProperties:
type: string
description: Metadata and operational flags
type: object
model:
type: string
object:
description: always "response"
type: string
output:
items:
$ref: '#/definitions/schema.ORItemField'
type: array
parallel_tool_calls:
type: boolean
presence_penalty:
type: number
previous_response_id:
type: string
prompt_cache_key:
description: nullable
type: string
reasoning:
allOf:
- $ref: '#/definitions/schema.ORReasoning'
description: nullable
safety_identifier:
description: Safety and caching
type: string
service_tier:
type: string
status:
description: in_progress|completed|failed|incomplete
type: string
store:
type: boolean
temperature:
description: Sampling parameters (always required)
type: number
text:
allOf:
- $ref: '#/definitions/schema.ORTextConfig'
description: Text format configuration
tool_choice: {}
tools:
description: Tool-related fields
items:
$ref: '#/definitions/schema.ORFunctionTool'
type: array
top_logprobs:
description: Default to 0
type: integer
top_p:
type: number
truncation:
description: Truncation and reasoning
type: string
usage:
allOf:
- $ref: '#/definitions/schema.ORUsage'
description: Usage statistics
type: object
schema.ORTextConfig:
properties:
format:
$ref: '#/definitions/schema.ORTextFormat'
type: object
schema.ORTextFormat:
properties:
type:
description: '"text" or "json_schema"'
type: string
type: object
schema.ORTopLogProb:
properties:
bytes:
items:
type: integer
type: array
logprob:
type: number
token:
type: string
type: object
schema.ORUsage:
properties:
input_tokens:
type: integer
input_tokens_details:
allOf:
- $ref: '#/definitions/schema.ORInputTokensDetails'
description: Always present
output_tokens:
type: integer
output_tokens_details:
allOf:
- $ref: '#/definitions/schema.OROutputTokensDetails'
description: Always present
total_tokens:
type: integer
type: object
schema.OpenAIModel:
properties:
id:
type: string
object:
type: string
type: object
schema.OpenAIRequest:
properties:
backend:
type: string
batch:
description: Custom parameters - not present in the OpenAI API
type: integer
clip_skip:
description: Diffusers
type: integer
echo:
type: boolean
encoding_format:
description: 'Embedding encoding format: "float" (default) or "base64" (OpenAI
Node.js SDK default)'
type: string
file:
description: whisper
type: string
files:
description: Multiple input images for img2img or inpainting
items:
type: string
type: array
frequency_penalty:
type: number
function_call:
description: might be a string or an object
functions:
description: A list of available functions to call
items:
$ref: '#/definitions/functions.Function'
type: array
grammar:
description: A grammar to constrain the LLM output
type: string
grammar_json_functions:
$ref: '#/definitions/functions.JSONFunctionStructure'
ignore_eos:
type: boolean
include_sounds:
type: boolean
include_speaker_profiles:
type: boolean
include_text:
type: boolean
input: {}
instruction:
description: Edit endpoint
type: string
language:
description: Also part of the OpenAI official spec
type: string
logit_bias:
additionalProperties:
format: float64
type: number
description: Map of token IDs to bias values (-100 to 100)
type: object
logprobs:
allOf:
- $ref: '#/definitions/schema.LogprobsValue'
description: |-
OpenAI API logprobs parameters
logprobs: boolean - if true, returns log probabilities of each output token
top_logprobs: integer 0-20 - number of most likely tokens to return at each token position
max_completion_tokens:
description: |-
MaxCompletionTokens is the modern alias for max_tokens
(OpenAI deprecated max_tokens; gpt-5 / o-series reject it).
Accepted on the wire so up-to-date clients can use the new
name; the request middleware collapses it into Maxtokens so
internal code reads exactly one field.
type: integer
max_tokens:
type: integer
messages:
description: Messages is read only by chat/completion API calls
items:
$ref: '#/definitions/schema.Message'
type: array
metadata:
additionalProperties:
type: string
type: object
min_p:
type: number
model:
type: string
model_base_name:
type: string
"n":
description: Also part of the OpenAI official spec. use it for returning multiple
results
type: integer
n_keep:
type: integer
negative_prompt:
description: |-
NegativePrompt for image generation (matches Stable Diffusion WebUI /
vLLM-Omni conventions). Combined, comma-separated, with any "|"-suffixed
negative tags in Prompt.
type: string
negative_prompt_scale:
type: number
pooling:
description: |-
Pooling is a LocalAI extension for /v1/embeddings: how the backend's
per-token vectors are reduced to a single embedding. "" or "backend"
leaves pooling to the inference backend (the pre-existing behavior);
"mean", "last" and "decayed_mean" pool Go-side from raw per-token
vectors (the backend must run with the "pooling:none" option, which
model configs get automatically when this is set).
type: string
pooling_half_life_tokens:
description: |-
PoolingHalfLifeTokens is a LocalAI extension for /v1/embeddings: the
half-life (in tokens) of the "decayed_mean" pooling scheme — a token's
weight halves every this-many positions counting back from the end of
the conversation. Defaults to 256 when unset.
type: integer
presence_penalty:
type: number
prompt:
description: Prompt is read only by completion/image API calls
quality:
description: Image (not supported by OpenAI)
type: string
reasoning_effort:
type: string
ref_images:
description: Reference images for models that support them (e.g., Flux Kontext)
items:
type: string
type: array
repeat_last_n:
type: integer
repeat_penalty:
type: number
response_format:
description: whisper/image
rope_freq_base:
type: number
rope_freq_scale:
type: number
seed:
type: integer
size:
description: image
type: string
step:
type: integer
stop: {}
stream:
type: boolean
stream_options:
allOf:
- $ref: '#/definitions/schema.StreamOptions'
description: StreamOptions opts into OpenAI streaming extensions, e.g. include_usage.
temperature:
type: number
tfz:
type: number
tokenizer:
description: RWKV (?)
type: string
tool_choice: {}
tools:
items:
$ref: '#/definitions/functions.Tool'
type: array
top_k:
type: integer
top_logprobs:
description: Number of top logprobs per token (0-20)
type: integer
top_p:
description: Common options between all the API calls, part of the OpenAI
spec
type: number
translate:
description: Only for audio transcription
type: boolean
typical_p:
type: number
required:
- file
type: object
schema.OpenAIResponse:
properties:
choices:
items:
$ref: '#/definitions/schema.Choice'
type: array
created:
type: integer
data:
items:
$ref: '#/definitions/schema.Item'
type: array
id:
type: string
metadata:
type: object
model:
type: string
object:
type: string
usage:
allOf:
- $ref: '#/definitions/schema.OpenAIUsage'
description: |-
Usage is intentionally a pointer with omitempty: per the OpenAI
chat-completion streaming spec, intermediate chunks must not carry
a `usage` field. Marshalling a value-typed usage would emit
`"usage":{"prompt_tokens":0,...}` on every chunk and break
OpenAI-SDK consumers that filter on a truthy `result.usage`
(continuedev/continue, Kilo Code, Roo Code, etc.).
type: object
schema.OpenAIUsage:
properties:
completion_tokens:
type: integer
compression_meta:
$ref: '#/definitions/schema.CompressionMetadata'
input_tokens:
description: Fields for image generation API compatibility
type: integer
input_tokens_details:
$ref: '#/definitions/schema.InputTokensDetails'
output_tokens:
type: integer
prompt_tokens:
type: integer
timing_prompt_processing:
description: Extra timing data, disabled by default as is't not a part of
OpenAI specification
type: number
timing_token_generation:
type: number
total_tokens:
type: integer
type: object
schema.OpenResponsesRequest:
properties:
allowed_tools:
description: Restrict which tools can be invoked
items:
type: string
type: array
background:
description: Run request in background
type: boolean
frequency_penalty:
description: Frequency penalty (-2.0 to 2.0)
type: number
include:
description: What to include in response
items:
type: string
type: array
input:
description: string or []ORItemParam
instructions:
type: string
logit_bias:
additionalProperties:
format: float64
type: number
description: OpenAI-compatible extensions (not in Open Responses spec)
type: object
max_output_tokens:
type: integer
max_tool_calls:
description: Maximum number of tool calls
type: integer
metadata:
additionalProperties:
type: string
type: object
model:
type: string
parallel_tool_calls:
description: Allow parallel tool calls
type: boolean
presence_penalty:
description: Presence penalty (-2.0 to 2.0)
type: number
previous_response_id:
type: string
reasoning:
$ref: '#/definitions/schema.ORReasoningParam'
service_tier:
description: '"auto"|"default"|priority hint'
type: string
store:
description: Whether to store the response
type: boolean
stream:
type: boolean
temperature:
type: number
text_format:
description: Additional parameters from spec
tool_choice:
description: '"auto"|"required"|"none"|{type:"function",name:"..."}'
tools:
items:
$ref: '#/definitions/schema.ORFunctionTool'
type: array
top_logprobs:
description: Number of top logprobs to return
type: integer
top_p:
type: number
truncation:
description: '"auto"|"disabled"'
type: string
type: object
schema.P2PNodesResponse:
properties:
federated_nodes:
items:
$ref: '#/definitions/schema.NodeData'
type: array
llama_cpp_nodes:
items:
$ref: '#/definitions/schema.NodeData'
type: array
mlx_nodes:
items:
$ref: '#/definitions/schema.NodeData'
type: array
type: object
schema.PIIAnalyzeRequest:
properties:
detectors:
description: |-
Detectors names the detector models to run (NER and/or pattern). Takes
precedence over Model.
items:
type: string
type: array
model:
description: |-
Model is a consuming model whose effective PII policy (own
pii.detectors, else the instance default detectors; PII must be
enabled) is used when Detectors is empty.
type: string
reveal:
description: |-
Reveal includes the per-entity hash_prefix in the response. Honoured
only for admin callers; ignored otherwise. The raw matched value is
never returned regardless.
type: boolean
text:
description: |-
Text is the string to scan. Bounded only by the server's global HTTP
body limit.
type: string
type: object
schema.PIIAnalyzeResponse:
properties:
blocked:
type: boolean
correlation_id:
type: string
entities:
items:
$ref: '#/definitions/schema.PIIEntity'
type: array
type: object
schema.PIIEntity:
properties:
action:
type: string
end:
type: integer
entity_type:
type: string
hash_prefix:
type: string
score:
type: number
source:
type: string
start:
type: integer
type: object
schema.PIIRedactResponse:
properties:
blocked:
type: boolean
correlation_id:
type: string
entities:
items:
$ref: '#/definitions/schema.PIIEntity'
type: array
masked:
type: boolean
redacted_text:
type: string
type: object
schema.RouterCorpusAddRequest:
properties:
entries:
items:
$ref: '#/definitions/schema.RouterCorpusEntry'
type: array
type: object
schema.RouterCorpusAddResponse:
properties:
added:
description: Added is how many entries were embedded, persisted, and indexed.
type: integer
label_counts:
additionalProperties:
type: integer
description: LabelCounts is the per-label exemplar count after the call.
type: object
router:
type: string
skipped:
description: |-
Skipped counts entries whose text was already in the corpus —
duplicates are rejected rather than double-weighted.
type: integer
total:
description: Total is the corpus size after the call.
type: integer
type: object
schema.RouterCorpusClearResponse:
properties:
cleared:
type: integer
router:
type: string
type: object
schema.RouterCorpusEntry:
properties:
labels:
items:
type: string
type: array
text:
type: string
type: object
schema.RouterCorpusStatsResponse:
properties:
embedding_model:
type: string
embedding_models:
description: |-
EmbeddingModels lists the embedder fingerprints present in the
persisted corpus; more than one means part of the corpus is
pending re-embedding on the next load.
items:
type: string
type: array
label_counts:
additionalProperties:
type: integer
type: object
router:
type: string
store_name:
type: string
total:
type: integer
type: object
schema.RouterDecideNeighbor:
properties:
id:
type: string
labels:
items:
type: string
type: array
similarity:
type: number
type: object
schema.RouterDecideRequest:
properties:
input:
description: |-
Input is the user-visible prompt text to classify. Required.
Schema-shape extraction (chat-message concatenation, etc.) is
the caller's responsibility — matches the Probe contract used
by the in-band middleware.
type: string
router:
description: |-
Router is the name of the router model (a ModelConfig with a
`router:` block). Required.
type: string
type: object
schema.RouterDecideResponse:
properties:
cache_similarity:
description: |-
CacheSimilarity carries the cosine similarity of the cache hit
(0 when not cached).
type: number
cached:
description: |-
Cached is true when the decision came from the L2 embedding
cache rather than a fresh classifier run.
type: boolean
candidate:
description: |-
Candidate is the model that would be routed to. Empty when no
candidate covers Labels AND no fallback is configured.
type: string
classifier:
description: |-
Classifier is the classifier name that produced the decision
(e.g. "score").
type: string
fallback:
description: |-
Fallback is true when Candidate is the router's configured
fallback because no candidate covered Labels. Lets callers
distinguish "matched" from "fell back" without comparing names.
type: boolean
labels:
description: Labels is the set of active policy labels.
items:
type: string
type: array
latency_ms:
description: LatencyMs is the classifier's wall-clock cost.
type: integer
nearest_similarity:
description: |-
NearestSimilarity is the cosine similarity of the closest KNN
corpus entry — populated by the knn classifier even when the
decision fell back because the probe was out of corpus range.
0 for other classifiers.
type: number
neighbors:
description: |-
Neighbors lists the corpus entries the knn classifier retrieved,
by descending similarity, including ones below the similarity
gate. Empty for other classifiers.
items:
$ref: '#/definitions/schema.RouterDecideNeighbor'
type: array
router:
description: Router echoes the requested router model.
type: string
score:
description: |-
Score is the top label's softmax probability (the
classifier-side confidence signal).
type: number
type: object
schema.SlotCacheRequest:
properties:
id:
description: 'restore only: an ID issued by a save for this model'
type: string
model:
type: string
slot:
description: slot id, 0 is the first slot
type: integer
type: object
schema.SlotCacheResponse:
properties:
action:
description: '"save" or "restore"'
type: string
duration_ms:
description: time the backend spent
type: number
id:
description: issued by the save, sent back to restore
type: string
message:
description: for example the IDs a save pruned
type: string
model:
type: string
n_bytes:
description: bytes written or read
type: integer
n_tokens:
description: tokens saved or restored
type: integer
slot:
type: integer
type: object
schema.SoundClassification:
properties:
index:
type: integer
label:
type: string
score:
type: number
type: object
schema.SoundClassificationResult:
properties:
detections:
items:
$ref: '#/definitions/schema.SoundClassification'
type: array
model:
type: string
type: object
schema.SpeakerEncoder:
properties:
dimension:
type: integer
family:
description: |-
Family is the embedding space of the encoder. The server fills it from the
loaded encoder; exported profiles do not carry it and it is not matched.
type: string
identity:
type: string
type: object
schema.SpeakerProfile:
properties:
clean_duration:
type: number
embedding:
items:
type: number
type: array
intervals:
items:
$ref: '#/definitions/schema.SpeakerProfileInterval'
type: array
speaker:
type: integer
unavailable_reason:
type: string
type: object
schema.SpeakerProfileInterval:
properties:
end:
type: number
start:
type: number
type: object
schema.SpeakerProfiles:
properties:
encoder:
$ref: '#/definitions/schema.SpeakerEncoder'
speakers:
items:
$ref: '#/definitions/schema.SpeakerProfile'
type: array
version:
type: integer
type: object
schema.StreamOptions:
properties:
include_usage:
type: boolean
type: object
schema.SysInfoModel:
properties:
backend:
description: |-
Backend is the engine serving this model. The loader knows only the ID,
so it is resolved from the model's config; empty when the model was
loaded without one (a loose file, or a config since removed).
type: string
id:
type: string
process:
allOf:
- $ref: '#/definitions/schema.SysInfoProcess'
description: |-
Process is the backend process serving the model on this host. Absent
when the model has no local process (a distributed worker holds it) or
the process could not be read.
size_vram:
description: |-
SizeVRAM is DRM-accounted resident device memory in bytes. Nil means
the backend process tree has no complete supported reading.
type: integer
type: object
schema.SysInfoProcess:
properties:
cpu_percent:
description: |-
CPUPercent is the share of the whole host's CPU used since the previous
reading, 0-100. Absent on the first reading of a process.
type: number
memory_percent:
type: number
pid:
type: integer
rss_bytes:
description: |-
RSSBytes is resident host memory. Weights offloaded to a GPU are not
in it.
type: integer
started_at:
type: string
type: object
schema.SystemInformationResponse:
properties:
backends:
description: available backend engines
items:
type: string
type: array
loaded_models:
description: currently loaded models
items:
$ref: '#/definitions/schema.SysInfoModel'
type: array
type: object
schema.SystemOneAnswer:
properties:
choice:
type: string
confidence:
type: number
entities:
items:
$ref: '#/definitions/schema.SystemOneEntity'
type: array
legend:
additionalProperties:
type: string
type: object
noul:
type: number
probabilities:
additionalProperties:
format: float64
type: number
type: object
score:
type: number
type:
type: string
type: object
schema.SystemOneEntity:
properties:
confidence:
type: number
end:
type: integer
start:
type: integer
text:
type: string
type: object
schema.SystemOnePermuteRequest:
properties:
n_perm:
type: integer
question:
type: string
request:
$ref: '#/definitions/schema.SystemOneRequest'
seed:
type: integer
type: object
schema.SystemOnePermuteResponse:
properties:
argmax_stable:
type: boolean
runs:
items:
$ref: '#/definitions/schema.SystemOnePermuteRun'
type: array
spread:
additionalProperties:
format: float64
type: number
type: object
type: object
schema.SystemOnePermuteRun:
properties:
choice:
type: string
latency_ms:
type: number
order:
items:
type: string
type: array
probabilities:
additionalProperties:
format: float64
type: number
type: object
type: object
schema.SystemOneRequest:
type: object
schema.SystemOneResponse:
properties:
answers:
additionalProperties:
$ref: '#/definitions/schema.SystemOneAnswer'
type: object
latency_ms:
type: number
model:
type: string
usage:
$ref: '#/definitions/schema.SystemOneUsage'
type: object
schema.SystemOneUsage:
properties:
input_tokens:
type: integer
output_tokens:
type: integer
type: object
schema.TTSRequest:
description: TTS request body
properties:
backend:
description: backend engine override
type: string
input:
description: text input
type: string
instructions:
description: |-
Instructions is a free-form, per-request style/voice description. It maps to
the OpenAI `instructions` field and is forwarded to the backend so expressive
TTS models (e.g. Qwen3-TTS CustomVoice/VoiceDesign) can vary tone or designed
voice per request instead of only via the static YAML option.
type: string
language:
description: (optional) language to use with TTS model
type: string
model:
type: string
params:
additionalProperties:
type: string
description: |-
Params carries optional, backend-specific per-request generation parameters
(LocalAI extension, e.g. Chatterbox exaggeration/cfg_weight/temperature).
type: object
response_format:
description: (optional) output format
type: string
sample_rate:
description: (optional) desired output sample rate
type: integer
speed:
description: |-
Speed is the OpenAI `speed` field (0.25-4.0). It is a pointer so an
explicit `"speed": 0` (invalid, rejected with 400) is distinguishable
from an omitted field (left at the backend default). It is normalised
into Params["speed"] so it reaches the backend over the same channel as
the other per-request generation parameters.
type: number
stream:
description: (optional) enable streaming TTS
type: boolean
voice:
description: voice audio file or speaker id
type: string
type: object
schema.Task:
properties:
created_at:
type: string
cron:
description: Optional cron expression
type: string
cron_parameters:
additionalProperties:
type: string
description: Parameters to use when executing cron jobs
type: object
description:
description: Optional description
type: string
enabled:
description: Can be disabled without deletion
type: boolean
id:
description: UUID
type: string
model:
description: Model name (must have MCP config)
type: string
multimedia_sources:
description: |-
Multimedia sources (for cron jobs)
URLs to fetch multimedia content from when cron job executes
Each source can have custom headers for authentication/authorization
items:
$ref: '#/definitions/schema.MultimediaSourceConfig'
type: array
name:
description: User-friendly name
type: string
prompt:
description: Template prompt (supports Go template .param syntax)
type: string
updated_at:
type: string
webhooks:
description: |-
Webhook configuration (for notifications).
Supports multiple webhook endpoints.
Webhooks can handle both success and failure cases using template variables:
.Job (Job object), .Task (Task object), .Result (if successful),
.Error (if failed), .Status (job status string).
items:
$ref: '#/definitions/schema.WebhookConfig'
type: array
type: object
schema.ThreeDInput:
properties:
label:
type: string
max_bytes:
type: integer
name:
type: string
required:
type: boolean
type:
type: string
type: object
schema.ThreeDOperation:
properties:
endpoint:
type: string
id:
type: string
inputs:
items:
$ref: '#/definitions/schema.ThreeDInput'
type: array
label:
type: string
output:
type: string
parameters:
items:
$ref: '#/definitions/schema.ThreeDParameter'
type: array
type: object
schema.ThreeDParameter:
properties:
advanced:
type: boolean
default:
type: string
label:
type: string
max:
type: number
min:
type: number
name:
type: string
options:
items:
type: string
type: array
type:
type: string
type: object
schema.TokenizeRequest:
properties:
content:
description: text to tokenize
type: string
model:
type: string
type: object
schema.TokenizeResponse:
properties:
tokens:
description: token IDs
items:
type: integer
type: array
type: object
schema.ToolCall:
properties:
function:
$ref: '#/definitions/schema.FunctionCall'
id:
type: string
index:
type: integer
type:
type: string
type: object
schema.VADRequest:
description: VAD request body
properties:
audio:
description: raw audio samples as float32 PCM
items:
type: number
type: array
model:
type: string
type: object
schema.VideoReference:
properties:
audio:
description: optional audio paired with this video
type: string
fps:
description: frame rate of the source frames; 0 means the backend default
type: integer
frames:
description: 'ordered frame images: URL, base64 or data URI'
items:
type: string
type: array
type: object
schema.VideoRequest:
properties:
audio:
description: URL or base64 audio for audio-conditioned generation
type: string
cfg_scale:
description: classifier-free guidance scale
type: number
end_image:
description: URL or base64 of the last frame
type: string
fps:
description: frames per second
type: integer
height:
description: output height in pixels
type: integer
input_reference:
description: reference image or video URL
type: string
model:
type: string
negative_prompt:
description: things to avoid in the output
type: string
num_frames:
description: total number of frames to generate
type: integer
params:
additionalProperties:
type: string
description: backend-specific generation parameters
type: object
prompt:
description: text description of the video to generate
type: string
ref_audios:
description: reference audio clips (WAV); exclusive with start_image/end_image
items:
type: string
type: array
ref_images:
description: reference images (URL, base64 or data URI); exclusive with start_image/end_image
items:
type: string
type: array
ref_videos:
description: reference videos as frame lists; exclusive with start_image/end_image
items:
$ref: '#/definitions/schema.VideoReference'
type: array
response_format:
description: output format (url or b64_json)
type: string
seconds:
description: duration in seconds (alternative to num_frames)
type: string
seed:
description: random seed for reproducibility
type: integer
size:
description: WxH shorthand (e.g. "512x512")
type: string
start_image:
description: URL or base64 of the first frame
type: string
step:
description: number of diffusion steps
type: integer
width:
description: output width in pixels
type: integer
type: object
schema.VoiceAnalysis:
properties:
age:
type: number
dominant_emotion:
type: string
dominant_gender:
type: string
emotion:
additionalProperties:
format: float32
type: number
type: object
end:
type: number
gender:
additionalProperties:
format: float32
type: number
type: object
start:
type: number
type: object
schema.VoiceAnalyzeRequest:
properties:
actions:
description: subset of {"age","gender","emotion"}
items:
type: string
type: array
audio:
type: string
model:
type: string
type: object
schema.VoiceAnalyzeResponse:
properties:
segments:
items:
$ref: '#/definitions/schema.VoiceAnalysis'
type: array
type: object
schema.VoiceEmbedRequest:
properties:
audio:
type: string
model:
type: string
type: object
schema.VoiceEmbedResponse:
properties:
dim:
type: integer
embedding:
items:
type: number
type: array
model:
type: string
type: object
schema.VoiceForgetRequest:
properties:
id:
type: string
model:
type: string
store:
type: string
type: object
schema.VoiceIdentifyMatch:
properties:
confidence:
type: number
distance:
type: number
id:
type: string
labels:
additionalProperties:
type: string
type: object
match:
type: boolean
name:
type: string
type: object
schema.VoiceIdentifyRequest:
properties:
audio:
type: string
model:
type: string
store:
type: string
threshold:
type: number
top_k:
type: integer
type: object
schema.VoiceIdentifyResponse:
properties:
matches:
items:
$ref: '#/definitions/schema.VoiceIdentifyMatch'
type: array
type: object
schema.VoiceRegisterRequest:
properties:
audio:
type: string
labels:
additionalProperties:
type: string
type: object
model:
type: string
name:
type: string
speaker_profiles:
$ref: '#/definitions/schema.SpeakerProfiles'
speaker_slot:
type: integer
store:
type: string
type: object
schema.VoiceRegisterResponse:
properties:
id:
type: string
name:
type: string
registered_at:
type: string
type: object
schema.VoiceVerifyRequest:
properties:
anti_spoofing:
type: boolean
audio1:
type: string
audio2:
type: string
model:
type: string
threshold:
type: number
type: object
schema.VoiceVerifyResponse:
properties:
confidence:
type: number
distance:
type: number
model:
type: string
processing_time_ms:
type: number
threshold:
type: number
verified:
type: boolean
type: object
schema.WebhookConfig:
properties:
headers:
additionalProperties:
type: string
description: Custom headers (e.g., Authorization)
type: object
method:
description: 'HTTP method (POST, PUT, PATCH) - default: POST'
type: string
payload_template:
description: Optional template for payload
type: string
url:
description: Webhook endpoint URL
type: string
type: object
updates.State:
enum:
- unknown
- up-to-date
- update-available
- incompatible
- check-failed
- integrity-error
type: string
x-enum-varnames:
- Unknown
- UpToDate
- UpdateAvailable
- Incompatible
- CheckFailed
- IntegrityError
updates.Status:
properties:
addonId:
example: notes
type: string
available:
description: Available is true only for update-available.
type: boolean
candidateDigest:
type: string
candidateVersion:
example: 1.1.0
type: string
channel:
example: development
type: string
checkedAt:
description: |-
CheckedAt is when the status was computed. LastSuccess is when the
library was last read successfully: a failed check keeps it, so the
page can say how old the knowledge is.
type: string
error:
description: Error is the redacted class of a failed check.
example: refresh-failed
type: string
generation:
description: Generation is the installed generation the status describes.
example: 1
type: integer
installedDigest:
type: string
installedVersion:
example: 1.0.0
type: string
lastSuccess:
type: string
reasons:
description: |-
Reasons are the compatibility reasons of an incompatible or
integrity-error status.
items:
type: string
type: array
selection:
example: 1.0.0
type: string
sourceId:
description: |-
SourceID, Channel and Selection are the library, channel and
selection the add-on was installed from. They never change by themselves.
example: official
type: string
stale:
description: |-
Stale is true when the library data or the cached answer is older than
the time to live.
type: boolean
state:
allOf:
- $ref: '#/definitions/updates.State'
enum:
- unknown
- up-to-date
- update-available
- incompatible
- check-failed
- integrity-error
example: update-available
throttled:
description: |-
Throttled is true when an explicit refresh was not performed because
one ran moments ago. The status is then the last one.
type: boolean
type: object
voiceprofile.AudioMetadata:
properties:
bit_depth:
type: integer
channels:
type: integer
duration_ms:
type: integer
mime_type:
type: string
sample_rate:
type: integer
size_bytes:
type: integer
type: object
voiceprofile.Profile:
properties:
audio:
$ref: '#/definitions/voiceprofile.AudioMetadata'
consent_confirmed_at:
type: string
created_at:
type: string
description:
type: string
id:
type: string
language:
type: string
name:
type: string
references:
items:
$ref: '#/definitions/voiceprofile.ReferenceMetadata'
type: array
transcript:
type: string
updated_at:
type: string
voice:
type: string
type: object
voiceprofile.ReferenceMetadata:
properties:
audio:
$ref: '#/definitions/voiceprofile.AudioMetadata'
transcript:
type: string
type: object
info:
contact:
name: LocalAI
url: https://localai.io
description: The LocalAI Rest API.
license:
name: MIT
url: https://raw.githubusercontent.com/mudler/LocalAI/master/LICENSE
title: LocalAI API
version: 2.0.0
paths:
/3d/animate:
post:
parameters:
- description: Named conditioning inputs and model-specific parameters
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.Model3DAnimationRequest'
responses:
"200":
description: OK
schema:
$ref: '#/definitions/schema.OpenAIResponse'
summary: Creates a 3D animation (binary glTF / GLB).
tags:
- 3d
/3d/generations:
post:
parameters:
- description: query params
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.Model3DRequest'
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.OpenAIResponse'
summary: Creates a 3D asset (binary glTF / GLB) from a conditioning image.
tags:
- 3d
/3d/remesh:
post:
consumes:
- multipart/form-data
parameters:
- description: 3D model name
in: formData
name: model
required: true
type: string
- description: Source GLB
in: formData
name: mesh
required: true
type: file
- description: Detail size as percent of the source bounding-box diagonal (0.35–2.5;
default 0.5)
in: formData
name: detail
type: number
produces:
- model/gltf-binary
responses:
"200":
description: Remeshed GLB
schema:
type: file
summary: Applies watertight print remeshing to an existing 3D asset.
tags:
- 3d
/api/addons/{id}/assets/{digest}/{path}:
get:
description: 'Streams one file the addon manifest declares as UI code (the entry
module or a style sheet) from the verified package on the owner, relayed through
the receiving frontend. The digest in the path is the sha256 of the installed
package, in lower-case hex, as listed in the ui entry of the apps list. The
file is served only while the addon is installed and enabled and the digest
is the current one; a file the manifest does not declare, a traversal, a directory,
another addon, an older package, a disabled or uninstalled addon and a missing
feature all give a denial without any file content, and a denial is never
cached. The response is text/javascript or text/css with X-Content-Type-Options
nosniff and Cache-Control private, max-age=31536000, immutable: the URL changes
with the package, so the file never changes under it. The caller is authenticated
by an API key header or by the same-origin browser session; a credential in
the URL is never accepted. The addon process is never asked.'
parameters:
- description: Addon ID
in: path
name: id
required: true
type: string
- description: Package digest, 64 lower-case hex characters
in: path
name: digest
required: true
type: string
- description: Declared package file, for example ui.js
in: path
name: path
required: true
type: string
produces:
- text/javascript
- text/css
responses:
"200":
description: File bytes
headers:
Cache-Control:
description: private, max-age=31536000, immutable
type: string
X-Content-Type-Options:
description: nosniff
type: string
schema:
type: string
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Feature denied, or the file, addon or package digest is not
currently served
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Addons or the owner are unavailable
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Read an immutable file of an addon UI package
tags:
- Addons
/api/addons/{id}/purge:
post:
consumes:
- application/json
description: 'Administrators only, from their own browser session, with the
add-on ID typed as confirm. Removes retained data the scope names: the add-on''s
data and the owner''s records of its resources and shares (data), its backups
(backups) and the data copies that restores and failed upgrades set aside
(recoveryCopies). The add-on must be uninstalled or disabled. It is not the
deletion of a database and not an uninstall; those never remove retained data.
The purge is journaled and finished after a crash, and it touches no other
add-on. No MCP tool maps to this route.'
parameters:
- description: Add-on ID
in: path
name: id
required: true
type: string
- description: Operation, scope and confirmation
in: body
name: request
required: true
schema:
$ref: '#/definitions/addons.RecoveryPurgeRequest'
produces:
- application/json
responses:
"200":
description: What was purged, with warnings
schema:
$ref: '#/definitions/recovery.PurgeReceipt'
"400":
description: Malformed request, empty scope or type confirmation_mismatch
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Feature, administration or browser session denied
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"409":
description: Type addon_running, operation_conflict or busy
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Unavailable, or outcome_unknown (with operationId)
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Purge the retained data of an add-on (administrators, browser session)
tags:
- Addons
/api/addons/{id}/recovery:
get:
description: Administrators only. Returns the recovery state of the add-on's
data (ready, upgrading, restoring, needs-recovery or purging) with its reason,
the backups newest first with their size, creation time, reason (manual, upgrade
or restore), the ownership mode and package version they hold and the last
recorded verification result (verified, failed or unverified), the backup
that is the recovery copy, the receipt and warnings of the last restore, the
retention policy, the number of data copies a restore set aside and the operation
IDs whose result is recorded. Read-only. No MCP tool maps to this route.
parameters:
- description: Add-on ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: Recovery state
schema:
$ref: '#/definitions/recovery.Status'
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Feature or administration denied
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Addons or the owner are unavailable
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Read the data recovery state and the backups of an add-on (administrators)
tags:
- Addons
/api/addons/{id}/recovery/backup:
post:
consumes:
- application/json
description: Administrators only, from their own browser session (same-origin
fetch, X-LocalAI-Confirm equal to the operationId). Blocks new admission for
the add-on's resources, invalidates its pending proposals, drains admitted
work, stops the add-on, makes a consistent copy of its data (every SQLite
file with VACUUM INTO, so the write-ahead log is part of it) together with
the owner's access state, verifies the copy, publishes it atomically with
restricted permissions and starts the add-on again if it was meant to run.
A backup that cannot be completed leaves nothing behind. Repeating the operationId
returns the same backup. 503 insufficient_storage means the free space did
not fit the backup and nothing was changed. No MCP tool maps to this route.
parameters:
- description: Add-on ID
in: path
name: id
required: true
type: string
- description: Operation
in: body
name: request
required: true
schema:
$ref: '#/definitions/addons.RecoveryBackupRequest'
produces:
- application/json
responses:
"200":
description: The verified backup
schema:
$ref: '#/definitions/recovery.BackupReceipt'
"400":
description: Malformed request
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Feature, administration or browser session denied
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"404":
description: Type not_installed
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"409":
description: Type busy
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Unavailable, insufficient_storage, or outcome_unknown (with
operationId)
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Back up the data of an add-on (administrators, browser session)
tags:
- Addons
/api/addons/{id}/recovery/delete-backup:
post:
consumes:
- application/json
description: Administrators only, from their own browser session. The only verified
copy and the recovery copy of an upgrade are never removed this way (409 sole_recovery_copy);
a purge with explicit scope removes them. No MCP tool maps to this route.
parameters:
- description: Add-on ID
in: path
name: id
required: true
type: string
- description: Operation and backup
in: body
name: request
required: true
schema:
$ref: '#/definitions/addons.RecoveryDeleteBackupRequest'
produces:
- application/json
responses:
"200":
description: The deleted backup
schema:
$ref: '#/definitions/addons.RecoveryDeleted'
"400":
description: Malformed request
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Feature, administration or browser session denied
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"404":
description: Type backup_not_found
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"409":
description: Type sole_recovery_copy or busy
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Unavailable, or outcome_unknown (with operationId)
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Delete one backup of an add-on (administrators, browser session)
tags:
- Addons
/api/addons/{id}/recovery/prune:
post:
consumes:
- application/json
description: Administrators only, from their own browser session. Removes the
backups the configured count and age policy no longer keeps. The newest verified
backup and the recovery copy of an upgrade stay, whatever their age. No MCP
tool maps to this route.
parameters:
- description: Add-on ID
in: path
name: id
required: true
type: string
- description: Operation
in: body
name: request
required: true
schema:
$ref: '#/definitions/addons.RecoveryPruneRequest'
produces:
- application/json
responses:
"200":
description: The removed backups
schema:
$ref: '#/definitions/addons.RecoveryPruned'
"400":
description: Malformed request
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Feature, administration or browser session denied
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"409":
description: Type busy
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Unavailable, or outcome_unknown (with operationId)
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Apply the backup retention policy now (administrators, browser session)
tags:
- Addons
/api/addons/{id}/recovery/restore:
post:
consumes:
- application/json
description: 'Administrators only, from their own browser session, with the
add-on ID typed as confirm. The add-on must not be running. The backup is
verified before anything changes, its files are staged and swapped in atomically,
and the data they replace stays as a recovery copy until it is purged. Access
is not restored as it was: every grant is checked again against the current
accounts and the lowerings of access recorded since the backup, so nobody
gets back access that was taken away; pending proposals are cancelled and
operations with an unknown outcome are looked up by receipt and never applied
again. The answer carries warnings: the time the data goes back to, the number
of changes made after it that are lost, and the shares that were not restored.
A backup made in local-owner mode needs mapping {"local-owner": "<account
id>"}; a backup of named-user data is refused in local-owner mode. Repeating
the operationId returns the same receipt and does not restore again. No MCP
tool maps to this route. The backup must belong to the add-on in the path;
a backup of another add-on is refused with type invalid_request and nothing
is touched.'
parameters:
- description: Add-on ID
in: path
name: id
required: true
type: string
- description: Operation, backup, mapping and confirmation
in: body
name: request
required: true
schema:
$ref: '#/definitions/addons.RecoveryRestoreRequest'
produces:
- application/json
responses:
"200":
description: What was restored, with warnings
schema:
$ref: '#/definitions/recovery.RestoreReceipt'
"400":
description: Malformed request, type confirmation_mismatch or mapping_invalid
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Feature, administration or browser session denied
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"404":
description: Type backup_not_found
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"409":
description: Type addon_running, backup_corrupt, incompatible_format, identity_changed,
mapping_required, downgrade_unsupported, operation_conflict or busy
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Unavailable, or outcome_unknown (with operationId)
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Restore a backup of an add-on (administrators, browser session)
tags:
- Addons
/api/addons/{id}/recovery/verify:
post:
consumes:
- application/json
description: Administrators only, from their own browser session. Reads every
file of the backup against its manifest digests and runs the SQLite integrity
check, and records the result shown in the list. A failed backup stays in
place; removing it is a separate explicit action. No MCP tool maps to this
route.
parameters:
- description: Add-on ID
in: path
name: id
required: true
type: string
- description: Operation and backup
in: body
name: request
required: true
schema:
$ref: '#/definitions/addons.RecoveryVerifyRequest'
produces:
- application/json
responses:
"200":
description: The verified backup
schema:
$ref: '#/definitions/recovery.BackupReceipt'
"400":
description: Malformed request
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Feature, administration or browser session denied
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"404":
description: Type backup_not_found
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"409":
description: Type backup_corrupt
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Unavailable, or outcome_unknown (with operationId)
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Verify a backup of an add-on (administrators, browser session)
tags:
- Addons
/api/addons/{id}/update:
get:
description: 'Returns the owner''s update check for an installed add-on, for
every authenticated caller who holds the addons feature and may see the add-on
(an administrator any installed add-on, others only an enabled one; anything
else is the same 403). The status is computed by the owner from the library
the add-on was installed from and never from the browser: state is unknown,
up-to-date, update-available, incompatible (with reasons: platform, host-version,
api-version, protocol-version, sdk-version or data-format), check-failed (with
a redacted error class and the time the library was last read) or integrity-error.
A failed check is never up-to-date. A moving channel (development, a branch,
latest) compares resolved digests, so a changed digest with the same version
label is an update; an immutable version selects only a greater compatible
version of the same major. The library and channel never change by themselves.
The route never uses the network and never applies anything. Callers who are
not administrators get the state, versions and times only, without library,
channel or digests. No MCP tool maps to this route.'
parameters:
- description: Add-on ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: Update status
schema:
$ref: '#/definitions/updates.Status'
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Feature denied, or the add-on is unknown or hidden
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Addons or the owner are unavailable
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Read the update status of an addon
tags:
- Addons
/api/addons/{id}/update/check:
post:
consumes:
- application/json
description: 'Administrators only, from their own browser session (same-origin
fetch, X-LocalAI-Confirm equal to the operationId). The owner fetches the
library the add-on was installed from again, through the credential reference
the library is configured with, and answers with the new update status. It
is rate limited per add-on and per library: within the interval the last status
is returned with throttled true. It applies nothing; an upgrade is a separate
explicit request. No MCP tool maps to this route.'
parameters:
- description: Add-on ID
in: path
name: id
required: true
type: string
- description: Operation
in: body
name: request
required: true
schema:
$ref: '#/definitions/addons.UpdateCheckRequest'
produces:
- application/json
responses:
"200":
description: Update status
schema:
$ref: '#/definitions/updates.Status'
"400":
description: Malformed request
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Feature, administration or browser session denied
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Addons or the owner are unavailable
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Check an addon for updates now (administrators, browser session)
tags:
- Addons
/api/addons/{id}/upgrade:
post:
consumes:
- application/json
description: 'Administrators only, from their own browser session (same-origin
fetch, X-LocalAI-Confirm equal to the operationId). The only action that applies
an update. It carries the digest of the installed package the caller saw (expectedDigest)
and the digest of the candidate the check resolved (candidateDigest). The
owner re-resolves the library the add-on came from and refuses, before it
records anything, an installed package that is not the expected one (409 stale_installed),
a candidate that is not the one it resolves now (409 candidate_changed), an
incompatible candidate (409 incompatible), a rewritten immutable version (409
integrity_error) and the same transition under another operation ID (409 upgrade_conflict).
It never changes the library or the channel. The upgrade then follows the
lifecycle of an add-on: the candidate is staged and verified, the data is
backed up and migrated when the add-on has any, and the new generation is
published only when it starts. A failure or cancellation keeps the last good
generation or leaves an explicit recovery state; the previous installation
is never deleted. Repeating the operationId returns the recorded result and
never runs again; after outcome_unknown read operation-status with the same
operationId. No MCP tool maps to this route.'
parameters:
- description: Add-on ID
in: path
name: id
required: true
type: string
- description: Operation and the pinned digests
in: body
name: request
required: true
schema:
$ref: '#/definitions/addons.UpgradeRequest'
produces:
- application/json
responses:
"200":
description: Operation accepted; the payload is the operation status
schema:
$ref: '#/definitions/contract.Result'
"400":
description: Malformed request
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Feature, administration or browser session denied
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"409":
description: Type stale_installed, candidate_changed, incompatible, integrity_error,
upgrade_conflict, upgrade_failed or operation_conflict
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Unavailable, check_failed, or outcome_unknown (with operationId)
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Upgrade an addon to the candidate that was checked (administrators,
browser session)
tags:
- Addons
/api/addons/apps:
get:
description: Returns the installed addons that are enabled, for every authenticated
caller who holds the addons feature. The owner decides what a caller sees;
hiding an entry is never the control, because every call the entry leads to
is authorized again. Each app has its title, description, icon URL, version
and installed generation, a process state (running, starting, failed or stopped;
the state is an observation, separate from the enabled flag), the path of
its main page when its manifest declares a valid one, and a bounded tool summary.
A headless addon is listed without a main page. Administrators additionally
see installed addons that are disabled and, per app, the start and stop controls
and the management link. An app carries update update-pending, separate from
state, only when the owner's cached update check says an update is available
for the installed package; the list never evaluates a check and never reaches
a library.
produces:
- application/json
responses:
"200":
description: Apps visible to the caller
schema:
$ref: '#/definitions/apps.List'
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Feature or owner policy denied the request
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Addons or the owner are unavailable
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: List the addon apps the caller may use
tags:
- Addons
/api/addons/apps/{id}/icon:
get:
description: Streams the immutable icon image of the app at the generation named
in the query. The image comes from the verified package on the owner, relayed
through the receiving frontend; it is never served from an addon process and
never from a URL the manifest names. It is served only for an app the caller
may see at the generation that was listed. An unknown app, a hidden app, an
app without a verified icon and a stale generation give the same 403. The
response is an image with X-Content-Type-Options nosniff and Cache-Control
private, no-store.
parameters:
- description: Addon ID
in: path
name: id
required: true
type: string
- description: Installed generation from the apps list
in: query
name: generation
required: true
type: integer
produces:
- image/png
- image/webp
- image/jpeg
responses:
"200":
description: Icon bytes
headers:
Cache-Control:
description: private, no-store
type: string
X-Content-Type-Options:
description: nosniff
type: string
schema:
type: string
"400":
description: Missing or malformed generation
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Feature denied, or the app is unknown, hidden, has no icon
or the generation is stale
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Addons or the owner are unavailable
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Read the icon of an addon app
tags:
- Addons
/api/addons/apps/{id}/start:
post:
consumes:
- application/json
description: 'Administrators only. Records the desired state enabled through
the same lifecycle manager and owner as the typed enable action; the owner
starts the process and health stays a separate observation. The body carries
the generation the caller saw in the apps list: a different installed generation
is denied before anything is recorded. The operationId is the identity of
the change: repeat it to replay safely, and after an outcome_unknown response
poll operation-status with it instead of submitting a new operation. Non-administrators
are denied (403) whatever the body says.'
parameters:
- description: Addon ID
in: path
name: id
required: true
type: string
- description: Operation and the generation the caller saw
in: body
name: request
required: true
schema:
$ref: '#/definitions/apps.StartRequest'
produces:
- application/json
responses:
"200":
description: Operation accepted; the payload is the operation status
schema:
$ref: '#/definitions/contract.Result'
"400":
description: Malformed body, missing operationId or generation
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Feature, administration or generation denied the request
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Addons or the owner are unavailable, or the outcome is unknown
(type outcome_unknown, with operationId)
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Start an addon app
tags:
- Addons
/api/addons/apps/{id}/stop:
post:
consumes:
- application/json
description: 'Administrators only. Records the desired state disabled through
the same lifecycle manager and owner as the typed disable action; the owner
drains and stops the process and keeps all data. The body carries the generation
the caller saw in the apps list: a different installed generation is denied
before anything is recorded. The operationId is the identity of the change:
repeat it to replay safely, and after an outcome_unknown response poll operation-status
with it instead of submitting a new operation. Non-administrators are denied
(403) whatever the body says.'
parameters:
- description: Addon ID
in: path
name: id
required: true
type: string
- description: Operation and the generation the caller saw
in: body
name: request
required: true
schema:
$ref: '#/definitions/apps.StartRequest'
produces:
- application/json
responses:
"200":
description: Operation accepted; the payload is the operation status
schema:
$ref: '#/definitions/contract.Result'
"400":
description: Malformed body, missing operationId or generation
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Feature, administration or generation denied the request
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Addons or the owner are unavailable, or the outcome is unknown
(type outcome_unknown, with operationId)
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Stop an addon app
tags:
- Addons
/api/addons/artifacts/{id}:
get:
description: 'Returns the caller''s own artifact: its state (transferring, complete,
failed or cancelled), the sanitized file name, the media type, the exact size
and the expiry. Only the principal that requested the result can read it;
an unknown identifier and another user''s artifact give the same 403, so identifiers
cannot be probed. The response never carries a storage path or an addon handle.
This is the status lookup of the background transfer; it is read-only.'
parameters:
- description: Artifact ID (host generated, opaque)
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: Artifact state
schema:
$ref: '#/definitions/gateway.Artifact'
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Feature denied, or the artifact is unknown, expired or not
the caller's
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Addons or the owner are unavailable
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Read the state of a private addon file result
tags:
- Addons
/api/addons/artifacts/{id}/download:
get:
description: Streams the caller's own complete artifact as an attachment, relayed
through the receiving frontend from the owner that holds the bytes. Access
needs the session or key of the principal that requested the result and, at
the start and while streaming, current read access to every source resource
and a current account. An artifact that is not complete, is expired, belongs
to another principal or is unknown gives the same 403. The response is always
an attachment (RFC 6266) with a sanitized name, a media type from a fixed
allowlist or application/octet-stream, X-Content-Type-Options nosniff and
Cache-Control private, no-store; it is never rendered inline. A failure after
the first byte aborts the connection, so a truncated file never looks complete.
Disabling the addon denies downloads and keeps the bytes until expiry; enabling
it again serves unexpired artifacts to principals that still have access.
parameters:
- description: Artifact ID (host generated, opaque)
in: path
name: id
required: true
type: string
produces:
- application/octet-stream
- text/csv
- application/json
responses:
"200":
description: Artifact bytes
headers:
Cache-Control:
description: private, no-store
type: string
Content-Disposition:
description: attachment with a sanitized filename and filename*
type: string
Content-Length:
description: exact size of the artifact
type: string
X-Content-Type-Options:
description: nosniff
type: string
schema:
type: string
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Feature denied, or the artifact is unknown, expired, incomplete,
not the caller's or no longer readable by the caller
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Addons or the owner are unavailable, or the download bound
is reached
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Download a private addon file result
tags:
- Addons
/api/addons/builtin:
get:
description: 'Returns the page add-ons that ship inside the web bundle. The
list is empty today: Studio and Talk are packaged add-ons that a person installs
from the Add-ons drawer. Each entry carries only its own gate: the route needs
an authenticated caller and no `addons` feature.'
produces:
- application/json
responses:
"200":
description: Entries the caller may open
schema:
additionalProperties:
items:
$ref: '#/definitions/builtin.Entry'
type: array
type: object
"401":
description: Authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: List the built-in add-ons the caller may open
tags:
- AddonNavigation
/api/addons/conversations/{conversationId}/selection/{addonId}:
delete:
description: Removes the authenticated user's selection for the conversation
and add-on. Clearing a selection that does not exist succeeds. No MCP tool
maps to this route.
parameters:
- description: Conversation ID
in: path
name: conversationId
required: true
type: string
- description: Add-on ID
in: path
name: addonId
required: true
type: string
responses:
"204":
description: Cleared
"400":
description: Malformed conversation or add-on ID
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Feature denied
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Addons or the owner are unavailable
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Clear the resource selected for a conversation
tags:
- Addons
get:
description: 'Returns the resource the authenticated user selected for the conversation
and add-on, with the user''s current role and display name. The stored reference
is keyed by the authenticated user, the conversation and the add-on, and is
never a credential: the owner authorizes it again on every use. A reference
that was revoked, deleted or never set is one answer: 404 not_selected. Another
user''s selection of the same conversation ID is never visible. Read-only.
No MCP tool maps to this route.'
parameters:
- description: Conversation ID
in: path
name: conversationId
required: true
type: string
- description: Add-on ID
in: path
name: addonId
required: true
type: string
produces:
- application/json
responses:
"200":
description: The selection
schema:
$ref: '#/definitions/gateway.Selection'
"400":
description: Malformed conversation or add-on ID
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Feature denied
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"404":
description: Type not_selected
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Addons or the owner are unavailable
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Read the resource selected for a conversation
tags:
- Addons
put:
consumes:
- application/json
description: Stores which resource the authenticated user chose for the conversation
and add-on, so that chat tool calls that name no resource use it. The caller
must hold at least the viewer role on the resource now; the stored reference
is never a bearer and is authorized again at the owner on every use. It is
not process-global, not shared between users or conversations, and not part
of the chat history. The store is bounded per user and expires unused entries.
No MCP tool maps to this route.
parameters:
- description: Conversation ID
in: path
name: conversationId
required: true
type: string
- description: Add-on ID
in: path
name: addonId
required: true
type: string
- description: The resource
in: body
name: request
required: true
schema:
$ref: '#/definitions/gateway.SelectionRequest'
produces:
- application/json
responses:
"200":
description: The selection
schema:
$ref: '#/definitions/gateway.Selection'
"400":
description: Malformed IDs or body
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Feature denied, or the resource is unknown or not readable
by the caller
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Addons or the owner are unavailable
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Select the resource a conversation works on
tags:
- Addons
/api/addons/dispatch:
post:
consumes:
- application/json
description: 'Authenticates the named caller, checks the addons feature, requires
administration for every action except read, and forwards the typed request
to the designated addon owner. A mutation is never retried: after an outcome_unknown
response keep the operationId and poll operation-status instead of submitting
a new mutation. Lifecycle actions are install, upgrade, enable, disable and
uninstall (arguments sourceId and version; enable and disable take the generation
that was listed). The management reads, all administrator-only and never mutations,
are catalog-search (arguments text, kind, sourceId, offset, limit up to 100;
kind is addon by default, or backend, or all), catalog-details (addonId plus
arguments sourceId and version), catalog-sources and addons-installed. The
library changes are catalog-source-save (arguments are one source: id, name,
url, enabled, policy, authReference; removed true deletes it and never touches
installed addons) and catalog-source-refresh (argument sourceId). A library
names a credential only by a reference the owner configured, never a secret.
Unknown argument fields are denied. The update actions are update-status and
update-check (no arguments; the check fetches the library again and applies
nothing) and update-upgrade (arguments expectedDigest and candidateDigest,
the pinned upgrade); each answers with a payload {error: {type, message, status}}
or {data}, the same from every frontend. The browser pages use the dedicated
routes under /api/addons/{id}/update and /api/addons/{id}/upgrade, which accept
only an administrator''s own browser session.'
parameters:
- description: Typed addon request
in: body
name: request
required: true
schema:
$ref: '#/definitions/contract.Request'
produces:
- application/json
responses:
"200":
description: Operation accepted or read result
schema:
$ref: '#/definitions/contract.Result'
"400":
description: 'Malformed or unknown request fields, or type invalid_request
when the add-on refused the request as invalid: nothing was applied and
the same call is refused again'
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: 'Feature, administration or owner policy denied the request,
or type sdk_incompatible when an install is refused because the add-on
needs another SDK version: the message names the range the add-on needs
and the SDK version the host provides'
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Addons or the owner are unavailable, or the outcome of a mutation
is unknown (type outcome_unknown, with operationId)
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Submit a typed addon lifecycle operation or read an addon resource
tags:
- Addons
/api/addons/pins:
get:
description: 'Returns the ordered add-on IDs the caller pinned to the sidebar.
The route never pins anything by itself; Studio and Talk are pinned once,
at upgrade, for the accounts that existed then. The list holds only IDs the
caller may see right now: a hidden or removed add-on is left out and the route
does not reveal whether it exists. Needs an authenticated caller and no administrator
role.'
produces:
- application/json
responses:
"200":
description: Ordered add-on IDs
schema:
items:
type: string
type: array
"401":
description: Authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: The pin store is unavailable
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: List the add-ons the caller pinned
tags:
- AddonNavigation
put:
consumes:
- application/json
description: Replaces the caller's pins with the ordered list in the body. IDs
the caller may not see are dropped without any hint, and pins that are only
hidden for now are kept. At most 32 IDs are accepted. Needs an authenticated
caller from a same-origin browser request or a credential header, and no administrator
role.
parameters:
- description: Ordered add-on IDs
in: body
name: pins
required: true
schema:
items:
type: string
type: array
produces:
- application/json
responses:
"200":
description: The saved list the caller can see
schema:
items:
type: string
type: array
"400":
description: Not a list of strings, or longer than 32
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"401":
description: Authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: The pin store or the add-on owner is unavailable
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Replace the add-ons the caller pinned
tags:
- AddonNavigation
/api/addons/proposals:
get:
description: 'Returns the caller''s proposals that still wait for a human decision,
newest first, at most 32, each with its state, exact effect count, bounded
sample, digest and expiry. This is where a change proposed by a chat tool,
an agent or a scheduled job waits: only the proposer''s own browser session
can confirm it. A proposal of another user is never listed, and an expired
one is left out. Read-only: it applies nothing. API keys may call it so an
unattended agent can see what is waiting; they still cannot confirm.'
parameters:
- description: Only pending is supported
enum:
- pending
in: query
name: state
required: true
type: string
produces:
- application/json
responses:
"200":
description: The caller's pending proposals
schema:
$ref: '#/definitions/gateway.PendingList'
"400":
description: Missing or unsupported state filter
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Feature denied
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Addons or the owner are unavailable
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: List the caller's own pending addon proposals
tags:
- Addons
post:
consumes:
- application/json
description: 'A request with action create and no resourceId proposes the creation
of a resource: the owner reserves a pending resource for the caller that nobody
can reach, shows the requested name, and creates it only on confirmation by
the proposer''s browser session. Previews the mutation on the addon owner
and stores it as a pending proposal with its exact effect count, a bounded
sample, the revisions it saw and an expiry. Nothing is applied. The operationId
becomes the proposal ID; repeating the same request returns the same proposal.
Sharing and database deletion are never proposals. A named session or API
key with the addons feature may propose; the proposal can only be applied
by Confirm, which requires the proposer''s own browser session. No MCP tool
confirms a proposal.'
parameters:
- description: Typed write, schema or create request
in: body
name: request
required: true
schema:
$ref: '#/definitions/contract.Request'
produces:
- application/json
responses:
"200":
description: Stored proposal
schema:
$ref: '#/definitions/gateway.Proposal'
"400":
description: 'Malformed or unknown request fields, or type invalid_request
when the add-on refused the request as invalid: nothing was applied and
the same call is refused again'
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Feature, resource policy or request binding denied the proposal.
Type outcome_blocked (with blockedBy) when the caller is the owner role
of the resource and another operation on it has an unresolved outcome;
other callers get the plain denial
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: 'Addons or the owner are unavailable. Type outcome_unknown
(with operationId): the proposal had been handed to the addon and its
outcome is unknown, reconcile it. Type proposal_unavailable (with operationId):
the owner could not serve this call and this call sent nothing to the
addon; read the proposal for its state, which may already be settled,
and repeat the same call with the same ID'
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Propose an addon data or schema mutation, or a resource creation, for
confirmation
tags:
- Addons
/api/addons/proposals/{id}:
get:
description: Returns the caller's own proposal with its state, effects, receipt
and, for a pending proposal that is blocked, the operation to resolve first.
Expiry is recorded when a pending proposal is read after its expiry.
parameters:
- description: Proposal ID (the operation ID)
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: Stored proposal
schema:
$ref: '#/definitions/gateway.Proposal'
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Feature denied, or the proposal is not the caller's
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Addons or the owner are unavailable
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Read a stored addon proposal
tags:
- Addons
/api/addons/proposals/{id}/cancel:
post:
description: Withdraws the caller's pending proposal. A cancelled, expired or
settled proposal can never run. Cancelling needs only a current identity.
parameters:
- description: Proposal ID (the operation ID)
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: Cancelled proposal
schema:
$ref: '#/definitions/gateway.Proposal'
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Feature denied, the proposal is not the caller's, or it is
not pending
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: 'Addons or the owner are unavailable. Type outcome_unknown
(with operationId): the proposal had been handed to the addon and its
outcome is unknown, reconcile it. Type proposal_unavailable (with operationId):
the owner could not serve this call and this call sent nothing to the
addon; read the proposal for its state, which may already be settled,
and repeat the same call with the same ID'
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Cancel a pending addon proposal
tags:
- Addons
/api/addons/proposals/{id}/confirm:
post:
consumes:
- application/json
description: 'Applies exactly the stored operation once. This is the only way
a stored mutation reaches an addon. It is accepted only from the proposer''s
own browser session: a same-origin fetch from the host UI that carries the
X-LocalAI-Confirm header equal to the proposal ID and the digest of what was
shown. API keys, bearer tokens, MCP sessions and requests that carry tool
or agent execution markers are refused, and no MCP tool maps to this route.
A repeated confirmation returns the stored receipt. If the reply is lost the
outcome is outcome_unknown with the original operationId; resolve it with
reconcile and never submit the change again.'
parameters:
- description: Proposal ID (the operation ID)
in: path
name: id
required: true
type: string
- description: Digest of the displayed proposal
in: body
name: request
required: true
schema:
$ref: '#/definitions/addons.ConfirmRequest'
produces:
- application/json
responses:
"200":
description: Proposal after the apply, with its receipt
schema:
$ref: '#/definitions/gateway.Proposal'
"400":
description: 'Malformed or unknown request fields, or type invalid_request
when the add-on refused the request as invalid: nothing was applied and
the same call is refused again'
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Not a human confirmation surface, feature denied, or the proposal
is not pending, is expired, stale, changed or blocked
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: 'Addons or the owner are unavailable. Type outcome_unknown
(with operationId): the proposal had been handed to the addon and its
outcome is unknown, reconcile it. Type proposal_unavailable (with operationId):
the owner could not serve this call and this call sent nothing to the
addon; read the proposal for its state, which may already be settled,
and repeat the same call with the same ID'
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Confirm and apply a pending addon proposal
tags:
- Addons
/api/addons/proposals/{id}/reconcile:
post:
description: Looks the operation's receipt up on the owner and records a committed
or rejected result. It never applies anything and can be repeated. Use it
after an outcome_unknown response. While an outcome is unresolved, other writes
on the same resource are denied.
parameters:
- description: Proposal ID (the operation ID)
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: Proposal after the lookup
schema:
$ref: '#/definitions/gateway.Proposal'
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Feature denied or the proposal is not the caller's
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Addons, the owner or the addon runtime are unavailable
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Resolve the outcome of an addon proposal by receipt lookup
tags:
- Addons
/api/addons/proposals/{id}/resolve:
post:
consumes:
- application/json
description: 'Explicit recovery for an operation whose receipt cannot be found.
After outcome_unknown, repeated reconcile calls and the automatic lookups
that did not settle it, the owner role of the resource may record that the
outcome is not worth waiting for. The proposal becomes abandoned-unknown with
the acting owner, the time and the stated reason, and stops blocking writes
on the resource. The operation is never submitted again, and a later receipt
lookup that says it ran is recorded as applied. The owner is asserting that
waiting is not worth it: a change that did run stays in the data, and the
revision check of later changes protects against applying on a stale view.
Accepted only from a host confirmation surface with the same rules as confirm:
the owner''s own browser session, a same-origin fetch, the X-LocalAI-Confirm
header equal to the proposal ID, and no tool, agent or MCP marker. Installation
administrators and API keys have no access through this route, and no MCP
tool maps to it.'
parameters:
- description: Proposal ID (the operation ID)
in: path
name: id
required: true
type: string
- description: Digest of the displayed proposal and the reason
in: body
name: request
required: true
schema:
$ref: '#/definitions/addons.ResolveRequest'
produces:
- application/json
responses:
"200":
description: Proposal after the acknowledgement, or settled by a final receipt
schema:
$ref: '#/definitions/gateway.Proposal'
"400":
description: 'Malformed or unknown request fields, or type invalid_request
when the add-on refused the request as invalid: nothing was applied and
the same call is refused again'
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Not a human confirmation surface, not the resource owner, feature
denied, digest changed or the proposal is not unresolved
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: 'Addons or the owner are unavailable. Always type proposal_unavailable
(with operationId), whoever proposed the operation, because resolving
is not an apply: the owner could not serve this call and it sent nothing
to the addon; read the proposal for its state and repeat the same call
with the same ID'
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Abandon an unresolved addon proposal outcome as the resource owner
tags:
- Addons
/api/addons/relay:
post:
consumes:
- application/json
description: 'Streams the response of the designated addon owner through the
receiving frontend, bounded per kind by the configured byte and time limits.
The kind selects the response: status (JSON), progress (text/event-stream),
json, file (a private file result as an attachment: the handle is the artifact
ID that a read returned, never an addon handle) or asset (text/javascript
or text/css). An owner decision made before the first byte is returned with
the same status from every frontend; a failure after the first byte aborts
the stream.'
parameters:
- description: Relay request
in: body
name: request
required: true
schema:
$ref: '#/definitions/gateway.RelayRequest'
produces:
- application/json
- text/event-stream
- application/octet-stream
- text/javascript
- text/css
responses:
"200":
description: Relayed response body
schema:
type: string
"400":
description: 'Malformed or unknown request fields, or type invalid_request
when the add-on refused the request as invalid: nothing was applied and
the same call is refused again'
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Feature or owner policy denied the request
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Addons or the owner are unavailable
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Relay addon status, lifecycle progress, JSON, attachments or immutable
UI assets
tags:
- Addons
/api/addons/resources:
get:
description: 'Returns the resources of one add-on that the caller owns or that
were shared with the caller, each with the caller''s own role, the display
name the add-on reported (empty when it could not answer in time), the owner''s
display name for a shared resource and, for the owner role only, how many
people it is shared with and the revision to send back with a rename or a
delete. Resources of other people that are not shared with the caller are
never listed, whatever the caller''s installation role: installation administration
is not data access. The answer also carries the installed generation, whether
sharing is possible (false in local-owner mode) and the management operations
the add-on supports. At most 100 resources are listed (truncated says more
exist). Read-only. API keys may call it. No MCP tool maps to this route.'
parameters:
- description: Add-on ID
in: query
name: addonId
required: true
type: string
produces:
- application/json
responses:
"200":
description: Resources the caller may use
schema:
$ref: '#/definitions/gateway.ResourceList'
"400":
description: Missing or malformed add-on ID
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Feature denied
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Addons, the owner or the add-on are unavailable
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: List the add-on resources the caller may use
tags:
- Addons
post:
consumes:
- application/json
description: 'Creates a resource through the add-on''s create tool as the person''s
own explicit action, for example a new database. It needs no confirmation
card: the request is the intent, and the same admission, quota, receipt and
crash reconciliation rules as every mutation apply. The caller becomes the
owner and the resource is private. Repeating the same operationId returns
the same resource and never creates a second one; after outcome_unknown repeat
the same call. The arguments are validated against the add-on''s own tool
definition. Accepted only from the person''s own browser session: a same-origin
fetch whose X-LocalAI-Confirm header equals the operationId, with no API key
and no tool, agent or MCP marker. No MCP tool maps to this route.'
parameters:
- description: Create request
in: body
name: request
required: true
schema:
$ref: '#/definitions/gateway.CreateResourceRequest'
produces:
- application/json
responses:
"200":
description: The created resource
schema:
$ref: '#/definitions/gateway.ResourceInfo'
"400":
description: Malformed request or arguments the add-on's tool does not accept
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Not a human surface, feature or creation authority denied,
or type quota_reached
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"409":
description: 'Type stale: the generation is not the installed one'
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Unavailable, or type outcome_unknown (with operationId) after
which the same call is repeated
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Create an add-on resource (UI only)
tags:
- Addons
/api/addons/resources/{resourceId}/apply:
post:
consumes:
- application/json
description: 'Applies one change through a write or schema tool the add-on declares,
for example inserting rows or adding a column, as the person''s own explicit
action in the person''s own browser tab. It needs no confirmation card: the
request is the intent. It is not a proposal and nothing is stored for later.
The same rules as every change apply: the role of the action (the owner and
editors write rows, only the owner changes the schema, viewers and installation
administrators without a grant get the answer of an unknown resource), the
declared tool definition, the resource''s admission, the generation and the
revision the caller read (409 stale, nothing changed), the add-on''s receipt,
which makes repeating the same operationId with the same request one change,
and a wait behind an unresolved outcome. The tool''s arguments must not name
the resource, the tool, an actor or any field the tool definition does not
declare. Reads, creations, the add-on''s rename and delete, administrator
tools and tools nobody declared are refused with 400. Accepted only from the
person''s own browser session: a same-origin fetch whose X-LocalAI-Confirm
header equals the resource ID, with no API key and no tool, agent or MCP marker.
After outcome_unknown, look the receipt up with kind=apply and the original
operationId; never submit a new operation. No MCP tool maps to this route.'
parameters:
- description: Resource ID
in: path
name: resourceId
required: true
type: string
- description: Change request
in: body
name: request
required: true
schema:
$ref: '#/definitions/gateway.ApplyResourceRequest'
produces:
- application/json
responses:
"200":
description: The committed change and its receipt
schema:
$ref: '#/definitions/gateway.ApplyResult'
"400":
description: Malformed request, a tool that is not a change, or arguments
the tool does not accept
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Not a human surface, feature denied, role too low or unknown
resource, or type outcome_blocked
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"409":
description: 'Type stale: the generation or the revision moved'
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Unavailable, or type outcome_unknown (with operationId)
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Change a resource's data or schema by the person's own action (UI only)
tags:
- Addons
/api/addons/resources/{resourceId}/delete:
post:
consumes:
- application/json
description: 'Permanently deletes the resource, its data and every grant, as
the owner''s own explicit action. It is never a chat operation and never an
uninstall. The request must carry the generation and revision the owner listed
and confirm, which must equal the resource''s display name exactly. The owner
marks the resource as deleting (inaccessible to everyone, no new admission),
stops and waits for admitted work, checks the revision, cancels pending proposals,
asks the add-on to delete and only then removes the record and the grants.
A crash leaves a deleting record that the owner finishes at startup; an unconfirmed
one returns to use. A 503 with type outcome_unknown means the deletion is
confirmed and being finished: repeat the same call, the resource is inaccessible
meanwhile. Accepted only from the owner''s own browser session (same-origin
fetch, X-LocalAI-Confirm equal to the resource ID). No MCP tool maps to this
route and the add-on''s delete tool is not offered to any model.'
parameters:
- description: Resource ID
in: path
name: resourceId
required: true
type: string
- description: Delete request with the typed confirmation
in: body
name: request
required: true
schema:
$ref: '#/definitions/gateway.DeleteResourceRequest'
produces:
- application/json
responses:
"200":
description: Deleted
schema:
$ref: '#/definitions/gateway.DeleteResult'
"400":
description: Malformed request, wrong confirmation or unsupported operation
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Not a human surface, feature denied, not the owner role or
unknown resource, or type outcome_blocked
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"409":
description: Type stale
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Unavailable, or type outcome_unknown (with operationId)
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Delete a resource and its data (owner, UI only)
tags:
- Addons
/api/addons/resources/{resourceId}/grants:
get:
description: 'Returns the grants of the whole resource: the immutable account
ID, the display name and the role of each grantee. Only the owner role of
the resource may read it; installation administrators, editors and viewers
get the same denial as for an unknown resource. Local-owner mode has no sharing
and answers 409 sharing_disabled. Accepted only from the owner''s own browser
session (same-origin fetch, X-LocalAI-Confirm equal to the resource ID). No
MCP tool maps to this route.'
parameters:
- description: Resource ID
in: path
name: resourceId
required: true
type: string
produces:
- application/json
responses:
"200":
description: Grants of the resource
schema:
$ref: '#/definitions/gateway.GrantList'
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Not a human surface, feature denied, not the owner role or
unknown resource
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"409":
description: Type sharing_disabled
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Addons or the owner are unavailable
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: List who a resource is shared with (owner, UI only)
tags:
- Addons
/api/addons/resources/{resourceId}/grants/{userId}:
delete:
description: Removes the user's grant. It returns only after the user's admitted
work stopped and their pending proposals were cancelled; a drain that did
not finish in the bound is a 503 and the revocation is already effective for
new work. Local-owner mode answers 409 sharing_disabled. Accepted only from
the owner's own browser session (same-origin fetch, X-LocalAI-Confirm equal
to the resource ID). Safe to repeat. No MCP tool maps to this route.
parameters:
- description: Resource ID
in: path
name: resourceId
required: true
type: string
- description: Account ID of the grantee
in: path
name: userId
required: true
type: string
- description: Optional operation ID, returned with outcome_unknown
in: query
name: operationId
type: string
produces:
- application/json
responses:
"200":
description: Grants after the change
schema:
$ref: '#/definitions/gateway.GrantList'
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Not a human surface, feature denied, not the owner role or
unknown resource
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"409":
description: Type sharing_disabled
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Unavailable, or type outcome_unknown (with operationId)
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Stop sharing a resource with a user (owner, UI only)
tags:
- Addons
put:
consumes:
- application/json
description: 'Gives the user the viewer or editor role on the whole resource;
there are no per-table grants and the owner role cannot be granted. The user
is named by the immutable account ID the user picker returned, and must be
an active named account that may use add-ons. Lowering a role stops the user''s
admitted work and cancels the user''s pending proposals before it is acknowledged.
Local-owner mode answers 409 sharing_disabled. Accepted only from the owner''s
own browser session (same-origin fetch, X-LocalAI-Confirm equal to the resource
ID). Safe to repeat; after outcome_unknown repeat the same call. No MCP tool
maps to this route: sharing is never a tool.'
parameters:
- description: Resource ID
in: path
name: resourceId
required: true
type: string
- description: Account ID of the grantee
in: path
name: userId
required: true
type: string
- description: Role
in: body
name: request
required: true
schema:
$ref: '#/definitions/gateway.SetGrantRequest'
produces:
- application/json
responses:
"200":
description: Grants after the change
schema:
$ref: '#/definitions/gateway.GrantList'
"400":
description: Malformed body or role
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Not a human surface, feature denied, not the owner role, unknown
resource or a user that cannot be granted
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"409":
description: Type sharing_disabled
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Unavailable, or type outcome_unknown (with operationId)
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Share a whole resource with a named user (owner, UI only)
tags:
- Addons
/api/addons/resources/{resourceId}/operations/{operationId}:
get:
description: Read-only receipt lookup after an outcome_unknown answer. kind
is rename (operationId is the one the rename carried), delete or apply (the
operationId of a change; any role that may write looks up its own). The state
is pending, committed, rejected or unknown; it never applies anything. The
owner role may look up a rename or a deletion and the roles that may write
look up their own changes, from the owner's own browser session (same-origin
fetch, X-LocalAI-Confirm equal to the resource ID). After a deletion finished
the resource is gone and the lookup is denied like any unknown resource. No
MCP tool maps to this route.
parameters:
- description: Resource ID
in: path
name: resourceId
required: true
type: string
- description: Operation ID of the rename
in: path
name: operationId
required: true
type: string
- description: Operation kind
enum:
- rename
- delete
- apply
in: query
name: kind
required: true
type: string
- description: 'Apply only: the requestHash of the request the caller means
(64 lowercase hex). A lookup whose hash is not the one the operation ID
was used for is a 409 operation_conflict, never the other request''s receipt'
in: query
name: requestHash
type: string
produces:
- application/json
responses:
"200":
description: Receipt state
schema:
$ref: '#/definitions/gateway.OperationStatus'
"400":
description: Unsupported kind or malformed requestHash
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Not a human surface, feature denied, not the owner role or
unknown resource
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"409":
description: 'Type operation_conflict: the operation ID belongs to another
request'
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Addons, the owner or the add-on are unavailable
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Look up the receipt of a rename or a deletion (owner, UI only)
tags:
- Addons
/api/addons/resources/{resourceId}/proposals:
get:
description: 'Returns the proposals on the resource whose outcome is unresolved
(executing, outcome-unknown) or abandoned-unknown, whoever proposed them,
so the resource owner can learn the operation ID and digest that resolve needs.
Each entry has the proposal ID, state, the proposing user, the action, the
exact effect count and the bounded effect sample the proposer saw, the expiry,
the digest and the age in seconds. It never returns the proposed arguments
or any credential. Read-only. Only the owner role of the resource may call
it; installation administrators, editors and viewers are denied. It is accepted
only from a host confirmation surface with the rules of resolve: the owner''s
own browser session, a same-origin fetch, the X-LocalAI-Confirm header equal
to the resource ID, and no tool, agent or MCP marker. API keys are refused
and no MCP tool maps to this route.'
parameters:
- description: Resource ID
in: path
name: resourceId
required: true
type: string
- description: Only unresolved is supported
enum:
- unresolved
in: query
name: state
required: true
type: string
produces:
- application/json
responses:
"200":
description: Unresolved proposals, oldest first
schema:
$ref: '#/definitions/gateway.ProposalList'
"400":
description: Missing or unsupported state filter
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Not a human confirmation surface, not the owner role of the
resource, feature denied or unknown resource
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Addons or the owner are unavailable
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: List the unresolved addon proposals of a resource as its owner
tags:
- Addons
/api/addons/resources/{resourceId}/rename:
post:
consumes:
- application/json
description: Renames the resource through the add-on as the owner's own explicit
action, with no confirmation card. It still runs under the resource's admission,
waits behind an unresolved outcome (403 outcome_blocked for the owner role),
is checked against the generation and the revision the owner listed (409 stale,
nothing changed) and leaves the add-on's receipt for the operation. Repeating
the same operationId never renames twice; after outcome_unknown repeat the
same call or look it up with the operation status route. Accepted only from
the owner's own browser session (same-origin fetch, X-LocalAI-Confirm equal
to the resource ID). No MCP tool maps to this route.
parameters:
- description: Resource ID
in: path
name: resourceId
required: true
type: string
- description: Rename request
in: body
name: request
required: true
schema:
$ref: '#/definitions/gateway.RenameResourceRequest'
produces:
- application/json
responses:
"200":
description: The renamed resource
schema:
$ref: '#/definitions/gateway.ResourceInfo'
"400":
description: Malformed request or a name the add-on refuses
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Not a human surface, feature denied, not the owner role or
unknown resource, or type outcome_blocked
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"409":
description: Type stale
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Unavailable, or type outcome_unknown (with operationId)
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Rename a resource (owner, UI only)
tags:
- Addons
/api/addons/resources/{resourceId}/users:
get:
description: Finds active named accounts that may use add-ons by a prefix of
the display name or of the address, 2 to 64 characters, at most 20 results.
Each result is an immutable account ID and a display name and nothing else.
Only the owner role of the resource may search; the owner and the caller are
left out. Local-owner mode answers 409 sharing_disabled. Accepted only from
the owner's own browser session (same-origin fetch, X-LocalAI-Confirm equal
to the resource ID). No MCP tool maps to this route.
parameters:
- description: Resource ID
in: path
name: resourceId
required: true
type: string
- description: Name or address prefix
in: query
name: q
required: true
type: string
- description: At most this many results, up to 20
in: query
name: limit
type: integer
produces:
- application/json
responses:
"200":
description: Matching people
schema:
$ref: '#/definitions/gateway.UserList'
"400":
description: Query too short or too long
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"401":
description: Named authentication required
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"403":
description: Not a human surface, feature denied, not the owner role or
unknown resource
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"409":
description: Type sharing_disabled
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
"503":
description: Addons or the owner are unavailable
schema:
$ref: '#/definitions/addons.AddonErrorResponse'
summary: Search the people a resource can be shared with (owner, UI only)
tags:
- Addons
/api/agent/jobs:
get:
parameters:
- description: Filter by task ID
in: query
name: task_id
type: string
- description: Filter by status (pending, running, completed, failed, cancelled)
in: query
name: status
type: string
- description: Max number of jobs to return
in: query
name: limit
type: integer
- description: Set to 'true' for admin cross-user listing
in: query
name: all_users
type: string
produces:
- application/json
responses:
"200":
description: jobs
schema:
items:
$ref: '#/definitions/schema.Job'
type: array
summary: List agent jobs
tags:
- agent-jobs
/api/agent/jobs/{id}:
delete:
parameters:
- description: Job ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: message
schema:
additionalProperties:
type: string
type: object
"404":
description: error
schema:
additionalProperties:
type: string
type: object
summary: Delete an agent job
tags:
- agent-jobs
get:
parameters:
- description: Job ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: job
schema:
$ref: '#/definitions/schema.Job'
"404":
description: error
schema:
additionalProperties:
type: string
type: object
summary: Get an agent job
tags:
- agent-jobs
/api/agent/jobs/{id}/cancel:
post:
parameters:
- description: Job ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: message
schema:
additionalProperties:
type: string
type: object
"400":
description: error
schema:
additionalProperties:
type: string
type: object
"404":
description: error
schema:
additionalProperties:
type: string
type: object
summary: Cancel an agent job
tags:
- agent-jobs
/api/agent/jobs/execute:
post:
consumes:
- application/json
parameters:
- description: Job execution request
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.JobExecutionRequest'
produces:
- application/json
responses:
"201":
description: job created
schema:
$ref: '#/definitions/schema.JobExecutionResponse'
"400":
description: error
schema:
additionalProperties:
type: string
type: object
summary: Execute an agent job
tags:
- agent-jobs
/api/agent/tasks:
get:
parameters:
- description: Set to 'true' for admin cross-user listing
in: query
name: all_users
type: string
produces:
- application/json
responses:
"200":
description: tasks
schema:
items:
$ref: '#/definitions/schema.Task'
type: array
summary: List agent tasks
tags:
- agent-jobs
post:
consumes:
- application/json
parameters:
- description: Task definition
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.Task'
produces:
- application/json
responses:
"201":
description: id
schema:
additionalProperties:
type: string
type: object
"400":
description: error
schema:
additionalProperties:
type: string
type: object
summary: Create a new agent task
tags:
- agent-jobs
/api/agent/tasks/{id}:
delete:
parameters:
- description: Task ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: message
schema:
additionalProperties:
type: string
type: object
"404":
description: error
schema:
additionalProperties:
type: string
type: object
summary: Delete an agent task
tags:
- agent-jobs
get:
parameters:
- description: Task ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: task
schema:
$ref: '#/definitions/schema.Task'
"404":
description: error
schema:
additionalProperties:
type: string
type: object
summary: Get an agent task
tags:
- agent-jobs
put:
consumes:
- application/json
parameters:
- description: Task ID
in: path
name: id
required: true
type: string
- description: Updated task definition
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.Task'
produces:
- application/json
responses:
"200":
description: message
schema:
additionalProperties:
type: string
type: object
"400":
description: error
schema:
additionalProperties:
type: string
type: object
"404":
description: error
schema:
additionalProperties:
type: string
type: object
summary: Update an agent task
tags:
- agent-jobs
/api/agent/tasks/{name}/execute:
post:
consumes:
- application/json
parameters:
- description: Task name
in: path
name: name
required: true
type: string
- description: Optional template parameters
in: body
name: parameters
schema:
type: object
produces:
- application/json
responses:
"201":
description: job created
schema:
$ref: '#/definitions/schema.JobExecutionResponse'
"400":
description: error
schema:
additionalProperties:
type: string
type: object
"404":
description: error
schema:
additionalProperties:
type: string
type: object
summary: Execute an agent task by name
tags:
- agent-jobs
/api/aliases:
get:
responses:
"200":
description: OK
schema:
items:
$ref: '#/definitions/localai.AliasInfo'
type: array
summary: List model aliases
tags:
- models
/api/backend-logs:
get:
description: Returns a sorted list of model IDs that have captured backend process
output
produces:
- application/json
responses:
"200":
description: Model IDs with logs
schema:
items:
type: string
type: array
summary: List models with backend logs
tags:
- monitoring
/api/backend-logs/{modelId}:
get:
description: Returns all captured log lines (stdout/stderr) for the specified
model's backend process
parameters:
- description: Model ID
in: path
name: modelId
required: true
type: string
produces:
- application/json
responses:
"200":
description: Log lines
schema:
items:
$ref: '#/definitions/model.BackendLogLine'
type: array
summary: Get backend logs for a model
tags:
- monitoring
/api/backend-logs/{modelId}/clear:
post:
description: Removes all captured log lines for the specified model's backend
process
parameters:
- description: Model ID
in: path
name: modelId
required: true
type: string
responses:
"204":
description: Logs cleared
summary: Clear backend logs for a model
tags:
- monitoring
/api/backend-traces:
get:
description: Returns a bounded, newest-first page of captured backend traces
(LLM calls, embeddings, TTS, etc). The heavy body and data fields are omitted
unless full=true; fetch them per-trace from /api/backend-traces/{id}. Paging
metadata is returned in the X-Total-Count, X-Trace-Offset and X-Trace-Limit
headers.
parameters:
- description: Maximum entries to return (default 50, max 1000, 0 for all)
in: query
name: limit
type: integer
- description: Number of entries to skip (default 0)
in: query
name: offset
type: integer
- description: Include the body and data payloads (default false)
in: query
name: full
type: boolean
produces:
- application/json
responses:
"200":
description: Backend operation traces
schema:
additionalProperties: true
type: object
summary: List backend operation traces
tags:
- monitoring
/api/backend-traces/{id}:
get:
description: Returns a single captured backend trace, including the body and
data payloads omitted from the list response
parameters:
- description: Trace ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: Backend operation trace
schema:
additionalProperties: true
type: object
"404":
description: Trace not found
schema:
$ref: '#/definitions/schema.ErrorResponse'
summary: Get one backend operation trace
tags:
- monitoring
/api/backend-traces/clear:
post:
description: Removes all captured backend operation traces from the buffer
responses:
"204":
description: Traces cleared
summary: Clear backend traces
tags:
- monitoring
/api/branding:
get:
description: Returns the configured instance name, tagline, and asset URLs.
Public — no authentication required.
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/localai.BrandingResponse'
summary: Get instance branding
tags:
- branding
/api/branding/asset/{kind}:
delete:
description: Remove a custom branding asset; the UI falls back to the bundled
LocalAI default.
parameters:
- description: 'Asset kind: logo, logo_horizontal, or favicon'
in: path
name: kind
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/localai.BrandingResponse'
summary: Reset a branding asset to default
tags:
- branding
post:
consumes:
- multipart/form-data
description: Upload a custom logo, horizontal logo, or favicon. The file replaces
any previous override for that kind.
parameters:
- description: 'Asset kind: logo, logo_horizontal, or favicon'
in: path
name: kind
required: true
type: string
- description: Image file (png, jpeg, svg, webp, ico — up to 5MiB)
in: formData
name: file
required: true
type: file
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/localai.BrandingResponse'
"400":
description: Bad Request
schema:
additionalProperties:
type: string
type: object
summary: Upload a branding asset
tags:
- branding
/api/conversations:
delete:
produces:
- application/json
responses:
"200":
description: OK
schema:
additionalProperties:
type: string
type: object
summary: Delete all chat conversations for the current user
tags:
- chat-history
get:
description: Returns the live conversations, newest first, and in `deleted`
the conversations the user deleted. A client must drop any local copy whose
id appears in `deleted` instead of uploading it again.
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/schema.ConversationList'
summary: List chat conversations
tags:
- chat-history
post:
consumes:
- application/json
description: Stores the conversation and returns it with its new server-assigned
`version`. `createdAt`/`updatedAt` are kept as sent (Unix ms). Writing a conversation
the user deleted returns 410 and does not bring it back.
parameters:
- description: Conversation payload
in: body
name: body
required: true
schema:
$ref: '#/definitions/schema.Conversation'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/schema.Conversation'
"400":
description: Invalid id or body
schema:
additionalProperties:
type: string
type: object
"410":
description: Deleted
schema:
additionalProperties:
type: string
type: object
summary: Save a chat conversation (upsert)
tags:
- chat-history
/api/conversations/{id}:
delete:
description: Deletes the conversation and keeps a tombstone so no client can
write it back. Deleting an unknown or already deleted id succeeds.
parameters:
- description: Conversation ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
additionalProperties:
type: string
type: object
"400":
description: Invalid id
schema:
additionalProperties:
type: string
type: object
summary: Delete a chat conversation
tags:
- chat-history
get:
parameters:
- description: Conversation ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/schema.Conversation'
"404":
description: Never existed
schema:
additionalProperties:
type: string
type: object
"410":
description: Deleted
schema:
additionalProperties:
type: string
type: object
summary: Get a chat conversation
tags:
- chat-history
put:
consumes:
- application/json
parameters:
- description: Conversation ID (overrides the body id)
in: path
name: id
required: true
type: string
- description: Conversation payload
in: body
name: body
required: true
schema:
$ref: '#/definitions/schema.Conversation'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/schema.Conversation'
"400":
description: Invalid id or body
schema:
additionalProperties:
type: string
type: object
"410":
description: Deleted
schema:
additionalProperties:
type: string
type: object
summary: Save a chat conversation by id (upsert)
tags:
- chat-history
/api/conversations/bulk:
put:
consumes:
- application/json
description: Upserts every conversation in the payload and deletes the user's
other live conversations. Ids the user deleted earlier are not written and
are listed in `skipped`.
parameters:
- description: Conversations
in: body
name: body
required: true
schema:
$ref: '#/definitions/schema.ConversationBulkRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/schema.ConversationBulkResponse'
"400":
description: Invalid id or body
schema:
additionalProperties:
type: string
type: object
summary: Replace all chat conversations
tags:
- chat-history
/api/failover:
get:
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/localai.FailoverChainsResponse'
summary: List failover chains and the health of their targets
tags:
- failover
/api/failover/{chain}:
get:
parameters:
- description: Chain name
in: path
name: chain
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/failover.ChainStatus'
"404":
description: Not Found
schema:
$ref: '#/definitions/schema.ErrorResponse'
summary: Get one failover chain
tags:
- failover
/api/failover/{chain}/pin:
delete:
parameters:
- description: Chain name
in: path
name: chain
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/failover.ChainStatus'
"404":
description: Not Found
schema:
$ref: '#/definitions/schema.ErrorResponse'
summary: Remove the pin from a failover chain
tags:
- failover
post:
consumes:
- application/json
parameters:
- description: Chain name
in: path
name: chain
required: true
type: string
- description: Target to pin
in: body
name: request
required: true
schema:
$ref: '#/definitions/localai.FailoverPinRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/failover.ChainStatus'
"400":
description: Bad Request
schema:
$ref: '#/definitions/schema.ErrorResponse'
"404":
description: Not Found
schema:
$ref: '#/definitions/schema.ErrorResponse'
summary: Pin a failover chain to one target
tags:
- failover
/api/failover/events:
get:
description: The first event is "snapshot" with the full state, then "chain.switched"
and "target.state" events.
produces:
- text/event-stream
responses:
"200":
description: OK
summary: Stream failover events (server-sent events)
tags:
- failover
/api/fine-tuning/status:
get:
description: Returns model_exports=false when this instance does not share the
models path of the add-on owner. The value is the same as the model_exports
key of GET /api/features.
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/localai.ModelExportsStatus'
"503":
description: add-ons are off or the owner is not reachable
schema:
additionalProperties: true
type: object
summary: Report whether model exports are allowed
tags:
- fine-tuning
- quantization
/api/instructions:
get:
description: Returns a compact list of instruction areas with descriptions and
URLs for detailed guides
produces:
- application/json
responses:
"200":
description: instructions list with hint
schema:
additionalProperties: true
type: object
summary: List available API instruction areas
tags:
- instructions
/api/instructions/{name}:
get:
description: Returns a markdown guide (default) or filtered OpenAPI fragment
(format=json) for a named instruction
parameters:
- description: Instruction name (e.g. chat-inference, config-management)
in: path
name: name
required: true
type: string
- description: 'Response format: json for OpenAPI fragment, omit for markdown'
in: query
name: format
type: string
produces:
- application/json
- text/markdown
responses:
"200":
description: instruction documentation
schema:
$ref: '#/definitions/localai.APIInstructionResponse'
"404":
description: instruction not found
schema:
additionalProperties:
type: string
type: object
summary: Get an instruction's API guide or OpenAPI fragment
tags:
- instructions
/api/library/sources:
get:
description: 'Every library source of the add-on, backend and model kinds, with
its state: kind, id, name, url, enabled (what the host does with it), default
(shipped), removed (a default the user removed; a tombstone), suspended (a
default while the official libraries are off), the conflict message when it
clashes with another source, and the last fetch state when there is one. Administrators
only.'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/localai.LibrarySourcesResponse'
"503":
description: 'on a frontend: the add-on owner is not reachable, does not
serve library calls, or runs on another platform; the message says which'
schema:
$ref: '#/definitions/schema.ErrorResponse'
summary: List the library sources
tags:
- library
post:
consumes:
- application/json
description: Adds a source of your own. kind is addon, backend or model; format
is library (default) or gallery. The id is derived from the name or URL when
it is empty. A source with the same kind and URL is refused (409), as is a
taken id. Administrators only.
produces:
- application/json
responses:
"201":
description: Created
schema:
$ref: '#/definitions/library.Info'
"503":
description: 'on a frontend: the add-on owner is not reachable, does not
serve library calls, or runs on another platform; the message says which'
schema:
$ref: '#/definitions/schema.ErrorResponse'
summary: Add a library source
tags:
- library
/api/library/sources/{id}:
delete:
description: 'A source of your own is deleted. A shipped default is not: it
stays as a tombstone (removed true), so it does not come back at the next
start; enabling it brings it back. Administrators only.'
parameters:
- description: Source id
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
additionalProperties: true
type: object
"503":
description: 'on a frontend: the add-on owner is not reachable, does not
serve library calls, or runs on another platform; the message says which'
schema:
$ref: '#/definitions/schema.ErrorResponse'
summary: Remove a library source
tags:
- library
put:
consumes:
- application/json
description: Replaces the mirrors of a model or backend source; an empty list
clears them. Each mirror is an http(s), github:, oci:// or file:// address.
Administrators only.
parameters:
- description: Source id
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/library.Info'
"503":
description: 'on a frontend: the add-on owner is not reachable, does not
serve library calls, or runs on another platform; the message says which'
schema:
$ref: '#/definitions/schema.ErrorResponse'
summary: Change the mirrors of a library source
tags:
- library
/api/library/sources/{id}/disable:
post:
description: Enabling a removed default brings it back. Administrators only.
parameters:
- description: Source id
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/library.Info'
"503":
description: 'on a frontend: the add-on owner is not reachable, does not
serve library calls, or runs on another platform; the message says which'
schema:
$ref: '#/definitions/schema.ErrorResponse'
summary: Turn a library source on or off
tags:
- library
/api/library/sources/{id}/enable:
post:
description: Enabling a removed default brings it back. Administrators only.
parameters:
- description: Source id
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/library.Info'
"503":
description: 'on a frontend: the add-on owner is not reachable, does not
serve library calls, or runs on another platform; the message says which'
schema:
$ref: '#/definitions/schema.ErrorResponse'
summary: Turn a library source on or off
tags:
- library
/api/models/{id}/load-cancel:
post:
consumes:
- application/json
description: Cancels the load attempt named by `job_id` and stops its remote
work. 200 means the attempt is gone or the worker confirmed the stop. 202
means the cancel is recorded and the stop is pending; the model is released
after `retry_after` seconds regardless. 409 means a different attempt is current
and carries its `current_job_id`. Repeating the call is safe and does not
extend the hold.
parameters:
- description: Model ID
in: path
name: id
required: true
type: string
- description: The exact attempt to cancel
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.ModelLoadCancelRequest'
produces:
- application/json
responses:
"200":
description: Stopped, or no such load any more
schema:
$ref: '#/definitions/schema.ModelLoadCancelResponse'
"202":
description: Cancel recorded; stop pending
schema:
$ref: '#/definitions/schema.ModelLoadCancelResponse'
"400":
description: Bad Request
schema:
$ref: '#/definitions/schema.ErrorResponse'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/schema.ErrorResponse'
"403":
description: Forbidden
schema:
$ref: '#/definitions/schema.ErrorResponse'
"404":
description: Unknown model
schema:
$ref: '#/definitions/schema.ErrorResponse'
"409":
description: A different attempt is current
schema:
$ref: '#/definitions/schema.ModelLoadCancelResponse'
summary: Cancel one distributed model load.
tags:
- models
/api/models/{id}/load-status:
get:
description: 'Returns the live state of a distributed cold load: job id, phase,
node, byte progress, ETA, lease freshness, and for a failed attempt the cause,
whether the stop is pending and when the model is released. 404 means no load
exists for the model. A database error is 503, never an empty answer. This
is the same `loading` object the 503 response carries while a model is still
staging.'
parameters:
- description: Model ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: Live load progress
schema:
$ref: '#/definitions/schema.ModelLoadingStatus'
"404":
description: No load is running for this model
schema:
$ref: '#/definitions/schema.ErrorResponse'
"503":
description: The job table could not be read
schema:
$ref: '#/definitions/schema.ErrorResponse'
summary: Report the progress of an in-flight model load.
tags:
- models
/api/models/{name}/{action}:
put:
description: Enable or disable a model from being loaded on demand. Disabled
models remain installed but cannot be loaded.
parameters:
- description: Model name
in: path
name: name
required: true
type: string
- description: 'Action: ''enable'' or ''disable'''
in: path
name: action
required: true
type: string
responses:
"200":
description: OK
schema:
$ref: '#/definitions/localai.ModelResponse'
"400":
description: Bad Request
schema:
$ref: '#/definitions/localai.ModelResponse'
"404":
description: Not Found
schema:
$ref: '#/definitions/localai.ModelResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/localai.ModelResponse'
summary: Toggle model enabled/disabled status
tags:
- config
/api/models/config-json/{name}:
patch:
consumes:
- application/json
description: Deep-merges the JSON patch body into the existing model config
parameters:
- description: Model name
in: path
name: name
required: true
type: string
produces:
- application/json
responses:
"200":
description: success message
schema:
additionalProperties: true
type: object
summary: Partially update a model configuration
tags:
- config
/api/models/config-metadata:
get:
description: Returns config field metadata. Use ?section=<id> to filter by section,
or omit for a section index.
parameters:
- description: Section ID to filter (e.g. 'general', 'llm', 'parameters') or
'all' for everything
in: query
name: section
type: string
produces:
- application/json
responses:
"200":
description: Section index or filtered field metadata
schema:
additionalProperties: true
type: object
summary: List model configuration field metadata
tags:
- config
/api/models/config-metadata/autocomplete/{provider}:
get:
description: Returns runtime-resolved values for dynamic providers (backends,
models)
parameters:
- description: Provider name (backends, models, models:chat, models:tts, models:transcript,
models:vad)
in: path
name: provider
required: true
type: string
produces:
- application/json
responses:
"200":
description: values array
schema:
additionalProperties: true
type: object
summary: Get dynamic autocomplete values for a config field
tags:
- config
/api/models/storage:
get:
description: Per-model disk usage, shared-file relations and missing references
under the models path
produces:
- application/json
responses:
"200":
description: storage report
schema:
$ref: '#/definitions/gallery.StorageIndex'
summary: Report model storage usage on disk
tags:
- models
/api/models/toggle-pinned/{name}/{action}:
put:
description: Pin or unpin a model. Pinned models stay loaded and are excluded
from automatic eviction.
parameters:
- description: Model name
in: path
name: name
required: true
type: string
- description: 'Action: ''pin'' or ''unpin'''
in: path
name: action
required: true
type: string
responses:
"200":
description: OK
schema:
$ref: '#/definitions/localai.ModelResponse'
"400":
description: Bad Request
schema:
$ref: '#/definitions/localai.ModelResponse'
"404":
description: Not Found
schema:
$ref: '#/definitions/localai.ModelResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/localai.ModelResponse'
summary: Toggle model pinned status
tags:
- config
/api/models/vram-estimate:
post:
consumes:
- application/json
description: Estimates VRAM based on model weight files at multiple context
sizes
parameters:
- description: VRAM estimation parameters
in: body
name: request
required: true
schema:
$ref: '#/definitions/modeladmin.VRAMRequest'
produces:
- application/json
responses:
"200":
description: VRAM estimate
schema:
$ref: '#/definitions/modeladmin.VRAMResponse'
summary: Estimate VRAM usage for a model
tags:
- config
/api/motion/sessions:
post:
consumes:
- application/json
parameters:
- description: Model, output profile and source clock origin
in: body
name: request
required: true
schema:
$ref: '#/definitions/localai.MotionSessionRequest'
produces:
- application/json
responses:
"201":
description: Created
schema:
$ref: '#/definitions/localai.MotionSessionInfo'
summary: Create a motion capture session
tags:
- motion
/api/motion/sessions/{id}:
delete:
parameters:
- description: Session ID
in: path
name: id
required: true
type: string
responses:
"204":
description: No Content
summary: Close a motion session
tags:
- motion
get:
parameters:
- description: Session ID
in: path
name: id
required: true
type: string
responses:
"200":
description: OK
schema:
$ref: '#/definitions/localai.MotionSessionInfo'
summary: Get motion session status
tags:
- motion
/api/motion/sessions/{id}/poses:
get:
parameters:
- description: Session ID
in: path
name: id
required: true
type: string
responses:
"101":
description: Switching Protocols
summary: Stream motion frames and poses over a duplex WebSocket
tags:
- motion
/api/motion/sessions/{id}/tickets:
post:
consumes:
- application/json
parameters:
- description: Session ID
in: path
name: id
required: true
type: string
- description: Browser origin
in: body
name: request
required: true
schema:
$ref: '#/definitions/localai.MotionTicketRequest'
produces:
- application/json
responses:
"201":
description: Created
schema:
$ref: '#/definitions/auth.WebSocketTicketResponse'
summary: Issue a motion WebSocket ticket (30 seconds, single use)
tags:
- motion
/api/nodes/{id}/max-replicas-per-model:
delete:
parameters:
- description: Node ID
in: path
name: id
required: true
type: string
responses:
"200":
description: OK
schema:
additionalProperties:
type: boolean
type: object
"404":
description: node not found
schema:
additionalProperties: true
type: object
summary: Reset a node's max replicas per model to the worker default
tags:
- Nodes
put:
parameters:
- description: Node ID
in: path
name: id
required: true
type: string
- description: New value
in: body
name: request
required: true
schema:
$ref: '#/definitions/localai.UpdateMaxReplicasPerModelRequest'
responses:
"200":
description: OK
schema:
additionalProperties:
type: integer
type: object
"400":
description: value must be >= 1
schema:
additionalProperties: true
type: object
"404":
description: node not found
schema:
additionalProperties: true
type: object
summary: Update a node's max replicas per model
tags:
- Nodes
/api/nodes/{id}/vram-budget:
delete:
parameters:
- description: Node ID
in: path
name: id
required: true
type: string
responses:
"200":
description: OK
schema:
additionalProperties:
type: boolean
type: object
"404":
description: node not found
schema:
additionalProperties: true
type: object
summary: Reset a node's VRAM budget to the worker default
tags:
- Nodes
put:
parameters:
- description: Node ID
in: path
name: id
required: true
type: string
- description: New value (\
in: body
name: request
required: true
schema:
$ref: '#/definitions/localai.UpdateVRAMBudgetRequest'
responses:
"200":
description: OK
schema:
additionalProperties:
type: string
type: object
"400":
description: invalid budget
schema:
additionalProperties: true
type: object
"404":
description: node not found
schema:
additionalProperties: true
type: object
summary: Update a node's VRAM allocation budget
tags:
- Nodes
/api/nodes/models:
get:
responses:
"200":
description: OK
schema:
items:
$ref: '#/definitions/nodes.NodeModel'
type: array
summary: List all loaded models cluster-wide
tags:
- Nodes
/api/p2p:
get:
responses:
"200":
description: Response
schema:
items:
$ref: '#/definitions/schema.P2PNodesResponse'
type: array
summary: Returns available P2P nodes
tags:
- p2p
/api/p2p/token:
get:
responses:
"200":
description: Response
schema:
type: string
summary: Show the P2P token
tags:
- p2p
/api/pii/analyze:
post:
description: 'Runs the configured PII detectors (NER and/or pattern tiers) over
the supplied text and returns the matched entity spans with the policy action
that would fire. Detection only — the text is not modified and no block is
enforced. Select detectors explicitly via `detectors`, or pass a consuming
`model` to use its effective policy: the model''s own `pii.detectors`, else
the instance-wide `pii_default_detectors`. A model with PII disabled, or enabled
with nothing to scan with, is a 400. The raw matched value is never returned;
admins may set `reveal:true` for the audit hash prefix.'
parameters:
- description: text + detector selection
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.PIIAnalyzeRequest'
responses:
"200":
description: Detected entities
schema:
$ref: '#/definitions/schema.PIIAnalyzeResponse'
summary: Detect PII entities in a string (no mutation).
tags:
- pii
/api/pii/redact:
post:
description: 'Runs the configured PII detectors over the text and applies each
detector model''s policy: masked spans are replaced with `[REDACTED:<id>]`,
allow spans pass through, and a single block action causes a 400 (type `pii_blocked`)
carrying the offending entities — the text is never returned in that case.
Select detectors via `detectors`, or a consuming `model`''s effective policy
(its own `pii.detectors`, else the instance-wide `pii_default_detectors`;
PII must be enabled on the model). Records audit events (origin `pii_redact`)
visible at /api/pii/events.'
parameters:
- description: text + detector selection
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.PIIAnalyzeRequest'
responses:
"200":
description: Redacted text + entities
schema:
$ref: '#/definitions/schema.PIIRedactResponse'
summary: Redact PII in a string by applying the configured policy.
tags:
- pii
/api/quantization/status:
get:
description: Returns model_exports=false when this instance does not share the
models path of the add-on owner. The value is the same as the model_exports
key of GET /api/features.
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/localai.ModelExportsStatus'
"503":
description: add-ons are off or the owner is not reachable
schema:
additionalProperties: true
type: object
summary: Report whether model imports are allowed
tags:
- fine-tuning
- quantization
/api/router/{name}/corpus:
delete:
parameters:
- description: router model name
in: path
name: name
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/schema.RouterCorpusClearResponse'
"400":
description: Bad Request
schema:
additionalProperties:
type: string
type: object
"404":
description: Not Found
schema:
additionalProperties:
type: string
type: object
"500":
description: Internal Server Error
schema:
additionalProperties:
type: string
type: object
summary: Clear a router's KNN corpus
tags:
- router
post:
consumes:
- application/json
parameters:
- description: router model name
in: path
name: name
required: true
type: string
- description: labelled exemplars
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.RouterCorpusAddRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/schema.RouterCorpusAddResponse'
"400":
description: Bad Request
schema:
additionalProperties:
type: string
type: object
"404":
description: Not Found
schema:
additionalProperties:
type: string
type: object
"500":
description: Internal Server Error
schema:
additionalProperties:
type: string
type: object
summary: Seed the KNN routing corpus with labelled example prompts
tags:
- router
/api/router/{name}/corpus/stats:
get:
parameters:
- description: router model name
in: path
name: name
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/schema.RouterCorpusStatsResponse'
"400":
description: Bad Request
schema:
additionalProperties:
type: string
type: object
"404":
description: Not Found
schema:
additionalProperties:
type: string
type: object
"500":
description: Internal Server Error
schema:
additionalProperties:
type: string
type: object
summary: Inspect a router's KNN corpus (label counts only, never texts)
tags:
- router
/api/router/decide:
post:
consumes:
- application/json
parameters:
- description: decide params
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.RouterDecideRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/schema.RouterDecideResponse'
"400":
description: Bad Request
schema:
additionalProperties:
type: string
type: object
"404":
description: Not Found
schema:
additionalProperties:
type: string
type: object
"500":
description: Internal Server Error
schema:
additionalProperties:
type: string
type: object
"503":
description: Service Unavailable
schema:
additionalProperties:
type: string
type: object
summary: Classify a prompt against a router model's policies (decision oracle)
tags:
- router
/api/traces:
get:
description: Returns a bounded, newest-first page of captured API exchange traces.
Request and response bodies plus headers are omitted unless full=true; fetch
them per-trace from /api/traces/{id}. Paging metadata is returned in the X-Total-Count,
X-Trace-Offset and X-Trace-Limit headers.
parameters:
- description: Maximum entries to return (default 50, max 1000, 0 for all)
in: query
name: limit
type: integer
- description: Number of entries to skip (default 0)
in: query
name: offset
type: integer
- description: Include request/response bodies and headers (default false)
in: query
name: full
type: boolean
produces:
- application/json
responses:
"200":
description: Traced API exchanges
schema:
additionalProperties: true
type: object
summary: List API request/response traces
tags:
- monitoring
/api/traces/{id}:
get:
description: Returns a single captured API exchange, including the request and
response bodies omitted from the list response
parameters:
- description: Trace ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: Traced API exchange
schema:
additionalProperties: true
type: object
"404":
description: Trace not found
schema:
$ref: '#/definitions/schema.ErrorResponse'
summary: Get one API trace
tags:
- monitoring
/api/traces/clear:
post:
description: Removes all captured API request/response traces from the buffer
responses:
"204":
description: Traces cleared
summary: Clear API traces
tags:
- monitoring
/api/traces/summary:
get:
description: Returns request, failure and latency totals over a recent window,
plus a bucketed series for sparklines. Exists so callers wanting three numbers
do not have to fetch the whole trace list and count it themselves.
parameters:
- description: Window in hours (default 24, max 168)
in: query
name: hours
type: integer
produces:
- application/json
responses:
"200":
description: Counted trace totals
schema:
$ref: '#/definitions/middleware.TraceSummary'
summary: Summarize recent API traces
tags:
- monitoring
/api/voice-profiles:
get:
description: List saved voice-cloning references without exposing filesystem
paths.
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/localai.VoiceProfileListResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/schema.ErrorResponse'
summary: List voice profiles
tags:
- audio
- voice-profiles
post:
consumes:
- multipart/form-data
- application/json
description: Save a consent-confirmed PCM WAV reference clip and exact transcript
for voice cloning. Admin-only.
parameters:
- description: Display name
in: formData
name: name
required: true
type: string
- description: Optional description
in: formData
name: description
type: string
- description: Optional language tag
in: formData
name: language
type: string
- description: Exact transcript of the reference clip
in: formData
name: transcript
required: true
type: string
- description: Confirms authorization to clone the voice
in: formData
name: consent_confirmed
required: true
type: boolean
- description: 16-bit PCM WAV, preferably mono 24 kHz, 1-120 seconds, up to
50 MiB
in: formData
name: audio
required: true
type: file
produces:
- application/json
responses:
"201":
description: Created
schema:
$ref: '#/definitions/voiceprofile.Profile'
"400":
description: Bad Request
schema:
$ref: '#/definitions/schema.ErrorResponse'
"413":
description: Request Entity Too Large
schema:
$ref: '#/definitions/schema.ErrorResponse'
summary: Create a voice profile
tags:
- audio
- voice-profiles
/api/voice-profiles/{id}:
delete:
description: Permanently remove a saved voice-cloning profile. Admin-only.
parameters:
- description: Voice profile UUID
in: path
name: id
required: true
type: string
responses:
"204":
description: No Content
"404":
description: Not Found
schema:
$ref: '#/definitions/schema.ErrorResponse'
summary: Delete a voice profile
tags:
- audio
- voice-profiles
/api/voice-profiles/{id}/audio:
get:
description: Stream the saved reference WAV for an authenticated TTS user.
parameters:
- description: Voice profile UUID
in: path
name: id
required: true
type: string
produces:
- audio/x-wav
responses:
"200":
description: OK
schema:
type: string
"404":
description: Not Found
schema:
$ref: '#/definitions/schema.ErrorResponse'
summary: Preview voice profile audio
tags:
- audio
- voice-profiles
/audio/transform:
post:
consumes:
- multipart/form-data
description: Runs an audio-in / audio-out transform conditioned on an optional
auxiliary reference signal. Concrete transforms include AEC + noise suppression
+ dereverberation (LocalVQE), voice conversion (reference = target speaker),
and pitch shifting. The backend determines the operation; pass model-specific
tuning via repeated `params[<key>]=<value>` form fields.
parameters:
- description: model
in: formData
name: model
required: true
type: string
- description: primary input audio file
in: formData
name: audio
required: true
type: file
- description: auxiliary reference audio (loopback for AEC, target voice for
conversion, etc.)
in: formData
name: reference
type: file
- description: wav | mp3 | ogg | flac
in: formData
name: response_format
type: string
- description: desired output sample rate in Hz; omit for the backend's own
rate, otherwise 8000-192000
in: formData
name: sample_rate
type: integer
produces:
- audio/x-wav
responses:
"200":
description: transformed audio file
schema:
type: string
summary: Transform audio (echo cancellation, noise suppression, voice conversion,
etc.)
tags:
- audio
/audio/transformations:
post:
consumes:
- multipart/form-data
description: Runs an audio-in / audio-out transform conditioned on an optional
auxiliary reference signal. Concrete transforms include AEC + noise suppression
+ dereverberation (LocalVQE), voice conversion (reference = target speaker),
and pitch shifting. The backend determines the operation; pass model-specific
tuning via repeated `params[<key>]=<value>` form fields.
parameters:
- description: model
in: formData
name: model
required: true
type: string
- description: primary input audio file
in: formData
name: audio
required: true
type: file
- description: auxiliary reference audio (loopback for AEC, target voice for
conversion, etc.)
in: formData
name: reference
type: file
- description: wav | mp3 | ogg | flac
in: formData
name: response_format
type: string
- description: desired output sample rate in Hz; omit for the backend's own
rate, otherwise 8000-192000
in: formData
name: sample_rate
type: integer
produces:
- audio/x-wav
responses:
"200":
description: transformed audio file
schema:
type: string
summary: Transform audio (echo cancellation, noise suppression, voice conversion,
etc.)
tags:
- audio
/audio/transformations/stream:
get:
description: 'Streams binary PCM frames in (interleaved stereo: ch0=audio, ch1=reference)
and out (mono). The model must support the audio_transform use case. Any-to-any
realtime_audio models use the OpenAI Realtime API instead. The first message
must be a JSON `session.update` envelope describing model + sample format
+ frame size + backend params. Server emits binary PCM on the same cadence.'
responses: {}
summary: Bidirectional realtime audio transform over WebSocket.
tags:
- audio
/backend/load:
post:
consumes:
- application/json
description: Loads the named model (or, for a realtime pipeline, all of its
sub-models) into memory so subsequent requests pay no cold-start cost. The
inverse of /backend/shutdown.
parameters:
- description: Model to load
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.ModelLoadRequest'
produces:
- application/json
responses:
"200":
description: Model loaded
schema:
$ref: '#/definitions/schema.ModelLoadResponse'
"400":
description: Missing model name
schema:
$ref: '#/definitions/schema.ModelLoadResponse'
"500":
description: Load failed (Loaded lists any sub-models that did load)
schema:
$ref: '#/definitions/schema.ModelLoadResponse'
summary: Pre-load a model into memory
tags:
- monitoring
/backend/monitor:
get:
parameters:
- description: Name of the model to monitor
in: query
name: model
required: true
type: string
responses:
"200":
description: Response
schema:
$ref: '#/definitions/proto.StatusResponse'
summary: Backend monitor endpoint
tags:
- monitoring
/backend/shutdown:
post:
parameters:
- description: Backend statistics request
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.BackendMonitorRequest'
responses: {}
summary: Backend shutdown endpoint
tags:
- monitoring
/backends:
get:
responses:
"200":
description: Response
schema:
items:
$ref: '#/definitions/gallery.GalleryBackend'
type: array
summary: List all Backends
tags:
- backends
/backends/apply:
post:
parameters:
- description: query params
in: body
name: request
required: true
schema:
$ref: '#/definitions/localai.GalleryBackend'
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.BackendResponse'
"403":
description: Backend installation is disabled on this server (code backend_install_disabled)
schema:
additionalProperties: true
type: object
"409":
description: Hardware-specific build in distributed mode (code concrete_backend_requires_target)
schema:
additionalProperties: true
type: object
summary: Install backends to LocalAI.
tags:
- backends
/backends/available:
get:
responses:
"200":
description: Response
schema:
items:
$ref: '#/definitions/gallery.GalleryBackend'
type: array
summary: List all available Backends
tags:
- backends
/backends/delete/{name}:
post:
parameters:
- description: Backend name
in: path
name: name
required: true
type: string
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.BackendResponse'
summary: delete backends from LocalAI.
tags:
- backends
/backends/galleries:
get:
responses:
"200":
description: Response
schema:
items:
$ref: '#/definitions/config.Gallery'
type: array
summary: List all Galleries
tags:
- backends
/backends/jobs:
get:
responses:
"200":
description: Response
schema:
additionalProperties:
$ref: '#/definitions/galleryop.OpStatus'
type: object
summary: Returns all the jobs status progress
tags:
- backends
/backends/jobs/{uuid}:
get:
responses:
"200":
description: Response
schema:
$ref: '#/definitions/galleryop.OpStatus'
summary: Returns the job status
tags:
- backends
/backends/known:
get:
responses:
"200":
description: Response
schema:
items:
$ref: '#/definitions/schema.KnownBackend'
type: array
summary: List all known Backends (importer registry + curated pref-only + installed-on-disk)
tags:
- backends
/backends/library/install:
post:
parameters:
- description: library, backend name and version
in: body
name: request
required: true
schema:
$ref: '#/definitions/localai.BackendLibraryInstallRequest'
responses:
"200":
description: the job; read its status at the status URL
schema:
$ref: '#/definitions/schema.BackendResponse'
"400":
description: the request does not name an entry
schema:
$ref: '#/definitions/schema.ErrorResponse'
"409":
description: the same backend is already being installed
schema:
$ref: '#/definitions/schema.ErrorResponse'
"503":
description: 'on a frontend: the add-on owner is not reachable, does not
serve library calls, or runs on another platform; the message says which'
schema:
$ref: '#/definitions/schema.ErrorResponse'
summary: Install a backend from a library entry on this node.
tags:
- backends
/backends/library/updates:
get:
responses:
"200":
description: updates
schema:
additionalProperties:
items:
$ref: '#/definitions/backendlib.Update'
type: array
type: object
"503":
description: 'on a frontend: the add-on owner is not reachable, does not
serve library calls, or runs on another platform; the message says which'
schema:
$ref: '#/definitions/schema.ErrorResponse'
summary: List the installed library backends with a newer build in their library.
tags:
- backends
/backends/upgrade/{name}:
post:
parameters:
- description: Backend name
in: path
name: name
required: true
type: string
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.BackendResponse'
"403":
description: Backend installation is disabled on this server (code backend_install_disabled)
schema:
additionalProperties: true
type: object
summary: Upgrade a backend
tags:
- backends
/backends/upgrades:
get:
responses:
"200":
description: Response
schema:
additionalProperties:
$ref: '#/definitions/gallery.UpgradeInfo'
type: object
summary: Get available backend upgrades
tags:
- backends
/backends/upgrades/check:
post:
responses:
"200":
description: Response
schema:
additionalProperties:
$ref: '#/definitions/gallery.UpgradeInfo'
type: object
summary: Force backend upgrade check
tags:
- backends
/branding/asset/{kind}:
get:
description: Serves the admin-uploaded logo, horizontal logo, or favicon. 404
when no override is set.
parameters:
- description: 'Asset kind: logo, logo_horizontal, or favicon'
in: path
name: kind
required: true
type: string
produces:
- image/*
responses:
"200":
description: OK
"404":
description: Not Found
summary: Serve a custom branding asset
tags:
- branding
/metrics:
get:
produces:
- text/plain
responses:
"200":
description: Prometheus metrics
schema:
type: string
summary: Prometheus metrics endpoint
tags:
- monitoring
/models/apply:
post:
parameters:
- description: query params
in: body
name: request
required: true
schema:
$ref: '#/definitions/localai.GalleryModel'
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.GalleryResponse'
"409":
description: The model's backend is not installed and backend installation
is disabled (code backend_not_installed)
schema:
additionalProperties: true
type: object
summary: Install models to LocalAI.
tags:
- models
/models/available:
get:
responses:
"200":
description: Response
schema:
items:
$ref: '#/definitions/gallery.Metadata'
type: array
summary: List installable models.
tags:
- models
/models/delete/{name}:
post:
parameters:
- description: Model name
in: path
name: name
required: true
type: string
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.GalleryResponse'
summary: delete models to LocalAI.
tags:
- models
/models/galleries:
get:
responses:
"200":
description: Response
schema:
items:
$ref: '#/definitions/config.Gallery'
type: array
summary: List all Galleries
tags:
- models
/models/import:
post:
consumes:
- application/json
description: |-
Writes the posted model configuration. A config referencing
remote assets (download_files entries, URI-valued model/mmproj)
is enqueued on the gallery job queue and answered with a job id
plus status URL to poll, like a gallery install; a config with
no downloads is written synchronously and answered with a
plain success response. A queued import runs the gallery
installer, which also adds recommended inference defaults the
config leaves unset and installs the backend when automatic
backend installation is enabled; the synchronous path stores
the body as posted.
parameters:
- description: model configuration (YAML or JSON body)
in: body
name: request
required: true
schema:
type: object
produces:
- application/json
responses:
"200":
description: 'remote assets present: job id and status URL'
schema:
$ref: '#/definitions/schema.GalleryResponse'
"400":
description: invalid or incomplete configuration
schema:
$ref: '#/definitions/localai.ModelResponse'
summary: Import a model from a raw YAML or JSON configuration
tags:
- models
/models/jobs:
get:
responses:
"200":
description: Response
schema:
additionalProperties:
$ref: '#/definitions/galleryop.OpStatus'
type: object
summary: Returns all the jobs status progress
tags:
- models
/models/jobs/{uuid}:
get:
responses:
"200":
description: Response
schema:
$ref: '#/definitions/galleryop.OpStatus'
summary: Returns the job status
tags:
- models
/system:
get:
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.SystemInformationResponse'
summary: Show the LocalAI instance information
tags:
- monitoring
/tokenMetrics:
get:
consumes:
- application/json
produces:
- audio/x-wav
responses:
"200":
description: generated audio/wav file
schema:
type: string
summary: Get TokenMetrics for Active Slot.
tags:
- tokenize
/tts:
post:
consumes:
- application/json
parameters:
- description: query params
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.TTSRequest'
produces:
- audio/x-wav
responses:
"200":
description: generated audio/wav file
schema:
type: string
summary: Generates audio from the input text.
tags:
- audio
/v1/audio/classification:
post:
consumes:
- multipart/form-data
parameters:
- description: model
in: formData
name: model
required: true
type: string
- description: audio file
in: formData
name: file
required: true
type: file
- description: number of top tags to return (0 = backend default)
in: formData
name: top_k
type: integer
- description: drop tags scoring below this value
in: formData
name: threshold
type: number
responses:
"200":
description: OK
schema:
$ref: '#/definitions/schema.SoundClassificationResult'
summary: Classify sound events in audio (audio tagging).
tags:
- audio
/v1/audio/diarization:
post:
consumes:
- multipart/form-data
- application/json
description: JSON accepts model, file (raw base64 audio), include_text, include_speaker_profiles,
include_sounds and response_format. Profiles require voice-recognition permission
and json or verbose_json; unsupported backends return 501.
parameters:
- description: model
in: formData
name: model
required: true
type: string
- description: audio file
in: formData
name: file
required: true
type: file
- description: exact speaker count (>0 forces; 0 = auto)
in: formData
name: num_speakers
type: integer
- description: lower bound when auto-detecting
in: formData
name: min_speakers
type: integer
- description: upper bound when auto-detecting
in: formData
name: max_speakers
type: integer
- description: clustering distance threshold when num_speakers is unknown
in: formData
name: clustering_threshold
type: number
- description: discard segments shorter than this (seconds)
in: formData
name: min_duration_on
type: number
- description: merge gaps shorter than this (seconds)
in: formData
name: min_duration_off
type: number
- description: audio language hint (only meaningful for backends that bundle
ASR)
in: formData
name: language
type: string
- description: export portable biometric profiles (voice-recognition permission;
JSON formats only)
in: formData
name: include_speaker_profiles
type: boolean
- description: include per-segment transcript when the backend supports it
in: formData
name: include_text
type: boolean
- description: include closed sound events (start, end, label, confidence) when
the model has a sound_model companion; otherwise 501 include_sounds_unsupported
(JSON formats only)
in: formData
name: include_sounds
type: boolean
- description: json (default), verbose_json, or rttm
in: formData
name: response_format
type: string
responses:
"200":
description: OK
schema:
$ref: '#/definitions/schema.DiarizationResult'
summary: Identify speakers in audio (who spoke when).
tags:
- audio
/v1/audio/speech:
post:
consumes:
- application/json
parameters:
- description: query params
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.TTSRequest'
produces:
- audio/x-wav
responses:
"200":
description: generated audio/wav file
schema:
type: string
summary: Generates audio from the input text.
tags:
- audio
/v1/audio/transcriptions:
post:
consumes:
- multipart/form-data
parameters:
- description: model
in: formData
name: model
required: true
type: string
- description: file
in: formData
name: file
required: true
type: file
- description: sampling temperature
in: formData
name: temperature
type: number
- collectionFormat: csv
description: timestamp granularities (word, segment)
in: formData
items:
type: string
name: timestamp_granularities
type: array
- description: stream partial results as SSE
in: formData
name: stream
type: boolean
responses:
"200":
description: Response
schema:
additionalProperties:
type: string
type: object
summary: Transcribes audio into the input language.
tags:
- audio
/v1/audio/voices:
get:
description: List named voices and their language and gender metadata. Use the
optional model query parameter to filter the response.
parameters:
- description: Installed model name
in: query
name: model
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/localai.TTSVoicesResponse'
"404":
description: Not Found
schema:
$ref: '#/definitions/schema.ErrorResponse'
summary: List text-to-speech voices
tags:
- audio
/v1/chat/completions:
post:
parameters:
- description: query params
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.OpenAIRequest'
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.OpenAIResponse'
summary: Generate a chat completions for a given prompt and model.
tags:
- inference
/v1/completions:
post:
parameters:
- description: query params
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.OpenAIRequest'
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.OpenAIResponse'
summary: Generate completions for a given prompt and model.
tags:
- inference
/v1/decisions:
post:
consumes:
- application/json
description: Uses the same local decision and NER execution as SystemOne. Supports
inline images on capable backends; confidence is not OpenAI calibrated.
parameters:
- description: input + questions + model
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.DecisionsRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/schema.DecisionsResponse'
summary: Answer ordered predicate, choice and score questions.
tags:
- systemone
/v1/depth:
post:
parameters:
- description: query params
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.DepthRequest'
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.DepthResponse'
summary: Estimates per-pixel depth (and optionally pose/points) from an image.
tags:
- depth
/v1/detection:
post:
parameters:
- description: query params
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.DetectionRequest'
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.DetectionResponse'
summary: Detects objects in the input image.
tags:
- detection
/v1/detokenize:
post:
parameters:
- description: Request
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.DetokenizeRequest'
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.DetokenizeResponse'
summary: Detokenize the input.
tags:
- tokenize
/v1/edits:
post:
parameters:
- description: query params
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.OpenAIRequest'
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.OpenAIResponse'
summary: OpenAI edit endpoint
tags:
- inference
/v1/embeddings:
post:
parameters:
- description: query params
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.OpenAIRequest'
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.OpenAIResponse'
summary: Get a vector representation of a given input that can be easily consumed
by machine learning models and algorithms.
tags:
- embeddings
/v1/face/analyze:
post:
parameters:
- description: query params
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.FaceAnalyzeRequest'
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.FaceAnalyzeResponse'
summary: Analyze demographic attributes (age, gender, ...) of faces.
tags:
- face-recognition
/v1/face/embed:
post:
parameters:
- description: query params
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.FaceEmbedRequest'
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.FaceEmbedResponse'
summary: Extract a face embedding from an image.
tags:
- face-recognition
/v1/face/forget:
post:
parameters:
- description: query params
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.FaceForgetRequest'
responses:
"204":
description: No Content
summary: Remove a previously-registered face by ID.
tags:
- face-recognition
/v1/face/identify:
post:
parameters:
- description: query params
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.FaceIdentifyRequest'
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.FaceIdentifyResponse'
summary: Identify a face against the registered database (1:N recognition).
tags:
- face-recognition
/v1/face/register:
post:
parameters:
- description: query params
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.FaceRegisterRequest'
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.FaceRegisterResponse'
summary: Register a face for 1:N identification.
tags:
- face-recognition
/v1/face/verify:
post:
parameters:
- description: query params
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.FaceVerifyRequest'
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.FaceVerifyResponse'
summary: Verify that two images depict the same person.
tags:
- face-recognition
/v1/forecast:
post:
parameters:
- description: query params
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.ForecastRequest'
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.ForecastResponse'
summary: Forecasts numeric time series as quantile trajectories.
tags:
- forecast
/v1/images/generations:
post:
parameters:
- description: query params
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.OpenAIRequest'
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.OpenAIResponse'
summary: Creates an image given a prompt.
tags:
- images
/v1/images/inpainting:
post:
consumes:
- multipart/form-data
description: Perform image inpainting. Accepts multipart/form-data with `image`
and `mask` files.
parameters:
- description: Model identifier
in: formData
name: model
required: true
type: string
- description: Text prompt guiding the generation
in: formData
name: prompt
required: true
type: string
- description: Number of inference steps (default 25)
in: formData
name: steps
type: integer
- description: Original image file
in: formData
name: image
required: true
type: file
- description: Mask image file (white = area to inpaint)
in: formData
name: mask
required: true
type: file
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/schema.OpenAIResponse'
"400":
description: Bad Request
schema:
additionalProperties:
type: string
type: object
"500":
description: Internal Server Error
schema:
additionalProperties:
type: string
type: object
summary: Image inpainting
tags:
- images
/v1/images/upscale:
post:
consumes:
- multipart/form-data
description: Upscale an image using a specified model (e.g. stable-diffusion-x4-upscaler).
Accepts multipart/form-data.
parameters:
- description: Upscaler model identifier (e.g. stable-diffusion-x4-upscaler)
in: formData
name: model
required: true
type: string
- description: Input image file
in: formData
name: image
required: true
type: file
- description: 'Upscale factor: integer from 1 to 16; must match the model native
scale'
in: formData
name: scale
required: true
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/schema.OpenAIResponse'
"400":
description: Bad Request
schema:
additionalProperties:
type: string
type: object
"500":
description: Internal Server Error
schema:
additionalProperties:
type: string
type: object
summary: Image upscaling
tags:
- images
/v1/mcp/chat/completions:
post:
parameters:
- description: query params
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.OpenAIRequest'
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.OpenAIResponse'
summary: MCP chat completions with automatic tool execution
tags:
- mcp
/v1/messages:
post:
parameters:
- description: query params
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.AnthropicRequest'
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.AnthropicResponse'
summary: Generate a message response for the given messages and model.
tags:
- inference
/v1/models:
get:
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.ModelsDataResponse'
summary: List and describe the various models available in the API.
tags:
- models
/v1/models/capabilities:
get:
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.ModelCapabilitiesResponse'
summary: List available models enriched with capabilities and input/output modalities.
tags:
- models
/v1/moderations:
post:
parameters:
- description: query params
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.ModerationRequest'
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.ModerationResponse'
summary: Classify text for potentially harmful content.
tags:
- moderation
/v1/rerank:
post:
parameters:
- description: query params
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.JINARerankRequest'
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.JINARerankResponse'
summary: Reranks a list of phrases by relevance to a given text query.
tags:
- rerank
/v1/responses:
post:
parameters:
- description: Request body
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.OpenResponsesRequest'
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.ORResponseResource'
summary: Create a response using the Open Responses API
tags:
- inference
/v1/responses/{id}:
get:
description: Retrieve a response by ID. Can be used for polling background responses
or resuming streaming responses.
parameters:
- description: Response ID
in: path
name: id
required: true
type: string
- description: Set to 'true' to resume streaming
in: query
name: stream
type: string
- description: Sequence number to resume from (for streaming)
in: query
name: starting_after
type: integer
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.ORResponseResource'
"400":
description: Bad Request
schema:
additionalProperties: true
type: object
"404":
description: Not Found
schema:
additionalProperties: true
type: object
summary: Get a response by ID
tags:
- inference
/v1/responses/{id}/cancel:
post:
description: Cancel a background response if it's still in progress
parameters:
- description: Response ID
in: path
name: id
required: true
type: string
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.ORResponseResource'
"400":
description: Bad Request
schema:
additionalProperties: true
type: object
"404":
description: Not Found
schema:
additionalProperties: true
type: object
summary: Cancel a response
tags:
- inference
/v1/slots/restore:
post:
description: Loads the prompt cache that a save call returned an ID for into
one slot of a llama-cpp model. The ID must have been issued for this model.
The state is only as fresh as the save. Admin only.
parameters:
- description: Request
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.SlotCacheRequest'
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.SlotCacheResponse'
summary: Restore a slot's prompt cache by ID.
tags:
- inference
/v1/slots/save:
post:
description: Writes the prompt cache (KV state) of one slot of a llama-cpp model
under the directory set by the model's slot_save_path option, and returns
an ID for it. The server issues the ID; the client cannot choose a name or
a path. The server keeps at most 32 saves per model and deletes the oldest
one beyond that. Admin only.
parameters:
- description: Request
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.SlotCacheRequest'
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.SlotCacheResponse'
summary: Save a slot's prompt cache.
tags:
- inference
/v1/sound-generation:
post:
parameters:
- description: query params
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.ElevenLabsSoundGenerationRequest'
responses:
"200":
description: Response
schema:
type: string
summary: Generates audio from the input text.
tags:
- audio
/v1/systemone:
post:
description: 'Runs zero-shot NER over the supplied state and answers each question.
Question types: noul (binary entity presence), choice (pick one option), score
(pick one level).'
parameters:
- description: state + questions
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.SystemOneRequest'
responses:
"200":
description: OK
schema:
$ref: '#/definitions/schema.SystemOneResponse'
summary: Answer structured-extraction questions over state text.
tags:
- systemone
/v1/systemone/permute:
post:
description: Re-runs one choice question under n_perm option orders. Reports
per-order probabilities, argmax stability, and spread.
parameters:
- description: request + question + n_perm + seed
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.SystemOnePermuteRequest'
responses:
"200":
description: OK
schema:
$ref: '#/definitions/schema.SystemOnePermuteResponse'
summary: Re-run a choice question under multiple option orders.
tags:
- systemone
/v1/systemone/separate:
post:
description: Runs N independent NER passes, one per question, against the same
state. Response shape matches /v1/systemone.
parameters:
- description: state + questions
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.SystemOneRequest'
responses:
"200":
description: OK
schema:
$ref: '#/definitions/schema.SystemOneResponse'
summary: Answer each question in a separate NER pass.
tags:
- systemone
/v1/text-to-speech/{voice-id}:
post:
parameters:
- description: Account ID
in: path
name: voice-id
required: true
type: string
- description: query params
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.TTSRequest'
responses:
"200":
description: Response
schema:
type: string
summary: Generates audio from the input text.
tags:
- audio
/v1/tokenMetrics:
get:
consumes:
- application/json
produces:
- audio/x-wav
responses:
"200":
description: generated audio/wav file
schema:
type: string
summary: Get TokenMetrics for Active Slot.
tags:
- tokenize
/v1/tokenize:
post:
parameters:
- description: Request
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.TokenizeRequest'
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.TokenizeResponse'
summary: Tokenize the input.
tags:
- tokenize
/v1/voice/analyze:
post:
parameters:
- description: query params
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.VoiceAnalyzeRequest'
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.VoiceAnalyzeResponse'
summary: Analyze demographic attributes (age, gender, emotion) from a voice
clip.
tags:
- voice-recognition
/v1/voice/embed:
post:
parameters:
- description: query params
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.VoiceEmbedRequest'
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.VoiceEmbedResponse'
summary: Extract a speaker embedding from an audio clip.
tags:
- voice-recognition
/v1/voice/forget:
post:
parameters:
- description: query params
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.VoiceForgetRequest'
responses:
"204":
description: No Content
summary: Remove a previously-registered speaker by ID.
tags:
- voice-recognition
/v1/voice/identify:
post:
parameters:
- description: query params
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.VoiceIdentifyRequest'
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.VoiceIdentifyResponse'
summary: Identify a speaker against the registered database (1:N recognition).
tags:
- voice-recognition
/v1/voice/register:
post:
description: Supply either audio or speaker_profiles plus an explicit numeric
speaker_slot. The selected model must expose matching trusted encoder metadata
for portable enrollment. Registrations are global and ephemeral, with a fresh
ID for each request.
parameters:
- description: query params
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.VoiceRegisterRequest'
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.VoiceRegisterResponse'
summary: Register a speaker for 1:N identification.
tags:
- voice-recognition
/v1/voice/verify:
post:
parameters:
- description: query params
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.VoiceVerifyRequest'
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.VoiceVerifyResponse'
summary: Verify that two audio clips were spoken by the same person.
tags:
- voice-recognition
/vad:
post:
consumes:
- application/json
parameters:
- description: query params
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.VADRequest'
responses:
"200":
description: Response
schema:
$ref: '#/definitions/proto.VADResponse'
summary: Detect voice fragments in an audio stream
tags:
- audio
/video:
post:
parameters:
- description: query params
in: body
name: request
required: true
schema:
$ref: '#/definitions/schema.VideoRequest'
responses:
"200":
description: Response
schema:
$ref: '#/definitions/schema.OpenAIResponse'
summary: Creates a video from a prompt and optional image or audio conditioning.
tags:
- video
/ws/backend-logs/{modelId}:
get:
description: Opens a WebSocket connection for real-time backend log streaming.
Sends an initial batch of existing lines (type "initial"), then streams new
lines as they appear (type "line"). Supports ping/pong keepalive.
parameters:
- description: Model ID
in: path
name: modelId
required: true
type: string
responses: {}
summary: Stream backend logs via WebSocket
tags:
- monitoring
schemes:
- http
- https
securityDefinitions:
BearerAuth:
in: header
name: Authorization
type: apiKey
swagger: "2.0"