github mudler/LocalAI v4.10.0

3 hours ago

🎉 LocalAI 4.10.0 Release! 🚀




LocalAI 4.10.0 is out!

Twenty-eight days and 280 pull requests. The work landed on three fronts: operating a fleet, feeding it models from private sources, and fixing the backends you depend on. A fleet operations dashboard replaces the flat node list with cluster-wide health, capacity, running models, and bulk lifecycle actions. A credentials file lets one credentials.yaml authenticate OCI registries, galleries and direct downloads without scattering tokens across environment variables. And local-ai benchmark measures end-to-end latency and throughput from the CLI.

The ds4 backend had four fixes that together make it reliable on CUDA: the kernels now build for the target architecture, abandoned inference is cancelled, generation boundaries are enforced, and prefilled reasoning is separated from content. Distributed mode gained seven stabilisation fixes across staging, liveness, virtual models and the control-plane database. Four CVEs were patched, enable_thinking=false is now honoured across every text backend, and Apple M5 no longer SIGSEGVs at startup.

Highlights:

  • 📊 Fleet operations dashboard - a real-time cluster overview replacing the flat node list. Aggregate health bands, capacity gauges for VRAM/RAM/CPU/disk, a running-models tab showing replica placement across workers, bulk drain/resume/remove with bounded concurrency, and a slide-out node inspector. Workers now report CPU telemetry at registration and heartbeat.
  • 🔑 Credentials file for private sources - one credentials.yaml authenticates OCI registries, galleries, HTTP downloads and github: URIs. Supports basic auth, bearer tokens and custom headers, with secrets read at use time so rotated K8s secret mounts take effect without restart, and full masking in logs and error messages.
  • 📏 local-ai benchmark CLI command - measures end-to-end latency and throughput against configured text models. Reports min/mean/max latency and completion tokens/sec across warmup and measured runs, with table and JSON output, redirect blocking, and API-key redaction.
  • 🔧 vllm-cpp LoRA fusion at load time - lora_adapters and lora_scales are now consumed by the vllm-cpp video engine, fusing LoRA deltas into DiT weights at engine load. Works for both LTX2.5 and MiniMax-H3 through one generic path.
  • 🌍 Environment variables per model - an env: map in model config injects variables into the backend process environment, so CUDA_VISIBLE_DEVICES or VLLM_CACHE_DIR can be pinned per model without wrapping the backend in a script.
  • 💬 template.system_messages_after_first - agent frameworks that append system instructions mid-conversation no longer crash Qwen3.x models. Late system turns can be merged into the leading system message or forwarded as user turns.
  • 🧠 context_size in /v1/models/capabilities - clients can now read each model's effective context window to budget tokens and truncate prompts without probing the model config out-of-band.
  • 🛡️ Four CVEs patched - ip-address 10.3.1 (CVE-2026-69192), containerd 1.7.32 and 1.7.33 (CVE-2026-46680, CVE-2026-53488), and react-router (GHSA-qwww-vcr4-c8h2).
  • 🍎 Apple M5 SIGSEGV fixed - go-m1cpu bumped to v0.2.2, fixing a segmentation fault on Apple M5 hardware at startup.

Plus a focus mode toggle in chat settings, face enrollment replay for the 1:N registry, a ROCm build of stablediffusion-ggml, in-place editing of distributed scheduling rules, OCI layer download resumption, and 140 new gallery entries.


📊 This release in numbers

Pull requests merged 280
Commits 382
Files changed 633 (+46,550 / -3,316)
Development window 28 days (2026-08-20 to 2026-09-17)
Human contributors 29, of whom 16 first-time
Gallery entries 1,707 to 1,847 (+140)

Where the work landed:

Area Change
core/ +25,773 / -1,993 across 314 files
gallery/ +6,734 / -417
backend/ +4,932 / -433 across 154 files
pkg/ +4,392 / -91 across 55 files
docs/ +2,526 / -101 across 48 files
swagger/ +322

📌 TL;DR

