* feat(addons): add a durable host policy store Keep bounded host policy in one owner-managed durable store. Use revision checks and retained receipts to reconcile updates without stale writes. Require a sole migration source and explicit owner selection for clusters. Restrict provider pins to tools and skills that existing consumers replace. Document the internal scope; UI and carrier integration remain separate. Assisted-by: Codex:gpt-5 Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * fix(addons): reject malformed host policy JSON Reject duplicate keys, noncanonical fields, and incomplete durable structures before JSON decoding can discard evidence of corruption. Validate provider keys before deletion so invalid removals cannot commit. Keep empty provider sets canonical when writing migrated policies. Regressions cover malformed documents, unchanged storage on rejection, and replay with case-sensitive operation IDs. Assisted-by: OpenAI:ChatGPT Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * fix(addons): decouple host policy validation Move shared egress parsers into a dependency-light package so the gateway can consume host settings without importing itself through core/config. Keep config wrappers and a host type alias to preserve existing callers. Assisted-by: Codex:gpt-5 Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * feat(addons): carry host policy actions to owner Keep host policy reads and updates on the authenticated owner. The owner checks current administrator authority before updates and preserves CAS conflicts and durable operation receipts across forwarding. Provide read-only snapshots for trusted hosts over pinned mTLS. Missing owner services never fall back to frontend policy. Application startup, public settings routes and runtime consumers remain separate work. Verify typed actions with local and real mTLS forwarding tests, including revoked actors, strict payloads, receipt replay and unavailable stores. Assisted-by: Codex:gpt-5 Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * fix(addons): keep policy provenance private Return a bounded policy projection from gateway reads, updates and replay. Trusted host consumers use the same projection without migration metadata. The private owner store retains provenance for migration records. Cover local and pinned-carrier output, durable provenance and typed errors. Assisted-by: Codex:gpt-5 Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * feat(addons): initialize owner host settings Open durable host settings only after the owner acquires its storage guard. Keep frontends forwarding without importing their local configuration. Preserve automatic migration for the sole combined host configuration. Require explicit owner-local selection for non-default dedicated policy. Close the store once on cancellation, shutdown or startup failure. Cover migration, restrictive defaults, restart revisions, corruption, duplicate owners and frontend isolation in the native bootstrap test. Document the owner-only migration option and storage constraints. Assisted-by: OpenAI:ChatGPT Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * fix(addons): close settings before the owner guard Startup failures released the owner guard before closing host settings. Use one deferred cleanup to preserve the close order on every failure. Test real runtime and gateway failures, shutdown, and cancellation. Check once-only closure and reacquire both locks after cleanup. Assisted-by: Codex:gpt-5 Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * fix(addons): enforce owner egress policy in Studio Read owner policy for Studio defaults, views, cards and enforcement. Frontend configuration must not override policy or mask an owner outage. Propagate context and policy errors instead of reusing a cached allow. Preserve local settings behavior when add-ons are disabled. Cover existing consumers through independent pinned mTLS carriers. Verify live tightening, pending-card outages and restart persistence. Document the read semantics and the proxy verdict-cache boundary. Assisted-by: OpenAI:gpt-5 Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * fix(addons): read provider pins from owner policy Studio reads current owner pins for tools and skills instead of frontend configuration when add-ons are enabled. Policy failures stop selection rather than silently choosing built-ins. Disabled add-ons retain local configuration behavior. Cover owner updates and outages, and document the read contract. Assisted-by: Codex:gpt-5 Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * fix(studio): abort turns on mandatory policy errors Sessions must not treat owner policy failures as optional tool outages. Stop priming before harness startup and abort turns before model sends. Preserve wrapped policy causes and existing optional connector behavior. Cover sent turns, priming failures, and optional connector failures. Document the failure contract without changing fallback or cache rules. Assisted-by: Codex:gpt-5 Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * fix(addons): use owner policy for auto-upgrades Read fresh owner policy before each automatic upgrade pass. Skip the pass when that policy is unavailable instead of trusting local settings. Wire a real owner policy store into the transportless manager fixture. Keep assertions for stale frontend settings and owner policy changes. Assisted-by: Codex:gpt-5 Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * fix(addons): guard legacy settings writes Reject migrated owner policy fields before applying any local settings. Omit those fields from legacy reads while add-ons are enabled, and keep unrelated local settings available without an owner request. Cover presence, case folding, duplicate keys and atomic rejection. Document the legacy contract and unchanged disabled behavior. Assisted-by: Codex:gpt-5 Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * test(addons): use the existing Ginkgo suites Register settings authority regressions with the existing suites to comply with the Ginkgo/Gomega test policy. Preserve the conflict, compatibility, owner outage, and upgrade assertions without adding another RunSpecs bootstrap. Assisted-by: Codex:gpt-5 Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * feat(egress): bound wildcard host policy grants Support descendant and public-any patterns through the shared parser. Keep wildcard grants inside the administrator ceiling and public guard. Preserve the legacy exact-host exception under the registries ceiling. Keep policy strings lossless for existing receipts and stored exact hosts. Test canonical matching, private exclusions, ports, and policy replay. Proxy connection authorization and cache changes remain separate. Assisted-by: Codex:gpt-5 Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * fix(egress): authorize each new connection Remove cached allows so policy tightening and owner outages block new connections immediately. Keep existing DNS, private-address and SNI guards. Socket tests cover HTTP keep-alive, CONNECT and consumed grants. Established streams may finish under their original authorization. Expect the canonical runsc path in the gVisor test, matching production. This preserves the path contract when the test temp directory is a symlink. A short alias avoids Unix socket path limits in deep worktrees. Verify with go test -race -count=1 -timeout=180s ./addons/sandbox/... using an offline environment and a short alias to the worktree temp folder. Assisted-by: Codex:gpt-5 Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * fix(addons): save network policy through the owner Use owner revisions for host controls instead of frontend runtime settings. Keep drafts across conflicts and outages, and replay uncertain writes with the same operation identity. Read authoritative policy after each save. Accept bounded host wildcards while keeping extra registries exact. Keep typed private-access confirmation out of owner policy patches. Add rendered form and client tests, and document reconciliation behavior. Assisted-by: OpenAI: GPT-5 Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * fix(addons): fail closed on owner policy errors Reject partial, mistyped, unknown and oversized owner snapshots before publishing them to the form. Match the complete Go policy JSON shape. Keep owner availability errors and uncertain operation identities when Discard resets the local draft. Only reconciliation can reopen saving. Tests reproduce both review failures and cover immutable retries, malformed reloads and the rendered discard-then-edit regression. Assisted-by: Codex:gpt-5 Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * fix(addons): finish owner settings controls Route skill switches, provider choices and upgrade controls through owner policy. Preserve per-key changes when another frontend updates the policy. Keep local tool execution controls on their existing settings path. Extend the existing state checklist and add-on acceptance guidance so new controls declare their authority and test both deployment topologies. Assisted-by: nib:gpt-6.1-sol Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * fix(studio): check policy errors in Tables skill tests Adapt the Tables test added on master to the error-aware skillTurn API. Assert that normal skill selection succeeds instead of discarding errors. Verified with make test-distributed-fakebus and scoped golangci-lint. Assisted-by: nib:gpt-6.1-sol Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * fix(addons): document guarded settings IO boundaries Explain the narrow gosec exceptions for the authenticated administrator settings response and fixed owner-root files. Keep symlink, mode and type checks intact; no request-supplied paths reach this store. Explicitly ignore best-effort temporary-file and directory cleanup errors; file and directory sync failures still determine durability. Verified owner-store and handler race tests and scoped golangci-lint. Assisted-by: nib:gpt-6.1-sol Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * test(addons): run carrier policy cases in Ginkgo Register projection, forwarding, validation and CAS cases with the existing gateway suite. Check cleanup errors in test fixtures and explicitly ignore response-body cleanup after decoding in the internal read client. Verified gateway/application authority race tests and scoped lint. Assisted-by: nib:gpt-6.1-sol Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * test(addons): inventory owner policy gateway cases Require all four owner-policy cases in both the per-report and aggregate gateway and artifact acceptance inventories. Keep exact matching intact. Verified real test reports with the existing strict Ginkgo report validator: 215 gateway cases and 252 artifact cases passed, without skipped cases. The full browser readiness probe remains a separate CI gate. Assisted-by: nib:gpt-6.1-sol Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * test(ui): scope library settings apply action Select the exact Apply button in the runtime settings pending bar. The owner upgrade control has a separate Apply upgrade setting button, so an unscoped substring locator is ambiguous. Verified the failing Playwright case against the real UI test server and Google Chrome, with isolated server and browser temporary paths. Assisted-by: nib:gpt-6.1-sol Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * test(egress): update route and invalid-host fixtures Use the context-aware egress callback in route tests. Keep the last-valid list regression meaningful by using a partial-label wildcard, since a whole-label descendant pattern is now valid input. Verified focused application and route race tests and scoped lint. Assisted-by: nib:gpt-6.1-sol Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * test(settings): reject partial-label wildcard fixture Keep the invalid-input regression while accepting the newly supported whole-label descendant wildcard. Use api.*.example.com as invalid input. Reproduced the full endpoint suite failure, then verified all 616 endpoint specs pass and scoped lint is clean. Assisted-by: nib:gpt-6.1-sol 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>
9.1 KiB
LocalAI Agent Instructions
This file is the entry point for AI coding assistants (Claude Code, Cursor, Copilot, Codex, Aider, etc.) working on LocalAI. It is an index to detailed topic guides in the .agents/ directory. Read the relevant file(s) for the task at hand — you don't need to load all of them.
Human contributors: see CONTRIBUTING.md for the development workflow.
Policy for AI-Assisted Contributions
LocalAI follows the Linux kernel project's guidelines for AI coding assistants. Before submitting AI-assisted code, read .agents/ai-coding-assistants.md. Key rules:
- No
Signed-off-byfrom AI. Only the human submitter may sign off on the Developer Certificate of Origin. One exception: automation a maintainer operates signs off with that maintainer's identity, since no other human submitter exists to certify it. See .agents/ai-coding-assistants.md. - No
Co-Authored-By: <AI>trailers. The human contributor owns the change. - Use an
Assisted-by:trailer to attribute AI involvement. Format:Assisted-by: AGENT_NAME:MODEL_VERSION [TOOL1] [TOOL2]. - The human submitter is responsible for reviewing, testing, and understanding every line of generated code.
Topics
| File | When to read |
|---|---|
| .agents/ai-coding-assistants.md | Policy for AI-assisted contributions — licensing, DCO, attribution |
| .agents/building-and-testing.md | Building the project, running tests, Docker builds for specific platforms |
| .agents/ci-caching.md | CI build cache layout (registry-backed BuildKit cache on quay.io/go-skynet/ci-cache, per-arch keys), DEPS_REFRESH weekly cache-buster for unpinned Python deps, prebuilt base-grpc-* images for llama.cpp variants, per-arch native + manifest-merge pattern, setup-build-disk /mnt relocation, path filter on master push, manual eviction |
| .agents/adding-backends.md | Adding a new backend (Python, Go, or C++) — full step-by-step checklist, including importer integration (the /import-model dropdown is server-driven from GET /backends/known) |
| .agents/coding-style.md | Code style, editorconfig, logging, documentation conventions |
| .agents/llama-cpp-backend.md | Working on the llama.cpp backend — architecture, updating, tool call parsing |
| .agents/vllm-backend.md | Working on the vLLM / vLLM-omni backends — native parsers, ChatDelta, CPU build, libnuma packaging, backend hooks |
| .agents/sglang-backend.md | Working on the SGLang backend — engine_args validation against ServerArgs, speculative-decoding (EAGLE/EAGLE3/DFLASH/MTP) recipes, parser handling |
| .agents/ds4-backend.md | Working on the ds4 backend - DSML state machine, thinking modes, KV cache, Metal+CUDA matrix |
| .agents/testing-mcp-apps.md | Testing MCP Apps (interactive tool UIs) in the React UI |
| .agents/api-endpoints-and-auth.md | Adding API endpoints, auth middleware, feature permissions, user access control |
| .agents/debugging-backends.md | Debugging runtime backend failures, dependency conflicts, rebuilding backends |
| .agents/adding-gallery-models.md | Adding GGUF models from HuggingFace to the model gallery |
| .agents/localai-assistant-mcp.md | LocalAI Assistant chat modality — adding admin tools to the in-process MCP server, editing skill prompts, keeping REST + MCP + skills in sync |
| .agents/backend-signing.md | Backend OCI image signing (keyless cosign + sigstore-go) — producer-side CI setup, consumer-side gallery verification: block, strict mode (LOCALAI_REQUIRE_BACKEND_INTEGRITY), revocation via not_before |
| .agents/preparing-a-release.md | Cutting a release: PR labels, RELEASE_NOTES_vX.Y.Z.md, the blog post under website/content/blog/, and the demo clips under website/static/media/ |
| .agents/distributed-state.md | Features that keep runtime state — how they must behave with several frontends (syncstate, advisory-lock leaders, fakebus tests) |
| .agents/distributed-seams.md | Distributed mode transports: the fan-out, queue, control verb, agent RPC and dial seams, subject rules, the no-route contract, conformance suites, open items for a second carrier |
| .impeccable.md | Design context for UI/UX work — users, brand personality, aesthetic direction, and design principles |
Quick Reference
-
Coverage gates: Never lower a coverage baseline or widen a gate's tolerance to turn a red gate green — the coverage ratchet only moves up. If a change drops coverage, add tests to raise it (e.g. render-smoke specs). See .agents/building-and-testing.md.
-
Logging: Use
github.com/mudler/xlog(same API as slog) -
Go style: Prefer
anyoverinterface{} -
Comments: Explain why, not what
-
Docs (docs-with-code rule): When you change user-facing behavior (API endpoints, CLI flags, config keys, or features), update the corresponding page under
docs/content/in the SAME change, not as a follow-up. A user-facing change without a matching docs update is incomplete. See also the documentation conventions in .agents/coding-style.md. -
New API endpoints: LocalAI advertises its capability surface in several independent places — swagger
@Tags,/api/instructionsregistry, authRouteFeatureRegistry, React UIcapabilities.js, docs. Read .agents/api-endpoints-and-auth.md and follow its checklist — missing any surface means clients, admins, and the UI won't know the endpoint exists. -
Admin endpoints → MCP tool: every admin endpoint that an admin would manage conversationally (install/list/edit/toggle/upgrade) MUST also be exposed as an MCP tool in
pkg/mcp/localaitools/. The LocalAI Assistant chat modality and the standalonelocal-ai mcp-serverconsume that package; drift between REST and MCP is a real risk. Read .agents/localai-assistant-mcp.md — theTestToolHTTPRouteMappingCompletetest fails until you wire the new tool and update the route map. -
Releases ship with a post and clips: a release is not done at the tag. It needs labelled PRs,
RELEASE_NOTES_vX.Y.Z.md, a blog post underwebsite/content/blog/, and a short demo clip inwebsite/static/media/for each notable feature. See .agents/preparing-a-release.md. -
Build: Inspect
Makefileand.github/workflows/— ask the user before running long builds -
Backend OS coverage: a new backend must target every OS it can build for, not just Linux.
.github/backend-matrix.ymlhas two matrices —include:(Linux) andincludeDarwin:(macOS / Apple Silicon). Most C/C++/GGML and many Python backends build on Darwin too — wire theincludeDarwinentry + themetal:entries of the backend library (gallery/backends/index.yaml, added withbackendcatalog --add;backend/index.yamlis generated, never edited), or say in the PR why an OS is unsupported. See the darwin checklist in .agents/adding-backends.md. -
Gallery variant ranking: a gallery entry can declare
variants(alternative builds of the same weights), and LocalAI ranks the ones a host can run by engine preference first, size second. A new backend that should be preferred on some hardware must be listed inengineNamePreferenceRulesinpkg/system/capabilities.go; the siblingbackendBuildTagPreferenceRulesspeaks build tags rather than engine names, and using the wrong table matches nothing without erroring. See .agents/adding-backends.md. -
UI: The active UI is the React app in
core/http/react-ui/. The older Alpine.js/HTML UI incore/http/static/is pending deprecation — all new UI work goes in the React UI -
Distributed-aware state: any feature that keeps runtime state (maps, caches, pins, schedulers, background loops) must choose shared (syncstate), single-runner (advisorylock), stateless, or documented per-instance behaviour for multi-frontend clusters. See .agents/distributed-state.md.
-
Add-on settings authority: before adding settings or host-rendered controls, follow the existing checklist in .agents/distributed-state.md and the owner/two-frontend matrix in addon testing. UI placement does not establish authority. Declare owner-wide, cluster-wide, or node-local scope; owner-wide settings must use authenticated owner dispatch in both combined and distributed modes, not frontend-local
/api/settings.