Skip to content

feat: send a LocalAI User-Agent on registry pulls#10434

Open
vjsai wants to merge 1 commit into
mudler:masterfrom
vjsai:feat/registry-user-agent
Open

feat: send a LocalAI User-Agent on registry pulls#10434
vjsai wants to merge 1 commit into
mudler:masterfrom
vjsai:feat/registry-user-agent

Conversation

@vjsai

@vjsai vjsai commented Jun 21, 2026

Copy link
Copy Markdown

Description

This PR implements #6258.

LocalAI pulls models from OCI registries, the Ollama registry, and OCI blob stores, but every outbound request used the underlying library's generic User-Agent (go-containerregistry/…, oras-go, …). As @mudler noted in the issue, "we already support pulling images with Dockerhub in pkg/oci/image.go — however we don't have a specific User agent." That makes it impossible for registry operators to attribute traffic to LocalAI (the motivation in the issue, mirroring llama.cpp's User-Agent: "llama.cpp").

This adds a small oci.UserAgent() helper and wires it into all three registry-pull paths so every LocalAI request identifies itself consistently.

What changed

  • pkg/oci/useragent.go (new): UserAgent() returns LocalAI, or LocalAI/<version> when the binary is built with a version stamp (internal.Version, set via the existing -X …/internal.Version ldflag).
  • pkg/oci/image.go: adds remote.WithUserAgent(UserAgent()) to the go-containerregistry image and digest pulls (GetImage, GetImageDigest).
  • pkg/oci/ollama.go: sets a User-Agent header on the Ollama manifest request.
  • pkg/oci/blob.go: sets a LocalAI User-Agent on the oras blob client. It mirrors oras' auth.DefaultClient (same retry.DefaultClient policy) — only the advertised User-Agent changes, so the HTTP/redirect behavior is unchanged.
  • Tests: pkg/oci/useragent_test.go (Ginkgo/Gomega) covers both the unstamped (LocalAI) and stamped (LocalAI/<version>) cases.
  • Docs: a short note under Installing from OCI Registries in docs/content/getting-started/models.md.

Test output (go test ./pkg/oci/..., full suite, hits the live registries):

```
Ran 5 of 6 Specs in 66.958 seconds
SUCCESS! -- 5 Passed | 0 Failed | 0 Pending | 1 Skipped
```

go build, go vet, gofmt -l, and golangci-lint run ./pkg/oci/... (v2.12.2) all pass with 0 issues.

Notes for Reviewers

remote.WithUserAgent appends go-containerregistry/<ver> to the UA, so OCI image pulls advertise e.g. LocalAI/<version> go-containerregistry/v0.21.6; the Ollama and oras paths advertise exactly LocalAI/<version>. Prepared with AI assistance (Claude Code), per the repo's AI Coding Assistants policy — see the Assisted-by: trailer; I have reviewed and tested every line.

Signed commits

  • Yes, I signed my commits.

LocalAI pulls models from OCI registries (via go-containerregistry), the
Ollama registry, and OCI blob stores (via oras), but every request went
out with the underlying library's generic User-Agent, so registry
operators had no way to attribute traffic to LocalAI.

Add an oci.UserAgent() helper that returns "LocalAI" (or
"LocalAI/<version>" when the binary is built with a version stamp via
internal.Version) and wire it into all three pull paths:

- pkg/oci/image.go: remote.WithUserAgent on the go-containerregistry
  image and digest requests
- pkg/oci/ollama.go: a User-Agent header on the Ollama manifest request
- pkg/oci/blob.go: a LocalAI User-Agent on the oras blob client. This
  mirrors oras' auth.DefaultClient (same retry.DefaultClient policy);
  only the advertised User-Agent changes.

Implements mudler#6258.

Signed-off-by: Vijay Sai <vijaysaijnv@gmail.com>
Assisted-by: Claude:claude-opus-4-8 golangci-lint
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant