Files
2026-03-24 06:18:16 +08:00

88 lines
2.5 KiB
Go

package builtin
import (
"log/slog"
"strconv"
"strings"
"github.com/memohai/memoh/internal/config"
dbsqlc "github.com/memohai/memoh/internal/db/sqlc"
adapters "github.com/memohai/memoh/internal/memory/adapters"
storefs "github.com/memohai/memoh/internal/memory/storefs"
)
// BuiltinMemoryMode represents the operating mode of the built-in memory provider.
type BuiltinMemoryMode string
const (
ModeOff BuiltinMemoryMode = "off"
ModeSparse BuiltinMemoryMode = "sparse"
ModeDense BuiltinMemoryMode = "dense"
)
// NewBuiltinRuntimeFromConfig returns the appropriate memoryRuntime based on
// the provider's persisted config (memory_mode field). Returns the file
// runtime for "off" or unknown modes. Returns an error if a sparse or dense
// runtime was explicitly requested but failed to initialise, so that callers
// can surface configuration problems rather than silently degrading.
func NewBuiltinRuntimeFromConfig(_ *slog.Logger, providerConfig map[string]any, fileRuntime any, store *storefs.Service, queries *dbsqlc.Queries, cfg config.Config) (any, error) {
mode := BuiltinMemoryMode(strings.TrimSpace(adapters.StringFromConfig(providerConfig, "memory_mode")))
switch mode {
case ModeSparse:
host, port := parseQdrantHostPort(cfg.Qdrant.BaseURL)
if host == "" {
host = "localhost"
}
if port == 0 {
port = 6334
}
collection := adapters.StringFromConfig(providerConfig, "qdrant_collection")
if collection == "" {
collection = "memory_sparse"
}
return newSparseRuntime(
host,
port,
cfg.Qdrant.APIKey,
collection,
strings.TrimSpace(cfg.Sparse.BaseURL),
store,
)
case ModeDense:
return newDenseRuntime(providerConfig, queries, cfg, store)
default:
return fileRuntime, nil
}
}
// parseQdrantHostPort extracts host and gRPC port from a Qdrant base URL.
// Qdrant base URLs are typically HTTP (port 6333), but the gRPC port is 6334.
func parseQdrantHostPort(baseURL string) (string, int) {
baseURL = strings.TrimSpace(baseURL)
if baseURL == "" {
return "", 0
}
baseURL = strings.TrimPrefix(baseURL, "http://")
baseURL = strings.TrimPrefix(baseURL, "https://")
parts := strings.SplitN(baseURL, ":", 2)
host := parts[0]
if len(parts) == 2 {
httpPort, err := strconv.Atoi(strings.TrimRight(parts[1], "/"))
if err == nil {
switch httpPort {
case 6333:
return host, 6334
case 6334:
return host, 6334
default:
// Common case: operator already configured the intended gRPC port.
return host, httpPort
}
}
}
return host, 6334
}