feat: Go backend, enhanced search, new widgets, Docker deploy
Major changes: - Add Go backend (backend/) with microservices architecture - Enhanced master-agents-svc: reranker, content-classifier, stealth-crawler, proxy-manager, media-search, fastClassifier, language detection - New web-svc widgets: KnowledgeCard, ProductCard, ProfileCard, VideoCard, UnifiedCard, CardGallery, InlineImageGallery, SourcesPanel, RelatedQuestions - Improved discover-svc with discover-db integration - Docker deployment improvements (Caddyfile, vendor.sh, BUILD.md) - Library-svc: project_id schema migration - Remove deprecated finance-svc and travel-svc - Localization improvements across services Made-with: Cursor
This commit is contained in:
128
backend/internal/agent/researcher.go
Normal file
128
backend/internal/agent/researcher.go
Normal file
@@ -0,0 +1,128 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gooseek/backend/internal/llm"
|
||||
"github.com/gooseek/backend/internal/search"
|
||||
"github.com/gooseek/backend/internal/session"
|
||||
"github.com/gooseek/backend/internal/types"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type ResearchInput struct {
|
||||
ChatHistory []llm.Message
|
||||
FollowUp string
|
||||
Classification *ClassificationResult
|
||||
Mode Mode
|
||||
Sources []string
|
||||
Locale string
|
||||
DetectedLang string
|
||||
IsArticleSummary bool
|
||||
}
|
||||
|
||||
func research(
|
||||
ctx context.Context,
|
||||
sess *session.Session,
|
||||
llmClient llm.Client,
|
||||
searchClient *search.SearXNGClient,
|
||||
input ResearchInput,
|
||||
) ([]types.Chunk, error) {
|
||||
maxIterations := 1
|
||||
switch input.Mode {
|
||||
case ModeBalanced:
|
||||
maxIterations = 3
|
||||
case ModeQuality:
|
||||
maxIterations = 10
|
||||
}
|
||||
|
||||
researchBlockID := uuid.New().String()
|
||||
sess.EmitBlock(types.NewResearchBlock(researchBlockID))
|
||||
|
||||
allResults := make([]types.Chunk, 0)
|
||||
seenURLs := make(map[string]bool)
|
||||
|
||||
searchQuery := input.Classification.StandaloneFollowUp
|
||||
if searchQuery == "" {
|
||||
searchQuery = input.FollowUp
|
||||
}
|
||||
|
||||
for i := 0; i < maxIterations; i++ {
|
||||
queries := generateSearchQueries(searchQuery)
|
||||
|
||||
sess.UpdateBlock(researchBlockID, []session.Patch{
|
||||
{
|
||||
Op: "replace",
|
||||
Path: "/data/subSteps",
|
||||
Value: []types.ResearchSubStep{
|
||||
{
|
||||
ID: uuid.New().String(),
|
||||
Type: "searching",
|
||||
Searching: queries,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
for _, q := range queries {
|
||||
resp, err := searchClient.Search(ctx, q, &search.SearchOptions{
|
||||
Categories: categoriesToSearch(input.Sources),
|
||||
PageNo: 1,
|
||||
})
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, r := range resp.Results {
|
||||
if r.URL != "" && !seenURLs[r.URL] {
|
||||
seenURLs[r.URL] = true
|
||||
allResults = append(allResults, r.ToChunk())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if input.Mode == ModeSpeed {
|
||||
break
|
||||
}
|
||||
|
||||
if len(allResults) >= 20 && input.Mode == ModeBalanced {
|
||||
break
|
||||
}
|
||||
|
||||
if len(allResults) >= 50 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return allResults, nil
|
||||
}
|
||||
|
||||
func categoriesToSearch(sources []string) []string {
|
||||
if len(sources) == 0 {
|
||||
return []string{"general", "news"}
|
||||
}
|
||||
|
||||
categories := make([]string, 0)
|
||||
for _, s := range sources {
|
||||
switch s {
|
||||
case "web":
|
||||
categories = append(categories, "general")
|
||||
case "discussions":
|
||||
categories = append(categories, "social media")
|
||||
case "academic":
|
||||
categories = append(categories, "science")
|
||||
case "news":
|
||||
categories = append(categories, "news")
|
||||
case "images":
|
||||
categories = append(categories, "images")
|
||||
case "videos":
|
||||
categories = append(categories, "videos")
|
||||
}
|
||||
}
|
||||
|
||||
if len(categories) == 0 {
|
||||
return []string{"general"}
|
||||
}
|
||||
|
||||
return categories
|
||||
}
|
||||
Reference in New Issue
Block a user