Initial commit of Descrybe v2 without local scratch artifacts.

Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
This commit is contained in:
2026-08-09 22:47:43 +02:00
commit 8580c996c3
1285 changed files with 325780 additions and 0 deletions
@@ -0,0 +1,64 @@
package platformsettings
import (
"context"
"errors"
"strings"
"github.com/descrybe/descrybe-v2/apps/api/internal/processing"
)
// DynamicPinecone resolves platform settings on each call so admin changes
// apply without restarting the worker. Embeddings use admin AI role
// "vectorization" (ResolveAIConfig) with OPENAI_EMBEDDING_* / OPENAI_* env fallback.
type DynamicPinecone struct {
Settings *Service
}
func (d *DynamicPinecone) Enabled() bool {
if d == nil || d.Settings == nil {
return false
}
cfg, err := d.Settings.ResolvePinecone(context.Background())
return err == nil && cfg.Configured()
}
func (d *DynamicPinecone) SuggestCategory(ctx context.Context, companyID, productText string, candidates []string) (string, error) {
if d == nil || d.Settings == nil {
return "", errors.New("pinecone not configured")
}
cfg, err := d.Settings.ResolvePinecone(ctx)
if err != nil {
return "", err
}
if !cfg.Configured() {
return "", errors.New("pinecone not configured")
}
cat := processing.NewPineconeCategorizer(cfg.APIKey, cfg.Host, cfg.Namespace)
if emb, eerr := d.Settings.ResolveEmbedder(ctx); eerr == nil && emb != nil {
cat.Embedder = emb
}
return cat.SuggestCategory(ctx, companyID, productText, candidates)
}
// ResolveEmbedder builds an OpenAI-compatible Embedder from admin AI role
// "vectorization" (DB), falling back to OPENAI_EMBEDDING_* then OPENAI_* env.
// Returns (nil, nil) when unset so callers can keep Pinecone text-query mode.
func (s *Service) ResolveEmbedder(ctx context.Context) (processing.Embedder, error) {
if s == nil {
return nil, nil
}
cfg, err := s.ResolveAIConfig(ctx, AIRoleVectorization)
if err != nil {
return nil, err
}
if strings.TrimSpace(cfg.APIKey) == "" {
return nil, nil
}
model := strings.TrimSpace(cfg.Model)
if model == "" {
model = defaultEmbeddingModel
}
client := processing.NewOpenAIClient(cfg.APIKey, cfg.BaseURL, model, 0, 3)
return client, nil
}