feat: semantic search with Qdrant + Ollama embeddings
- Add SemanticSearchService with embed() + searchQdrant() methods - Add GET /api/search/semantic endpoint (?q=query&k=5) - Wire SemanticSearchService into router and cmd/server/main.go - Add SemanticSearch React page with results + similarity scores - Add 'Semantic Search' nav link in App.tsx - Add unit tests with mocked Ollama + Qdrant HTTP servers (4 tests, all passing) - Add GitHub issue templates (bug report, feature request) - Add pull request template
This commit is contained in:
@@ -54,6 +54,35 @@ func searchReleases(svc *service.SearchService) echo.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
func semanticSearch(svc *service.SemanticSearchService) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
ctx, cancel := context.WithTimeout(c.Request().Context(), 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
query := c.QueryParam("q")
|
||||
if query == "" {
|
||||
return c.JSON(http.StatusBadRequest, map[string]string{"error": "q parameter is required"})
|
||||
}
|
||||
|
||||
k := 5
|
||||
if kStr := c.QueryParam("k"); kStr != "" {
|
||||
if kVal, err := strconv.Atoi(kStr); err == nil && kVal > 0 && kVal <= 50 {
|
||||
k = kVal
|
||||
}
|
||||
}
|
||||
|
||||
results, err := svc.Search(ctx, query, k)
|
||||
if err != nil {
|
||||
slog.Error("semantic search failed", "error", err)
|
||||
return c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, map[string]interface{}{
|
||||
"results": results,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func grabRelease(svc *service.SearchService, dcSvc *service.DownloadClientService, queueSvc *service.QueueService, safetySvc *service.SafetyService, activitySvc *service.ActivityService) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
ctx, cancel := context.WithTimeout(c.Request().Context(), 30*time.Second)
|
||||
|
||||
Reference in New Issue
Block a user