Skip to content

pkg/miner: pluggable inference-engine backend interface (closes 3 TODOs)#2

Merged
zeekay merged 1 commit into
luxfi:mainfrom
abhicris:feat/pluggable-inference-backends
Apr 22, 2026
Merged

pkg/miner: pluggable inference-engine backend interface (closes 3 TODOs)#2
zeekay merged 1 commit into
luxfi:mainfrom
abhicris:feat/pluggable-inference-backends

Conversation

@abhicris
Copy link
Copy Markdown
Contributor

Closes #1.

Summary

Replaces three // TODO: Integrate with actual ... stubs in pkg/miner/miner.go with a small pluggable backend interface. The miner's runInference, runChat, and runEmbedding now dispatch through backend.InferenceBackend instead of inlining placeholder output.

Two reference backends ship in-tree:

Package Name Purpose
pkg/miner/backend/noop noop Deterministic mock, byte-for-byte identical to the pre-refactor inline stubs. Default. Zero config.
pkg/miner/backend/openai openai OpenAI-compatible HTTP adapter built on net/http. Covers llama.cpp, vllm, ollama, LocalAI, and api.openai.com via OPENAI_API_BASE.

No new go.mod dependencies.

Why one OpenAI-compatible adapter instead of direct bindings

llama.cpp bindings pull in ~20 MB of C source. vllm is Python-only. MLX bindings require CGo. But all of them — plus ollama and LocalAI — expose an OpenAI-compatible /v1/chat/completions + /v1/embeddings surface. One small Go adapter covers every engine an operator would realistically run, and the interface still lets someone add a direct-binding backend in a follow-up PR if latency-sensitive deployments need it.

Config changes

miner.Config gains five optional fields:

  • Backend string"noop" (default) or "openai"
  • OpenAIBase string — e.g. http://localhost:11434/v1 (ollama), http://localhost:8080/v1 (llama.cpp)
  • OpenAIAPIKey string — bearer token, empty is fine for local engines
  • OpenAIModel string — default model name
  • OpenAIEmbeddingModel string — optional override for embed tasks

Unknown Backend values fall back to noop so operator typos don't crash-loop the miner.

Sibling change: GPUStatsProvider hook

Adds a GPUStatsProvider hook on Miner:

m.SetGPUStatsProvider(func() (util float64, mem uint64) { ... })

GetStats merges its output into the returned Stats. Default is nil = no-op, matching current behaviour. A follow-up PR will wire a real NVML/MLX provider; this leaves the seam in place without pulling heavy bindings into the main binary.

Compatibility

  • Existing miner_test.go passes unchanged.
  • DefaultConfig() keeps producing a noop miner — zero behaviour change for current callers.
  • No go.mod churn.

Files

New:

  • pkg/miner/backend/backend.go — interface + request/response types
  • pkg/miner/backend/backend_test.go — interface contract tests
  • pkg/miner/backend/noop/noop.go + noop_test.go — deterministic mock
  • pkg/miner/backend/openai/openai.go + openai_test.go — HTTP adapter (httptest-mocked tests)
  • pkg/miner/backend/README.md — operator-facing doc with engine pointer commands

Modified:

  • pkg/miner/miner.go — backend wiring, Config extensions, GPU hook
  • pkg/miner/miner_test.go — added 7 tests for new wiring; existing 10 unchanged

Test output

ok  github.com/luxfi/ai/pkg/miner                   0.522s (17 tests)
ok  github.com/luxfi/ai/pkg/miner/backend           0.185s (3 tests)
ok  github.com/luxfi/ai/pkg/miner/backend/noop      0.336s (5 tests)
ok  github.com/luxfi/ai/pkg/miner/backend/openai    0.508s (10 tests)

Full-repo go build ./..., go vet ./..., and go test ./... all green.


Contributed by kcolbchain (https://kcolbchain.com) · https://abhishekkrishna.com

Close three `// TODO: Integrate with actual ...` stubs in
pkg/miner/miner.go (runInference, runChat, runEmbedding) by introducing
a small pluggable backend interface. The miner now dispatches through
backend.InferenceBackend rather than inlining placeholder output.

Two reference backends ship in-tree:

- pkg/miner/backend/noop  — deterministic mock, byte-for-byte identical
  to the pre-refactor inline stubs. Default. Zero config, zero deps.
- pkg/miner/backend/openai — OpenAI-compatible HTTP adapter built on
  net/http. Covers llama.cpp, vllm, ollama, LocalAI, and api.openai.com
  via OPENAI_API_BASE. No new go.mod dependencies.

Config gains Backend / OpenAIBase / OpenAIAPIKey / OpenAIModel /
OpenAIEmbeddingModel fields. Unknown backend values fall back to noop so
operator typos don't crash-loop the miner. Existing miner_test.go passes
unchanged; DefaultConfig() behaviour is preserved.

Also wire a GPUStatsProvider hook on Miner so GetStats can surface
best-effort GPU telemetry (GPUUtilization, MemoryUsed) without pulling
NVML/MLX bindings into the main binary. Default is nil = no-op, matching
current behaviour; a follow-up PR will wire a real provider.

Closes luxfi#1.

Contributed by kcolbchain (https://kcolbchain.com) · https://abhishekkrishna.com
@zeekay zeekay merged commit 9371835 into luxfi:main Apr 22, 2026
6 of 7 checks passed
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.

pkg/miner: pluggable inference-engine backend interface (closes 3 TODOs)

3 participants