3bb82a90db
MemoryEvalConfig and EmailConfig, with their two constants and their normalise arms. Neither loop can speak, which is why they read together. The shared defaults const block now holds only the core daemon's own; every other block keeps its defaults beside its struct.
70 lines
2.9 KiB
Go
70 lines
2.9 KiB
Go
package config
|
|
|
|
import "time"
|
|
|
|
// Two loops that run behind the conversation and never speak. Both are absent
|
|
// by default, and both follow the same rule as every other cost the owner did
|
|
// not ask for: present-but-empty (`{}`) is a valid "on with the defaults".
|
|
|
|
// MemoryEvalConfig — the background memory-evaluation loop (Vikunja #248).
|
|
// Absent ⇒ off, like every other capability that costs something the owner did
|
|
// not ask for. Each evaluation is a full LLM round-trip on the one resident
|
|
// model, which is the same model answering him; running it hourly by default
|
|
// would put a multi-second stall in front of an occasional voice turn for a
|
|
// feature he may not want.
|
|
//
|
|
// The loop only ever writes notes (source infer:memory-eval, visible on
|
|
// /dash). It cannot speak — see internal/memeval.
|
|
type MemoryEvalConfig struct {
|
|
// Interval — how often to evaluate. 0 ⇒ DefaultMemoryEvalInterval.
|
|
Interval Duration `json:"interval,omitempty"`
|
|
|
|
// MaxItems — recent facts / notes / nudges fed into one evaluation.
|
|
// 0 ⇒ memeval.DefaultMaxItems.
|
|
MaxItems int `json:"max_items,omitempty"`
|
|
|
|
// MinConfidence — observations the model scores below this are dropped.
|
|
// 0 ⇒ memeval.DefaultMinConfidence.
|
|
MinConfidence float64 `json:"min_confidence,omitempty"`
|
|
}
|
|
|
|
// DefaultMemoryEvalInterval — the plan's cadence (1h) for the memory
|
|
// evaluation loop, applied only when the block is present at all.
|
|
const DefaultMemoryEvalInterval = time.Hour
|
|
|
|
// normaliseMemoryEval leaves an absent block nil (⇒ no evaluation loop) and
|
|
// gives a present one the plan's cadence.
|
|
func (c *Config) normaliseMemoryEval() {
|
|
if c.MemoryEval != nil && c.MemoryEval.Interval <= 0 {
|
|
c.MemoryEval.Interval = Duration(DefaultMemoryEvalInterval)
|
|
}
|
|
}
|
|
|
|
// EmailConfig — core's half of the email reader: how many task candidates one
|
|
// message may produce, and how long the extraction call may take.
|
|
//
|
|
// There is deliberately nothing about a mailbox here. Core does not connect to
|
|
// IMAP, does not know an account exists, and holds no mail credential — the
|
|
// reader daemon does, the same split mavpoll uses for the zenmoney token. This
|
|
// block only says "extraction is allowed, with these bounds".
|
|
type EmailConfig struct {
|
|
// MaxTasks — candidates per message. 0 ⇒ email.MaxCandidates (3).
|
|
MaxTasks int `json:"max_tasks,omitempty"`
|
|
|
|
// Timeout — per-message extraction budget. 0 ⇒ DefaultEmailTimeout. This is
|
|
// a Thinking model reading a mail; nobody is waiting on the answer, but a
|
|
// hung llama-server must not pin the reader's connection forever.
|
|
Timeout Duration `json:"timeout,omitempty"`
|
|
}
|
|
|
|
// DefaultEmailTimeout — extraction budget per message.
|
|
const DefaultEmailTimeout = 2 * time.Minute
|
|
|
|
// normaliseEmail leaves an absent block nil (⇒ mail ingestion refused) and
|
|
// gives a present one the timeout default.
|
|
func (c *Config) normaliseEmail() {
|
|
if c.Email != nil && c.Email.Timeout <= 0 {
|
|
c.Email.Timeout = Duration(DefaultEmailTimeout)
|
|
}
|
|
}
|