ollama/ollama
github.com/ollama/ollama ↗ · 1232 files · 11.9 MB
Ollama Start building with open models. Download macOS shell curl -fsSL https://ollama.com/install.sh | sh or download manually Windows shell irm https://ollama.com/install.ps1 | iex or download manually Linux shell curl -fsSL https://ollama.com/install.sh | s
Overview
Ollama is a Go-based local LLM runner that packages models as OCI-style content-addressed blobs plus manifests under ~/.ollama/models, serves them through a Gin HTTP API on 127.0.0.1:11434, and delegates actual inference to per-model subprocesses — upstream llama-server for GGUF models and a bundled `ollama runner` MLX subprocess for safetensors models on Apple silicon. The same binary provides the end-user CLI (cobra), a Bubbletea TUI, and a desktop app (macOS/Windows webview + React/Vite chat UI backed by a sqlite store). Distinctively, it emulates OpenAI and Anthropic REST surfaces on top of its native /api/* routes via middleware translators, supports remote 'cloud' models hosted on ollama.com, and renders/parses chat formats in Go through per-model-family renderer and parser registries.
System map
Single Go module (github.com/ollama/ollama) whose main binary is both the CLI client and the server. `ollama serve` starts a Gin HTTP server that owns a model Scheduler; inference is delegated to subprocesses (llama-server for GGUF, `ollama runner` for MLX/safetensors) spoken to over loopback HTTP. Model artifacts live as sha256 blobs + JSON manifests under OLLAMA_MODELS. Native code (vendored llama.cpp under llama/, MLX under mlx/) is built by CMake; the desktop app adds a webview shell and a React/Vite UI. Everything is configured through OLLAMA_* environment variables centralized in envconfig.
- Process entrypoint is main.go which calls cmd.NewCLI().ExecuteContext; all user-facing commands are cobra subcommands registered in NewCLI in cmd/cmd.go
- The HTTP server is a Gin engine built by Server.GenerateRoutes, registering ~30 routes across /api/*, OpenAI-compatible /v1/*, and Anthropic /v1/messages
- Inference scheduling is a channel-based Scheduler with pendingReqCh/finishedReqCh/expiredCh/unloadedCh, a loaded map of runnerRef keyed by model path, and a single in-flight load (activeLoading)
- GGUF inference runs in a separate llama-server subprocess spawned via exec.Command and driven over loopback HTTP through the llm.LlamaServer interface (Completion, Chat, Embedding, Tokenize, WaitUntilRunning, Close)
- Safetensors/MLX models take a different runner path: sched.load detects m.IsMLX() (Config.ModelFormat == "safetensors") and creates an mlxrunner.Client which re-execs the same binary as `ollama runner --model X --port N`
- Model storage is content-addressed: manifest.Path() -> OLLAMA_MODELS/manifests/<name>, BlobsPath() -> OLLAMA_MODELS/blobs/sha256-<hex>; manifests map model names to typed layers
- Configuration is centralized in envconfig as OLLAMA_* variables (HOST, MODELS, KEEP_ALIVE, NUM_PARALLEL, MAX_LOADED_MODELS, MAX_QUEUE, ORIGINS, FLASH_ATTENTION, KV_CACHE_TYPE, NO_CLOUD, REMOTES, etc.) exposed via AsMap()
- The desktop app is a separate main package gated by `//go:build windows || darwin` in app/cmd/app/app.go, bundling a webview, sqlite-backed store (app/store/schema.sql), updater, and a React 19 + Vite + Tailwind UI under app/ui/app
- Full build is CMake-driven (cmake -B build .; cmake --build build) producing the Go binary plus native payload under build/lib/ollama; go build ./go run . serve works for Go-only iteration against an existing native payload
- Native engines are vendored/pinned: llama.cpp version in LLAMA_CPP_VERSION with llama/server sources, MLX pinned via MLX_VERSION and MLX_C_VERSION under mlx/, GPU backends selected via -DOLLAMA_LLAMA_BACKENDS=cuda_v12;cuda_v13;rocm_v7_1;rocm_v7_2;vulkan;cuda_jetpack5;cuda_jetpack6
- GPU/device discovery is performed by spawning helper binaries: `ollama gpu-discover` (hidden cobra cmd -> discover.RunNativeProbeCommand) and llama-server --list-devices probes in discover/llama_server.go
- The CLI talks to the server through api.Client (api/client.go) whose methods map 1:1 to the REST API and which reads OLLAMA_HOST via ClientFromEnvironment
Feature catalog
User-facing surface = CLI subcommands + REST endpoints + OpenAI/Anthropic compat shims + a desktop chat app. Features cover the full model lifecycle (pull/create/push/copy/show/list/ps/delete), inference (generate/chat/embed with streaming NDJSON, thinking, tools, vision/audio, structured output, logprobs), cloud remote inference on ollama.com, experimental web search/fetch, and Codex Desktop integration via a loopback proxy.
- CLI commands: create, show, run, stop, serve (alias start), pull, push, signin/login, signout/logout, list, ps, cp, rm; hidden commands `runner` (MLX runner entrypoint) and `gpu-discover`
- Native API endpoints: /api/generate, /api/chat, /api/embed, /api/embeddings, /api/pull, /api/push, /api/tags (GET+HEAD), /api/show, /api/delete, /api/create, /api/blobs/:digest (POST+HEAD), /api/copy, /api/ps, /api/me, /api/signout, /api/version, /api/status
- OpenAI-compatible endpoints /v1/chat/completions, /v1/completions, /v1/embeddings, /v1/models(+/:model), /v1/responses(+ /compact), /v1/audio/transcriptions are middleware translators over the native handlers
- Anthropic compatibility is provided by POST /v1/messages -> middleware.AnthropicMessagesMiddleware -> ChatHandler
- `ollama create` supports two paths: classic Modelfile+API (parser.ParseFile -> CreateRequest -> blob upload -> /api/create) and in-process safetensors import with --quantize/--draft-quantize/--force when the server is local (OLLAMA_CREATE_REMOTE forces remote)
- Chat features include thinking control (think bool or level; --think/--hidethinking flags), tool calling via api.Tools parsed by model parsers, vision/audio inputs (ImageData, MediaKind), and shift/truncate context management options
- Structured output: GenerateRequest.Format accepts a JSON schema which is passed to llama-server's json_schema field; a built-in BNF grammarJSON exists for generic JSON mode
- Cloud/remote models: models whose Config has RemoteHost+RemoteModel are proxied by ChatHandler to remoteURL via api.NewClient, gated by envconfig.Remotes() allowlist and OLLAMA_NO_CLOUD; :cloud model refs take cloudPassthroughMiddleware on /v1 routes (inferred)
- Experimental endpoints: POST /api/experimental/web_search, /api/experimental/web_fetch, GET /api/experimental/model-recommendations served from a stale-while-revalidate modelCaches.recommendations
- A loopback-only Codex Desktop reverse proxy is mounted at /api/codex/* (proxy.CodexDesktopPathPrefix) to route between native Ollama models and Codex upstreams, with request logging via writeActivity
- Model auth uses an ed25519 keypair at ~/.ollama/id_ed25519 generated on serve start (initializeKeypair); registry challenge-response tokens are obtained via signed nonce requests (getAuthorizationToken)
- Interactive UX: bare `ollama` launches a Bubbletea TUI (runInteractiveTUI + welcome flow via cmd/launch + cmd/tui); `ollama run` without prompt enters readline-based interactive session; selectors/sign-in/upgrade prompts are injected as launch.Default* hooks
Data flow
Requests enter via Gin handlers -> model resolution (manifest -> Model struct) -> option merge (defaults < generation defaults < model < request) -> Scheduler -> runner subprocess over loopback HTTP -> streamed tokens parsed back into API responses. Model artifacts flow registry -> blob downloads -> manifest write; create flows Modelfile/safetensors dir -> layer blobs -> manifest. Chat text flows messages -> Go renderer or llama-server chat template -> prompt -> token stream -> Parser.Add splits content/thinking/tool calls -> NDJSON stream.
- Option precedence is layered in modelOptions: api.DefaultOptions -> model.GenerationDefaults (parsed from GGUF metadata) -> model.Options (Modelfile params) -> request options, with embedding models getting a NumBatch=2048 default capped by context
- Chat path in ChatHandler: ShouldBindJSON -> parseAndValidateModelRef -> getExistingName -> GetModel -> (unload shortcut for keep_alive=0) -> scheduleRunner -> renderer/parser selection -> llm runner Chat/Completion -> NDJSON stream to client
- GetModel resolves a name through manifest.ParseNamedManifest -> config blob decode (ConfigV2) -> layer iteration, grouping split GGUF shards via groupManifestSplitGGUFLayers; parseFromModel auto-pulls when the manifest is missing
- Prompt rendering branches: models with a Go renderer name go through renderers.RenderWithRenderer; others use template.Template (embedded .gotmpl set indexed by index.json) or llama-server's native chat_template via /v1/chat/completions
- Output parsing: streamed runner tokens are fed to Parser.Add which returns (content, thinking, toolCalls); PreservedTokens tells llama-server which grammar tokens must survive detokenization
- Pull flow: PullHandler -> PullModel -> registry layer resolution -> blobDownload.Run with chunked resumable parts -> sha256 verification -> manifest write; progress is fanned out as api.ProgressResponse over a channel to streamResponse
- Blob writes are content-addressed: CreateBlobHandler accepts POST /api/blobs/:digest and HeadBlobHandler probes existence; digest validity enforced by manifest.ValidateDigest regex sha256[:-][64 hex]
- Runner placement: scheduler loads GGUF metadata (llm.LoadModel), predicts VRAM via llm.PredictServerVRAM, selects GPUs via selectLlamaServerPlacement honoring OLLAMA_SCHED_SPREAD and OLLAMA_GPU_OVERHEAD, then evicts loaded runners if predicted footprint exceeds 80% of free memory
- llama-server subprocesses receive model path, ports, -ngl/-t only when explicitly set (otherwise auto-detect), media marker rewriting ([img-N]) for vision, and report memory back via parsed log lines into runner's vramByDevice/systemFreeAtLoad
- Desktop app persists chats/settings in sqlite (mattn/go-sqlite3) via app/store with a frozen v2 schema (schema.sql) plus migrations; the React UI talks to the same Ollama HTTP API
- Inference request logging is optional and bounded: withInferenceRequestLogging wraps /api/generate, /api/chat, and the /v1 inference routes, gated by OLLAMA_DEBUG_LOG_REQUESTS
- Context management: num_ctx defaults come from OLLAMA_CONTEXT_LENGTH or a VRAM-tier auto default (numCtxAuto), clamped to model train context; `shift` enables sliding-window context shift except for deepseek2 family; `truncate` drops history instead of erroring
Behavior traces
Three canonical flows: (1) serve startup: main -> cobra serve -> initializeKeypair -> net.Listen -> server.Serve -> blob prune -> GenerateRoutes -> InitScheduler.Run; (2) `ollama run X prompt`: CLI heartbeat/pull -> api.Client.Chat -> ChatHandler -> GetModel -> getRunner -> load -> llama-server subprocess -> streamed parse -> NDJSON; (3) pull: PullHandler -> PullModel -> blob downloads -> manifest write. Safetensors models diverge at sched.load into the mlxrunner subprocess.
- Startup order: main() -> NewCLI() -> serveCmd -> RunServer -> initializeKeypair (ed25519 at ~/.ollama) -> net.Listen(envconfig.Host) -> server.Serve(ln)
- server.Serve sequence: slog logger init -> log cloud-disabled status -> llm.PruneSplitModelDirs on blobs dir -> fixBlobs -> PruneLayers + manifest.PruneDirectory (unless OLLAMA_NOPRUNE) -> GenerateRoutes -> InitScheduler -> sched.Run goroutines -> http.Serve
- CLI run flow: RunHandler parses --think/--keepalive/--format flags -> api.ClientFromEnvironment -> showOrPullModel (pulls if absent) -> inferThinkingOption -> isEmbeddingModel branch -> generateChat/generateInteractive -> client.Chat -> POST /api/chat
- Server chat flow: ChatHandler binds JSON -> parseAndValidateModelRef -> cloud refs proxied via proxyCloudJSONRequest -> GetModel -> keep_alive=0 unloads via sched.expireRunner -> remote models proxied to RemoteHost -> otherwise modelOptions + scheduleRunner
- Scheduling flow: getRunner builds LlmRequest -> loaded-map fast path via schedulerModelKey (modelPaths joined with NUL, or digest:/name: fallback) -> else enqueue pendingReqCh (ErrMaxQueue when full) -> scheduler picks GPUs -> load() spawns runner -> useLoadedRunner
- GGUF runner launch: sched.load -> llm.LoadModel (gguf.ReadModel metadata) -> PredictServerVRAM -> selectLlamaServerPlacement -> newServerFn = llm.NewLlamaServer -> NewLlamaServerRunner -> startLlamaServer -> exec.Command(llama-server, params) -> WaitUntilRunning polls /health
- MLX runner launch: sched.load -> m.IsMLX() -> mlxrunner.NewClient(modelName, numCtx) -> exec.Command(self, "runner", --model, --port) -> hidden cobra `runner` cmd -> mlxrunner.Execute -> HTTP server inside subprocess
- Pull trace: PullHandler binds api.PullRequest -> parseNormalizePullModelRef (normalizes :cloud) -> PullModel in goroutine -> per-layer blobDownload (chunked parts with backoff) -> manifest write -> progress channel -> streamResponse emits api.ProgressResponse NDJSON
- Create trace (Modelfile): CreateHandler -> readCreateModelfile -> parser.ParseFile -> reject adapter/typical_p -> modelfile.CreateRequest -> createBlob uploads per file (or sharedBlobStore local shortcut) -> client.Create -> /api/create -> server assembles layers + manifest
- Unload/keep-alive: empty chat request with keep_alive=0 triggers sched.expireRunner and returns done_reason=unload without inference; runners expire via expiredCh after sessionDuration (OLLAMA_KEEP_ALIVE default 5m)
- OOM resilience: on llm.IsOutOfMemory during Load, scheduler reduces automatically-derived num_ctx/num_batch once (oomRetryAttempted) and retries; evict-all-and-retry is guarded against infinite loops
Testing signals
Testing is Go-test-first with heavy coverage in server/, model/parsers, model/renderers, middleware, mlxrunner, create, envconfig; testify is the assertion library. integration/ holds end-to-end suites gated on a live server/registry; CI runs go test -count=1 ./... plus a -race job, golangci-lint, patch-apply checks, vitest for the React app, and a benchmark pass.
- CI test.yaml runs `go test -count=1 -bench=. -benchtime=1x ./...` on PRs and a separate `go test -race -count=1 ./...` race job
- CI includes golangci-lint (golangci-lint-action@v9), go_mod_tidy and go_license checks, plus a patches job that verifies llama/server patches apply cleanly under CMake
- The desktop app is tested with `go test -tags updater_live ./app/...` and the React UI via `npm ci && npm test` (vitest) plus npm run build; Storybook config also present (build-storybook script)
- server/ has ~30 *_test.go files including routes_*_test.go per endpoint family, a fuzz test (create_fuzz_test.go), and sched_test.go for scheduler logic
- model/parsers and model/renderers have per-family test files plus reference-test files (nemotron*_reference_test.go) and shared testhelpers_test.go
- integration/ contains end-to-end tests (api_test, concurrency_test, max_queue_test, vision/audio tests, reg_* group files) that require a running server and real model pulls — documented in integration/README.md
- Test isolation uses OLLAMA_MODELS/home overrides: many packages ship test_home_test.go helpers to redirect model storage into temp dirs (inferred)
- template/ has a golden-file style test driven by embedded index.json + per-model .gotmpl/.json pairs (template_test.go)
- api/ tests include types_typescript_test.go which cross-checks Go API types against generated TypeScript (typescriptify dep in go.mod)
- Coverage gaps: Objective-C/macOS glue (app/cmd/app/*.m, discover/gpu_info_darwin.m) and the codex_desktop_autoreview/proxy hot paths have tests but the darwin app lifecycle is largely untestable in CI (build-tagged windows||darwin) (inferred)
Risk map
Main risks: the API has no request authentication by default and can be bound to non-loopback hosts via OLLAMA_HOST; the server spawns subprocesses (llama-server, self runner, gpu probes) with model-derived arguments; startup blob pruning deletes on-disk data; registry push/pull signs with a local private key; and several middleware paths decompress/transform untrusted request bodies. Scheduler and runner state is intricate (eviction, OOM retry, panic on model mismatch during load).
- The REST API is unauthenticated; OLLAMA_HOST can bind it to 0.0.0.0 and OLLAMA_ORIGINS CORS allows wildcards/browser extensions, so any reachable origin can pull/delete/run models unless the operator restricts it (inferred)
- Subprocess attack surface: llama-server is exec'd with flags assembled from request/model options (num_ctx, -ngl, -t, chat templates); the runner binary path and env are constructed in startLlamaServer/SetupLlamaServerCommandEnv
- Startup performs destructive maintenance: PruneLayers, manifest.PruneDirectory and fixBlobs delete blobs/manifests under OLLAMA_MODELS; guarded only by OLLAMA_NOPRUNE and a 1h grace period for fresh blobs
- Private signing key ~/.ollama/id_ed25519 (0600) is generated on first serve and used by auth.Sign for registry token exchange; realm host is checked against original host to avoid token leakage cross-origin
- --insecure / registryOptions.Insecure permits plain-HTTP registry traffic (errInsecureProtocol exists but can be bypassed by request flag)
- Request-body decompression is capped at 20MB (maxDecompressedBodySize) in the OpenAI middleware — a decompression-bomb guard; other endpoints bind JSON directly via gin ShouldBindJSON without explicit size limits
- Scheduler contains a deliberate panic when the active load's ModelPath differs from the evicted-retry request — a crash-on-invariant-violation that takes down the whole server
- Secret hygiene in logs: filteredEnv redacts env values containing API/KEY/TOKEN/SECRET/PASSWORD/CREDENTIAL/AUTH before logging subprocess env, but only CUDA_/ROCR_/ROCM_/HIP_/HSA_/GGML_/PATH/LD_LIBRARY_PATH/DYLD_LIBRARY_PATH keys are logged at all
- Codex desktop proxy restricts to loopback requests (isLoopbackRequest) and websocket upgrades are special-cased; misconfiguration here would expose upstream proxying on the shared listener
- Runner stream parsing bounds single response lines at 8MB (llamaServerStreamMaxBufferSize); unbounded growth in a misbehaving subprocess is otherwise handled only via HasExited/ping timeouts
- Legacy/removed features linger as explicit errors: LoRA adapters rejected (errAdaptersUnsupported), typical_p rejected, `useClient2` experiment warns-and-continues; dead flags like --experimental are hidden no-ops
- Blast radius: a single Scheduler serializes all model loads (activeLoading) so a stuck subprocess load stalls every inference request; queue overflow surfaces as ErrMaxQueue (OLLAMA_MAX_QUEUE default 512)
Extension points
Deliberate plug-in surfaces: per-model-family Parser and Renderer registries (name-keyed constructors with a switch fallback), embedded named chat templates, the llm.LlamaServer runner interface, cobra command table, launch.Default* UI hooks, middleware translators for new API dialects, envconfig's AsMap registry, and the create/ import pipeline stages.
- New output parsers plug in via parsers.Register(name, constructor) or a case in ParserForName's switch; Parser interface = Init/Add/PreservedTokens/HasToolSupport/HasThinkingSupport
- New prompt renderers plug in via renderers.Register or rendererForName switch; Renderer interface = Thinking/Render/LeadingBOS; RenderImgTags global toggles [img] tag emission
- Named Go templates are added as .gotmpl+.json pairs embedded via go:embed and indexed in template/index.json; template.Named resolves by GGUF chat_template name for autodetection
- New inference backends implement llm.LlamaServer (Completion/Chat/Embedding/Tokenize/WaitUntilRunning/Close/...) and get wired through Scheduler.newServerFn or the IsMLX branch (mlxrunner.Client)
- New API dialects slot into GenerateRoutes as gin middleware translators in middleware/ (ChatMiddleware, CompletionsMiddleware, ResponsesMiddleware, AnthropicMessagesMiddleware, TranscriptionMiddleware) wrapping the core handlers
- New CLI commands register in NewCLI's command table; hidden/internal commands (runner, gpu-discover) show the pattern for plumbing sub-binaries through the same binary
- Interactive UI is swappable via launch.Default* function hooks (SingleSelector, MultiSelector, SignIn, Upgrade, ConfirmPrompt, Spinner) — cmd/cmd.go's init() replaces them with Bubbletea TUI implementations
- New environment settings register in envconfig: typed accessors (Bool/Uint/String/BoolWithDefault) plus an entry in AsMap() so `ollama serve` logs and help list them
- GPU backends are build-time extensions: OLLAMA_LLAMA_BACKENDS selects cuda_v12/cuda_v13/rocm_v7_1/rocm_v7_2/vulkan/jetpack variants; runtime discovery globs lib/ollama/*/ggml-* dirs
- Safetensors import is a staged pipeline in create/ (classify -> transform -> prequant -> quantize -> writer -> manifest) with per-architecture files (gemma4.go, qwen35.go, cohere2moe.go, glimmer.go, nemotron_h.go, laguna.go) — new architectures add a file + classification entry
- Model capabilities are declared via model.Capability flags (completion, tools, insert, vision, audio, embedding, thinking, image) checked through Model.CheckCapabilities, gating handler behavior per request
Contributor handoff
Start with AGENTS.md and docs/development.md. Build Go-only via `go build .`/`go run . serve`; full builds need CMake (native payload under build/lib/ollama). Tests: `go test ./...` (race: `go test -race ./...`), vitest under app/ui/app, integration/ needs a live server. Read cmd/cmd.go, server/routes.go, server/sched.go, llm/llama_server.go first. Traps: dual runner paths (GGUF subprocess vs MLX self-runner), removed features that still error loudly, scheduler panics, and env-var-driven behavior.
- Authoritative onboarding docs: AGENTS.md (build commands), docs/development.md (prereqs, GPU backends, platform notes), docs/api.md (REST reference)
- Read-first files for server changes: cmd/cmd.go (CLI+RunServer), server/routes.go (GenerateRoutes + handlers), server/sched.go (Scheduler lifecycle), server/images.go (Model + pull/create/prune), llm/llama_server.go (runner subprocess)
- Shared types live in api/types.go and are the contract between CLI client, server handlers, and the generated TypeScript (checked by api/types_typescript_test.go) — change them carefully
- Model support additions typically touch four places: model/parsers (output), model/renderers (prompt), template/ (named .gotmpl), and server/images.go capability/template selection — plus create/ for safetensors architectures (inferred)
- Safe edit boundaries: middleware/ translators and model/{parsers,renderers} are well-isolated and heavily tested; sched.go and llm/llama_server.go are high-blast-radius (concurrency + subprocess lifecycle) — add tests in the same package's *_test.go (inferred)
- Known traps: (a) LoRA adapters and typical_p are removed and error on use; (b) NumGPU==-1 means auto, 0 means CPU-only — don't collapse; (c) num_ctx auto-detection is VRAM-tiered (numCtxAuto flag) and OOM retry reduces it once; (d) scheduler model keys join shard paths with NUL
- Environment knobs for debugging: OLLAMA_DEBUG=1 (log level), OLLAMA_DEBUG_LOG_REQUESTS (request replay logs to temp dir), OLLAMA_LOAD_TIMEOUT (stall detection), OLLAMA_NOPRUNE (disable startup deletion), OLLAMA_HOST/OLLAMA_MODELS (paths/bind)
- Test commands: `go test -count=1 ./...` locally (some packages need CGO/native payload), `go test -race ./...` mirrors CI race job, `npm test`/`npm run build` under app/ui/app; integration tests are opt-in (need pulled models + running server)
- Platform-conditional code uses file-suffix build tags (llm_linux.go, llm_darwin.go, llm_windows.go, editor_unix.go, start_darwin.go) — edit the right variant and keep signatures identical across OSes
- Gin runs in DebugMode by default (mode var = gin.DebugMode with a defensive switch); don't rely on release-mode assumptions in handlers
- The repo mixes vendored native code (llama/ llama.cpp fork, mlx/) with Go; changes under llama/server or cmake/ trigger the `patches` CI job verifying patches apply — avoid touching unless intentional
- Progress reporting convention: long operations (pull/create/push) emit api.ProgressResponse structs over a channel consumed by streamResponse — new streaming endpoints should reuse that pattern
Languages
| Language | Files | Share of source |
|---|---|---|
| Go | 774 | 82% |
| TypeScript | 104 | 11% |
| Markdown | 76 | docs/config |
| C | 46 | 5% |
| JSON | 32 | docs/config |
| Shell | 10 | 1% |
| YAML | 9 | docs/config |
| C++ | 4 | 0% |
Start reading here
Probable source entrypoint: cmd/bench — inferred from the directory tree and manifest, not the upstream docs.
Source roots
app/ (237 files)
Source layout — app/
| Path | Files |
|---|---|
app/auth/ | 1 |
app/cmd/ | 22 |
app/logrotate/ | 2 |
app/tools/ | 11 |
app/types/ | 3 |
app/ui/ | 139 |
app/webview/ | 4 |
app/ollama.rc | 1 |
Repository structure
| Top-level path | Files |
|---|---|
app/ | 237 |
mlxrunner/ | 141 |
template/ | 104 |
model/ | 102 |
cmd/ | 96 |
mlx/ | 88 |
docs/ | 77 |
server/ | 61 |
Docs found: AGENTS.mdCLAUDE.mdCONTRIBUTING.mdREADME.mddocs/README.mddocs/api.mddocs/development.mddocs/examples.mddocs/tools/extract-examples/README.md
Package
go.mod — github.com/ollama/ollama, 0 declared dependencies.
CI & config entrypoints
README.md— Repository readmeAGENTS.md— Agent instructionsCLAUDE.md— Claude instructionsapp/ui/app/vite.config.ts— Vite configapp/ui/app/src/main.tsx— Vite React entrypointapp/ui/app/package.json— npm scripts: build, build-storybook, dev, lint, prettier, prettier:check, preview, storybook
Structural health signals
Average score 6.4/10 across 96 analyzed source files; 48 hotspots surfaced.
app/ui/app/src/components/ChatForm.tsx— 1013 lines, score 5 (Large file, Deep nesting)app/ui/app/src/components/Message.tsx— 990 lines, score 5 (Large file, Deep nesting)server/routes_generate_test.go— 1570 lines, score 5.2 (Large file, Long function/block)
These are deterministic review leads — size, churn, and structural signals — not proof of a bug in this project.
Recent history
6383a0fa9cbf2026-09-18 — server: allow registry cross-host redirects among allowlisted hosts (#18533)d0c8cdb795d42026-09-18 — api: expose model thinking levels and defaults (#18473)9a44d9d8de712026-09-18 — app: keep closed macOS windows from reopening on activation (#18518)4f6f739830362026-09-17 — tests: fix metadata deletion test flake (#18493)2c73164246532026-09-17 — nemotron_h: add MLX vision support (#17714)