Area Summary
📊 Fleet dashboard The Nodes page is rewritten as a fleet operations dashboard. A ClusterOverview shows health bands (healthy/draining/attention) and capacity gauges for VRAM, RAM, CPU and disk derived from the single GET /api/nodes response. A NodeFleetTable offers sortable, groupable, paginated rows with checkbox selection across filters and pages, and bulk Drain/Resume/Remove with bounded concurrency (limit 8). A Running Models tab shows all loaded replicas on healthy workers grouped by model, with replica count, node count, in-flight requests and backend types. Slide-out inspectors for nodes and models provide detail and drill-down. Workers now report cpu_logical_cores, cpu_usage_percent and cpu_load_1 at registration and heartbeat. Lifecycle transitions are atomic: MarkDraining flips status and deletes model records in one transaction, ResumeNode is conditional (draining to healthy only), and HTTP endpoints return proper 404/409 instead of generic 500.
🔑 Credentials file --credentials-file / LOCALAI_CREDENTIALS_FILE loads a YAML list of rules, each matching a URL prefix and carrying one auth type: basic (username + password/password_env/password_file), bearer (bearer/bearer_env/bearer_file), or custom header (header.name + header.value/_env/_file). OCI registries consult the store first, then docker config. HTTP downloads, galleries and github: URIs authenticate through a RoundTripper that clones the request per redirect hop, so a cross-host redirect never carries the credential. Secrets are read at use time, not load time, so a rotated K8s secret mount takes effect without restart. Credential and Store implement String, GoString and LogValue so no fmt verb or slog call can print secret material. Unknown YAML keys are errors; match strings with user:token@, ? or # are rejected at load.
📏 CLI benchmark local-ai benchmark MODEL [MODEL ...] sends non-streaming POST /v1/chat/completions requests at temperature:0 with configurable --runs (default 3), --warmup (default 1), --max-tokens (default 128) and --timeout (default 5m). Reports min/mean/max latency and end-to-end completion tokens/sec per model. Output is a table by default or --json for structured data with per-sample latency and nullable token counts. The HTTP client refuses redirects, the API key is redacted from error messages, and the full report is buffered and only written after all models succeed, so a failure leaves no partial output.
🔧 vllm-cpp LoRA fusion The lora_adapters, lora_scales, lora_adapter and lora_scale config fields are now consumed by the vllm-cpp video backend. buildLoraExtras converts them into indexed lora_path/lora_strength key-value pairs (first adapter unsuffixed, subsequent ones _2, _3, ...), packs them via the ABI v18 extras seam, and hands them to vllmVideoEngineLoad. vllm.cpp fuses the LoRA deltas into the DiT weights at load. One generic path serves both LTX2.5 and MiniMax-H3. Adapters are always loaded; per-request prompt-activated LoRA is out of scope.
🌍 Per-model env vars An env: map on the model config is appended to the child process environment after the base env, so model vars override inherited system vars. Delivered through the common process-spawning layer in pkg/model/process.go, so every gRPC backend inherits it with no per-backend wiring. The UI renders an editable key/value map. Model vars take effect only when a model spawns its own backend process, not when it reuses a worker-supervised one.
💬 Late system messages template.system_messages_after_first controls what happens to system-role messages after the leading system block. "merge" folds them into the first system message with a \n\n separator; "user" rewrites them in place to role user; unset passes through. Fixes a Jinja exception (System message must be at the beginning) raised by Qwen3.x tokenizer templates when agent frameworks append system instructions mid-conversation. Runs after stripEmptySystemMessages and before tokenizer-template system_prompt injection.
🧠 context_size exposed /v1/models/capabilities now populates entry.ContextSize with backend.EffectiveContextSize(cfg) when the result is positive, letting clients budget tokens and truncate prompts without probing the model config out-of-band.
🛡️ CVE fixes ip-address to 10.3.1 (CVE-2026-69192), containerd to 1.7.32 (CVE-2026-46680) then 1.7.33 (CVE-2026-53488), react-router to 7.18.2 / 8.3.0 (GHSA-qwww-vcr4-c8h2).
🍎 Apple M5 go-m1cpu bumped to v0.2.2, fixing a SIGSEGV on Apple M5 at startup.
🧠 Models 140 new gallery entries: Qwopus 3.6, OpenResearcher, LFM2.5 DSpark, Qwen3.8 small distills and Flash Next, UI-Mate 27B, Homura 30B, Ornith 1.5 35B and 9B, Granite 4.2, Tiel-Coder 35B, Thomson 1.0 Small, PhoneLLM, WeMM embedding, EXL3 vllm.cpp, Gemma 4 E4B, Orukeet for NeMo speech, and more.

🚀 New Features & Major Enhancements

📊 Fleet operations dashboard

The Nodes page was a flat list of per-node cards. It showed you what was registered but not what the cluster was doing, and every lifecycle action was one node at a time.

The rewrite is a fleet operations dashboard with two tabs and a shared summary poller.

ClusterOverview sits at the top. A health band segments nodes into healthy, draining and attention counts. Capacity gauges show VRAM, RAM, CPU and disk, each reporting how many workers do not report that metric so the number is honest rather than averaged over reporting nodes. An attention queue filters for pending approval, offline/unhealthy, low VRAM, low RAM and low disk, surfacing nodes that need action without double-counting the headline total.

NodeFleetTable is sortable, groupable (by label or type) and paginated at 50 rows per page, with checkbox selection that persists across filters and pages. Bulk Drain, Resume and Remove run with bounded concurrency (limit 8) so a fleet with thousands of registrations is usable. Columns: status pill, address, capacity (VRAM + RAM), CPU, workload and heartbeat. An Approve button appears on pending nodes.

Running models tab. A fleet-wide view of loaded replicas on healthy workers, grouped by model: model name, replica count, node count, in-flight requests, backend types and last used. Per-model Stop shuts down all placements through POST /backend/shutdown {model}, which now fires the remote unloader even when a local process exists, and deduplicates nodes before sending stop messages.

Inspectors. A slide-out NodeInspector shows health, labels, resource bars, CPU, loaded model count, backends (lazy-loaded) and in-flight, with Approve/Drain/Resume actions. A ModelInspector shows replica placement grouped by node, with clickable node names that drill into a NodeInspector.

Workers now report cpu_logical_cores, cpu_usage_percent and cpu_load_1 at registration and heartbeat. The dashboard shows CPU capacity and utilization, with idle cores derived as cpu_logical_cores * (1 - cpu_usage_percent / 100).

Lifecycle transitions are now atomic. MarkDraining flips status and deletes model records in one transaction rather than as separate operations that could interleave with SetNodeModel. ResumeNode is conditional: draining to healthy only, preventing overwriting of pending approval or concurrent state changes. HTTP endpoints return proper 404 (not found) and 409 (status conflict) instead of a generic 500.

ui-fleet-dashboard

🔗 PRs: #12046

🔑 Credentials file for private sources

Backends, models and gallery indexes can live behind private OCI registries, internal HTTP servers or private GitHub repos. Before this, each download path had its own ad-hoc auth mechanism, and tokens were scattered across environment variables.

One credentials.yaml file, loaded by --credentials-file / LOCALAI_CREDENTIALS_FILE, authenticates them all. It is a top-level YAML list of rules. Each rule has a match URL prefix and exactly one auth type: basic (username + password / password_env / password_file), bearer (bearer / bearer_env / bearer_file), or custom header (header.name + header.value / header.value_env / header.value_file). Exactly one of the plain, _env or _file form per secret; unknown keys are errors so a misspelled pasword_env fails loudly.

