p3: search API, pinned sources, cache, CLI

POST /v1/search and /v2/search fan in SearXNG, Brave LLM Context, and
Tavily from config-fixed endpoints. Public sources refuse private A
records; SearXNG is a loopback-only client, not the fetch guard.

Cache keys include caller class. Restricted callers search like the
fleet; logs omit query, hosts, URLs, and upstream errors. Degraded
results are not stored. Tavily sends search_depth=basic and drops
answer. Missing keys surface in /healthz.

Default-on sources stay off until the bake-off. Query harvest is not
in this commit.
This commit is contained in:
2026-09-23 12:17:51 -07:00
parent 3687636ed7
commit d7873403ff
27 changed files with 2361 additions and 21 deletions
+21
View File
@@ -210,6 +210,27 @@ func (e *Engine) embedModel() string {
return "honcho-embed"
}
// Embed is the search-rerank entry. Same gate as digest.
func (e *Engine) Embed(ctx context.Context, inputs []string) ([][]float64, error) {
return e.embed(ctx, inputs)
}
func (e *Engine) Acquire(ctx context.Context) (bool, string) {
if e == nil {
return false, "no embed"
}
if e.EmbedURL == "" {
return false, "no embed"
}
return e.Gate.Acquire(ctx)
}
func (e *Engine) Release() {
if e != nil {
e.Gate.Release()
}
}
func (e *Engine) logFallback(reason string, err error) {
e.noteFallback(reason)
if e == nil || e.Log == nil {