package tools import ( "context" "errors" "gitea.stevedudenhoeffer.com/steve/executus/tool" ) // StoreDeps wires the persistent-memory tools (kv_* and file_*). A host // supplies its KV and/or File backends; the kv group registers only when KV is // set and the file group only when Files is set, so a host can take just one. // Everything else has a sensible default: // // - Quota defaults to a generous static cap (a host that meters per-skill // storage supplies its own QuotaProvider). // - FileSearch / Minter+BaseURL are optional — file_search and // create_file_url register only when wired. // - MaxValueBytes / MaxFileBytes default when non-positive. type StoreDeps struct { KV KVStorage Files FileStorage Quota QuotaProvider FileSearch FileSearcher Minter FileTokenMinter BaseURL string MaxValueBytes int // kv_set per-value cap; default 256 KiB MaxFileBytes int // file_save per-file cap; default 16 MiB } // RegisterStore registers the kv_* tools (when KV is set) and the file_* tools // (when Files is set). At least one of KV/Files is required. func RegisterStore(reg tool.Registry, d StoreDeps) error { if d.KV == nil && d.Files == nil { return errors.New("tools: RegisterStore needs at least KV or Files") } if d.Quota == nil { d.Quota = staticQuota{kvMax: 64 << 20, filesMax: 1 << 30} } if d.MaxValueBytes <= 0 { d.MaxValueBytes = 256 << 10 } if d.MaxFileBytes <= 0 { d.MaxFileBytes = 16 << 20 } var ts []tool.Tool if d.KV != nil { ts = append(ts, NewKVGet(d.KV), NewKVSet(d.KV, d.Quota, d.MaxValueBytes), NewKVList(d.KV), NewKVDelete(d.KV), ) } if d.Files != nil { ts = append(ts, NewFileSave(d.Files, d.Quota, d.MaxFileBytes), NewFileGet(d.Files), NewFileGetText(d.Files), NewFileGetMetadata(d.Files), NewFileList(d.Files), NewFileDelete(d.Files), ) if d.FileSearch != nil { ts = append(ts, NewFileSearch(d.FileSearch)) } if d.Minter != nil && d.BaseURL != "" { ts = append(ts, NewCreateFileURL(d.Minter, d.Files, d.BaseURL)) } } return registerAll(reg, ts...) } // staticQuota is the default QuotaProvider: a fixed KV/file byte cap for every // skill. A host that needs per-skill metering supplies its own. type staticQuota struct{ kvMax, filesMax int64 } func (q staticQuota) EffectiveQuota(context.Context, string) (kvMax, filesMax int64, err error) { return q.kvMax, q.filesMax, nil }