Files
kyle b6e1cdf825 p3: map Brave LLM Context; RRF merge; per-source no_rerank
Live llm/context hits live in grounding.generic plus a URL-keyed
sources map, not a sources array. Fan-in uses reciprocal-rank fusion
instead of cosine. no_rerank keeps that source's own order as a prefix.
2026-09-23 16:02:21 -07:00

113 lines
2.6 KiB
Go

package config
import (
"os"
"time"
"github.com/pelletier/go-toml/v2"
)
// File is the on-disk /etc/sift/config.toml.
type File struct {
Listen string `toml:"listen"`
UserAgent string `toml:"user_agent"`
DenyPrefixes []string `toml:"deny_prefixes"`
SelfIP SelfIP `toml:"self_ip"`
Dixie Dixie `toml:"dixie"`
Digest Digest `toml:"digest"`
Context Context `toml:"context"`
Search Search `toml:"search"`
}
type Dixie struct {
Chat string `toml:"chat"`
Embed string `toml:"embed"`
EmbedModel string `toml:"embed_model"`
MaxInflight int `toml:"max_inflight"`
QueueDepth int `toml:"queue_depth"`
QueueWait string `toml:"queue_wait"`
}
type Digest struct {
Model string `toml:"model"`
Thinking bool `toml:"thinking"`
Cache string `toml:"cache"`
}
type Context struct {
Honcho string `toml:"honcho"`
Workspaces []string `toml:"workspaces"`
PermitRestricted []string `toml:"permit_restricted"`
}
// Search is the [search] block. Sources default off; bake-off picks defaults.
type Search struct {
K int `toml:"k"`
Timeout string `toml:"timeout"`
Rerank *bool `toml:"rerank"`
Digest bool `toml:"digest"`
CacheTTL string `toml:"cache_ttl"`
SearxNG SearchSource `toml:"searxng"`
BraveLLM SearchSource `toml:"brave_llm"`
Tavily TavilySource `toml:"tavily"`
}
type SearchSource struct {
Enabled bool `toml:"enabled"`
URL string `toml:"url"`
NoRerank bool `toml:"no_rerank"`
}
type TavilySource struct {
Enabled bool `toml:"enabled"`
URL string `toml:"url"`
DailyCreditCap int `toml:"daily_credit_cap"`
NoRerank bool `toml:"no_rerank"`
}
func (s Search) RerankOn() bool {
if s.Rerank == nil {
return true
}
return *s.Rerank
}
func (s Search) AnyEnabled() bool {
return s.SearxNG.Enabled || s.BraveLLM.Enabled || s.Tavily.Enabled
}
// SelfIP is the [self_ip] block.
type SelfIP struct {
Sources []string `toml:"sources"`
Interval string `toml:"interval"`
KeepPrevious string `toml:"keep_previous"`
Path string `toml:"path"`
}
// Load reads path. A missing file returns a zero File and a nil error.
func Load(path string) (File, error) {
var f File
b, err := os.ReadFile(path)
if err != nil {
if os.IsNotExist(err) {
return f, nil
}
return f, err
}
if err := toml.Unmarshal(b, &f); err != nil {
return File{}, err
}
return f, nil
}
func ParseDuration(s string, def time.Duration) time.Duration {
if s == "" {
return def
}
d, err := time.ParseDuration(s)
if err != nil {
return def
}
return d
}