OCI registries (backend images, oci:// and ollama:// models, digest lookup, Range resume, cosign verify) consult the store first, then authn.DefaultKeychain (docker config). HTTP downloads, galleries and github: URIs authenticate through an http.RoundTripper that puts the credential on a clone of the request. net/http rebuilds each redirect hop from the original headers, so a redirect to another host never carries the credential. A caller-supplied credential (e.g. HF_TOKEN) takes precedence: the transport leaves an existing Authorization header alone.

Secrets are read at use time, not load time, so a rotated K8s secret mount takes effect without restart. Credential and Store implement String, GoString and LogValue, so no fmt verb or slog call, including when nested in unexported fields, can print secret material. Credentials go only to https, or to http when the rule sets allow_insecure. Match strings containing user:token@, ? (where signed URLs carry tokens) or # are rejected at load. YAML decode errors are redacted: quoted scalar values (often secrets) are stripped, keeping only line numbers and parser wording.

🔗 PRs: #12028

📏 local-ai benchmark CLI command

A benchmark command for configured text models, answering "how fast is this model on this hardware" without leaving the terminal.

local-ai benchmark MODEL [MODEL ...] sends non-streaming POST /v1/chat/completions requests at temperature:0 with configurable --runs (default 3), --warmup (default 1), --max-tokens (default 128) and --timeout (default 5m). It reports min, mean and max latency and end-to-end completion tokens/sec per model.

The throughput metric is sum(completion_tokens) / sum(latencies) across measured runs. It is nil/N/A if any sample omits completion_tokens from the response usage, or if total latency is zero. The command does not measure decode-only speed or time to first token; it is an end-to-end client benchmark covering HTTP transport, queueing, prompt processing, generation and parse.

The HTTP client refuses redirects by default, so a misconfigured endpoint behind a redirect does not silently succeed. The API key is redacted from error messages, and raw transport errors are masked as HTTP request failed to avoid credential echo. The full report is buffered in a bytes.Buffer and only written via io.Copy after all models succeed, so a failure leaves no partial output. Signal handling cancels the active request on SIGINT/SIGTERM.

Output is a table by default or --json for structured data with per-sample latency and nullable token counts. The API key is not included in the JSON. To compare backends, configure separate model aliases per backend and pass those alias names.

🔗 PRs: #12020

🔧 vllm-cpp LoRA fusion at load time

The lora_adapters and lora_scales config fields are standard LocalAI fields that list LoRA adapter weight files and per-adapter strength multipliers. The vllm-cpp video backend now consumes them for the first time, fusing LoRA deltas into DiT (diffusion Transformer) weights at engine load.

buildLoraExtras converts the config fields into indexed lora_path / lora_strength key-value pairs. The first adapter is unsuffixed; subsequent ones get _2, _3, etc. If the singular lora_adapter is set, it is prepended as the first adapter before the plural list. Relative adapter paths are joined to the model path; absolute paths pass through. Strength defaults to 1.0 when no scale is provided.

The pairs are packed via the ABI v18 extras seam and handed to vllmVideoEngineLoad. vllm.cpp's ResolveDitLoraSpecs fuses the LoRA deltas into the DiT weights at load. One generic path serves both LTX2.5 and MiniMax-H3, since the engine auto-detects the DiT family from the checkpoint.

Adapters are always loaded; there is no per-request activation in this path. Runtime prompt-activated LoRA (punica-style <lora:name:strength>) is out of scope and tracked separately.

🔗 PRs: #12082

🌍 Environment variables per model

An env: map on the model config injects variables into the backend process environment. The primary use case is pinning CUDA_VISIBLE_DEVICES per model to control GPU placement, but it applies to any backend that reads environment variables.

name: vllm-model
backend: vllm
env:
  CUDA_VISIBLE_DEVICES: "0,1"
  VLLM_CACHE_DIR: "/tmp/vllm_cache"

The map is delivered through the common process-spawning layer in pkg/model/process.go, so every gRPC backend inherits it with no per-backend wiring. Model vars are appended last, after the base env, so they override same-named inherited system vars. The UI renders an editable key/value map.

Model vars take effect only when a model spawns its own backend process, not when it reuses a worker-supervised one. There is no allowlist or blocklist: model configs are an operator trust boundary, consistent with LocalAI's general posture.

🔗 PRs: #10721

💬 template.system_messages_after_first

Agent frameworks legitimately append system instructions mid-conversation: a tool-parameter prompt before a call, an adjustment prompt after a result. The Qwen3.x family of tokenizer templates raises Jinja Exception: System message must be at the beginning for any system-role message after the first turn, returning HTTP 500. Plain chat looks healthy; every agent task fails.

template.system_messages_after_first controls what happens to system-role messages that appear after the contiguous leading system block:

  • "merge" folds late system messages into the first system message with a \n\n separator, dropping them from their original position.
  • "user" rewrites each late system message in place to role user, keeping its position and content.
  • unset (default) passes through unchanged; the tokenizer template decides.

The normalization runs in ChatEndpoint after stripEmptySystemMessages and before tokenizer-template system_prompt injection, so the Jinja template never sees an out-of-place system message. It only touches requests whose model config opts in, so default behavior is unchanged.

"user" is the recommended mode for agent workloads: the instruction stays where the framework placed it, and the model follows it.

🔗 PRs: #11906

🧠 context_size in /v1/models/capabilities

The capabilities endpoint now populates entry.ContextSize with backend.EffectiveContextSize(cfg) when the result is positive. Clients can read each model's effective context window to budget tokens, truncate prompts and history, and avoid sending more context than the model accepts, without having to probe the model config out-of-band.

🔗 PRs: #12083

🕵️ Face enrollment replay

The face recognition 1:N registry gains a replay path. FaceRegisterRequest now accepts an Embedding (pre-computed vector) and RegisteredAt (original timestamp), so a client that previously extracted an embedding via /v1/face/embed can replay the saved vector, name, labels and timestamp directly, skipping image decoding and the FaceEmbed inference call entirely.

The store derives a deterministic ID from the embedding bytes and store namespace via uuid.NewSHA1, so replaying the same vector after a restart or on another replica returns the same ID without creating duplicates. The server does not persist the registry itself; clients must retain and replay the records to restore the registry after a restart.

🔗 PRs: #11908

🎯 Focus mode toggle

Focus mode (which collapses the global app sidebar and slims the header once a conversation has at least one message, with Esc temporarily restoring them) already existed as session-only behavior. This adds a persistent opt-out toggle in the chat settings drawer, backed by localStorage under localai_chat_focus_mode. It defaults to enabled; with the toggle off, the full layout stays even in an active conversation.

🔗 PRs: #11750

🧰 Smaller features worth knowing about

  • stablediffusion-ggml builds a ROCm variant. A ROCm build of the stable-diffusion ggml backend, extending accelerator coverage beyond CUDA and Metal.
  • Scheduling rules editable in place. Distributed scheduling rules can now be edited in place in the UI rather than through a round-trip to the config file.
  • Scheduling rules keyed by model alias. Distributed scheduling rules can be keyed by a model alias, not just a model name, so aliased models participate in scheduling correctly.
  • XIO copy buffer size is configurable. The copy buffer size for XIO transfers is now configurable rather than fixed.
  • OCI layer download resumption. Interrupted OCI layer downloads resume rather than restarting from scratch.
  • Progress updates no longer throttle downloads. Status updates were throttling downloads; the progress path is now bounded so it does not compete with the transfer.
  • Node operation controls restored. The node detail page's operation controls (drain, resume, remove) are restored after a regression that hid them, and backend actions are tested through their menu.

🔗 PRs: #11774, #11667, #11771, #11660, #11688, #11661, #12068, #12069


🐛 Bug Fixes (recap)

Security / CVE:

ds4:

  • fix(ds4): separate prefilled reasoning from content - #11802
  • fix(ds4): enforce generation boundaries - #11821
  • fix(ds4): cancel abandoned inference - #11822
  • fix(ds4): build CUDA kernels for the target architecture - #11840
  • fix(ds4): resolve Hugging Face repository imports - #11340

Distributed mode:

  • fix(distributed): restore node liveness tests - #11694
  • fix(distributed): survive a slow control-plane database - #11837
  • fix(distributed): stage sound detection audio - #11907
  • fix(distributed): finalize stalled model uploads - #11910
  • fix(distributed): resolve paths for virtual models - #11911
  • fix(distributed): bound ephemeral staging - #11924
  • fix(distributed): pass raw JPEG base64 through staging - #11956
  • fix(distributed): keep staging operations stable - #11663
  • fix(distributed): keep model replicas config-consistent - #11664

Realtime:

  • fix(realtime): accept GA WebRTC signaling - #11778
  • fix(realtime): skip responses for empty transcripts - #11940
  • fix(realtime): resolve pipeline voice profiles - #11942
  • fix(realtime): support voice profile switching - #11948

Backends:

  • fix(backends): honor enable_thinking=false in sglang and vllm - #11715
  • fix(backends): honor enable_thinking=false in mlx and vllm-omni - #11962
  • fix(diffusers): auto-detect CUDA instead of defaulting to CPU - #11891
  • fix: prefer the Intel diffusers venv SYCL runtime at startup - #11971
  • fix(qwen-tts): restore CUDA 13 SDPA fallback - #12067
  • fix(faster-whisper): manually install ctranslate2 with rocm support - #9839
  • fix(whisper): honour positional listen address argument - #11652
  • fix(backends): bound temporary scratch files - #11941
  • fix(openresponses): support Codex WebSocket warm-up - #11608

Gallery and models:

  • fix(gallery): tag MTP-enabled models - #11653
  • fix(gallery): remove duplicate Qwopus entries - #11670
  • fix(gallery): use published F16 mmproj for qwythos-9b - #11792
  • fix(gallery): persist inference defaults where the loader reads them - #11232
  • fix(gallery): default audio-cpp models to backend:best - #11892
  • fix(gallery): restore entries clobbered by batch PR applies - #12016
  • fix(gallery): use native Ministral tool parsing - #12022
  • fix(vram): persist remote probe metadata - #11487
  • fix(ollama): accept :latest tag on model lookup - #11732

UI:

  • fix(ui): omit empty system prompt so model default applies - #11838
  • fix(ui): omit GPU recommendations that do not fit - #11945
  • fix(ui): preserve percent signs in route parameters - #11883
  • fix(ui): restore node operation controls - #12068
  • fix(ui): test backend actions through their menu - #12069
  • fix(ui): size model fit against the cluster - #11765

Other:

  • fix(deps): bump go-m1cpu to v0.2.2 to fix SIGSEGV on Apple M5 - #11736
  • fix(downloader): make file:// installs reachable again - #11734
  • fix(detection): avoid temporary image files - #11938
  • fix(worker): resolve temporary paths in tests - #11944
  • fix(ci): bound Discord release summaries - #11695
  • fix(ci): stop the e2e teardown from failing a green suite - #11816
  • fix(ci): unbreak the e2e build and the darwin vllm-metal pin - #11849
  • fix(progress): stop status updates throttling downloads - #11661
  • fix(oci): resume interrupted layer downloads - #11688

🧠 Models

140 new gallery entries this cycle, taking the index from 1,707 to 1,847.

Text generation: Qwopus 3.6, OpenResearcher, LFM2.5 DSpark, Qwen3.8 small distills, Qwen3.8 Flash Next, Qwen3.8 OBLITERATED, Qwen3.8 Cold Fusion, Qwen3.8 GSQ-RCO, UI-Mate 27B, Homura 30B, Ornith 1.5 35B and 9B (including OBLITERATED), Granite 4.2, Tiel-Coder 35B, Thomson 1.0 Small, PhoneLLM, and Huihui Qwen3.8 Flash Next.

Embeddings: WeMM embedding variants.

EXL3: vllm.cpp EXL3 models.

Vision: Gemma 4 E4B HauhauCS variants.

Speech: Orukeet added to the NeMo speech backend.

🔗 PRs: #11662, #11658, #11676, #11675, #11672, #11680, #11691, #11714, #11719, #11723, #11766, #11772, #11763, #11775, #11779, #11754, #11751, #11787, #11803, #11912, #11625, #11903, #11921, #11998, #11716


👒 Dependencies

Submodule and pin bumps this cycle:

Project Bumps
0xShug0/audio.cpp 16
ggml-org/llama.cpp 12
CrispStrobe/CrispASR 10
ikawrakow/ik_llama.cpp 8
leejet/stable-diffusion.cpp 7
mudler/vllm.cpp 6
ggml-org/whisper.cpp 6
antirez/ds4 6
ServeurpersoCom/omnivoice.cpp 5
NVIDIA/NeMo-Speech.cpp 4
PrismML-Eng/llama.cpp 3
mudler/depth-anything.cpp 2
vllm-project/vllm cu130 wheel, vllm-metal (darwin), OpenNMT/CTranslate2 ROCm wheel, TheTom/llama-cpp-turboquant 1 each

Plus vllm 0.26.0 to 0.29.0 in the Python backends, torch 2.13.0+xpu to 2.14.0+xpu, grpcio to 1.83.1 across coqui/rerankers/vllm/template, charset-normalizer to 3.5.1, securego/gosec to 2.29.0, LocalAGI and localrecall to v0.6.5, 16 stale dependabot entries removed, npm_and_yarn group updates, and inference defaults refreshed from unsloth.


📖 Documentation

New pages for the CLI benchmark command and the credentials file / private sources guide. The distributed-mode docs document the fleet dashboard, CPU telemetry and the new endpoint error codes. Model configuration gained the env: map, template.system_messages_after_first and context_size documentation. The DCO guide clarifies that maintainer-operated automation may sign off. Installation paths were simplified, an Apache APISIX reverse proxy example was added, dead anchors and section links were fixed, documented env var and CLI flag names were corrected, and the containers page was fixed for Podman image qualification. A FAQ note covers OPENAI_BASE_URL for pointing clients at LocalAI, and Solstone was added to the README and ADOPTERS.md.

🔗 PRs: #11631, #11294, #11850, #11700, #11885, #11884, #11886, #11749, #11904, #11310, #12044, #12045


🙌 New Contributors

Thanks also to @mudler, @anupamme, @mvanhorn, @jimmykarily, @Nold360, @Anai-Guo, @SuperMarioYL, @eglia and @walcz-de for their contributions this cycle.

What's Changed

Bug fixes 🐛

Exciting New Features 🎉

🧠 Models

📖 Documentation and examples

👒 Dependencies

Other Changes

New Contributors

Full Changelog: v4.9.0...v4.10.0

Don't miss a new LocalAI release

NewReleases is sending notifications on new releases.