feat(control-center): P2 document vector store — ingestion, chunking, embedding, hybrid search
- internal/controlcenter/embed: OpenAI-compatible /embeddings client
(batch<=16, 30s timeout, 5xx/network retried once, 4xx not), Embedder
interface, deterministic offline Stub, pgvector literal formatting
- internal/controlcenter/docs: .doc/**/*.md sync into cc_documents with
sha256 diffing and vanished-file removal; YAML front matter -> jsonb,
title fallback, taxonomy from first .doc dir; heading-based chunking
with paragraph bisection over ~1800 est. tokens; chunk_hash idempotent
inserts (unchanged chunks keep embeddings); embedding failures degrade
to NULL vectors without failing the sync; IndexArtifact for
cc_stage_artifacts; StartPeriodic ticker (CC_DOC_SYNC_SECONDS)
- server: GET /api/v1/docs (taxonomy/q filters), /api/v1/docs/{id},
/api/v1/docs/search (semantic|keyword|hybrid, ts_rank+ILIKE keyword
fallback, 0.6/0.4 max-normalized fusion, degraded flag when embedding
unavailable); async artifact indexing hooked into agent artifacts and
external-submit handlers
- archtest module-boundaries allowlist updated for new packages
This commit is contained in:
@@ -16,6 +16,8 @@ import (
|
||||
"time"
|
||||
|
||||
"chat-agent-system/internal/controlcenter/config"
|
||||
"chat-agent-system/internal/controlcenter/docs"
|
||||
"chat-agent-system/internal/controlcenter/embed"
|
||||
"chat-agent-system/internal/controlcenter/server"
|
||||
"chat-agent-system/internal/controlcenter/store"
|
||||
)
|
||||
@@ -77,6 +79,23 @@ func cmdServe(args []string) error {
|
||||
}
|
||||
srv := server.New(cfg, st)
|
||||
|
||||
var emb *embed.HTTPClient
|
||||
if cfg.EmbeddingEndpoint != "" {
|
||||
emb = embed.NewHTTP(cfg.EmbeddingEndpoint, cfg.EmbeddingAPIKey, cfg.EmbeddingModel, embed.Dim)
|
||||
} else {
|
||||
slog.Warn("embedding endpoint not configured; search runs keyword-only")
|
||||
}
|
||||
syncer := docs.New(st, cfg.RepoRoot, emb)
|
||||
var embIface embed.Embedder
|
||||
if emb != nil {
|
||||
embIface = emb
|
||||
}
|
||||
srv.SetDocs(embIface, syncer)
|
||||
|
||||
syncCtx, stopSync := context.WithCancel(ctx)
|
||||
defer stopSync()
|
||||
syncer.StartPeriodic(syncCtx, time.Duration(cfg.DocSyncSecond)*time.Second)
|
||||
|
||||
reapCtx, stopReaper := context.WithCancel(ctx)
|
||||
defer stopReaper()
|
||||
srv.StartLeaseReaper(reapCtx)
|
||||
@@ -86,6 +105,7 @@ func cmdServe(args []string) error {
|
||||
sig := make(chan os.Signal, 1)
|
||||
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
|
||||
<-sig
|
||||
stopSync()
|
||||
stopReaper()
|
||||
shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
Reference in New Issue
Block a user