mirror of
https://github.com/luxfi/ai.git
synced 2026-10-30 17:02:43 +00:00
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/ai#1. Contributed by kcolbchain (https://kcolbchain.com) ยท https://abhishekkrishna.com
87 lines
2.7 KiB
Go
87 lines
2.7 KiB
Go
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
// Package noop provides a deterministic in-process InferenceBackend. It
|
|
// preserves the placeholder behaviour that was inlined into
|
|
// pkg/miner/miner.go before the backend interface landed, so existing tests
|
|
// and downstream consumers that rely on "some response comes back" keep
|
|
// working with zero configuration.
|
|
//
|
|
// This backend performs no real inference. Use it for local dev, CI, and as
|
|
// the safe default when an operator hasn't configured a real engine.
|
|
package noop
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/luxfi/ai/pkg/miner/backend"
|
|
)
|
|
|
|
// DefaultEmbeddingDims matches the placeholder dim used by the pre-refactor
|
|
// embedding stub in pkg/miner/miner.go (len(embedding) == 384).
|
|
const DefaultEmbeddingDims = 384
|
|
|
|
// Backend is a deterministic mock implementing backend.InferenceBackend.
|
|
type Backend struct {
|
|
// EmbeddingDims controls the length of the zero-vector returned by
|
|
// Embed. Defaults to DefaultEmbeddingDims when zero.
|
|
EmbeddingDims int
|
|
}
|
|
|
|
// New returns a new noop backend with default embedding dimensionality.
|
|
func New() *Backend {
|
|
return &Backend{EmbeddingDims: DefaultEmbeddingDims}
|
|
}
|
|
|
|
// Name implements backend.InferenceBackend.
|
|
func (*Backend) Name() string { return "noop" }
|
|
|
|
// Capabilities implements backend.InferenceBackend.
|
|
func (b *Backend) Capabilities() backend.Capabilities {
|
|
dims := b.EmbeddingDims
|
|
if dims == 0 {
|
|
dims = DefaultEmbeddingDims
|
|
}
|
|
return backend.Capabilities{
|
|
Chat: true,
|
|
Inference: true,
|
|
Embedding: true,
|
|
EmbeddingDims: dims,
|
|
}
|
|
}
|
|
|
|
// Chat returns a fixed assistant message. Identical to the string returned by
|
|
// the previous inline stub in miner.runChat.
|
|
func (b *Backend) Chat(_ context.Context, req backend.ChatRequest) (backend.ChatResponse, error) {
|
|
return backend.ChatResponse{
|
|
Role: "assistant",
|
|
Content: "I'm an AI assistant running on the Lux network.",
|
|
Model: req.Model,
|
|
}, nil
|
|
}
|
|
|
|
// Inference echoes the prompt, matching the previous inline stub in
|
|
// miner.runInference.
|
|
func (b *Backend) Inference(_ context.Context, req backend.InferenceRequest) (backend.InferenceResponse, error) {
|
|
return backend.InferenceResponse{
|
|
Text: fmt.Sprintf("Response to: %s", req.Prompt),
|
|
Tokens: 10,
|
|
Model: req.Model,
|
|
}, nil
|
|
}
|
|
|
|
// Embed returns a zero vector of EmbeddingDims length โ byte-for-byte identical
|
|
// to the pre-refactor miner.runEmbedding placeholder.
|
|
func (b *Backend) Embed(_ context.Context, req backend.EmbedRequest) (backend.EmbedResponse, error) {
|
|
dims := b.EmbeddingDims
|
|
if dims == 0 {
|
|
dims = DefaultEmbeddingDims
|
|
}
|
|
vec := make([]float64, dims)
|
|
return backend.EmbedResponse{
|
|
Embedding: vec,
|
|
Model: req.Model,
|
|
}, nil
|
|
}
|