mirror of
https://github.com/Dvorinka/Devour.git
synced 2026-06-04 04:23:02 +00:00
update
This commit is contained in:
+100
-18
@@ -1,9 +1,14 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
appconfig "github.com/yourorg/devour/internal/config"
|
||||
"github.com/yourorg/devour/internal/search"
|
||||
)
|
||||
|
||||
var queryCmd = &cobra.Command{
|
||||
@@ -29,32 +34,109 @@ var (
|
||||
)
|
||||
|
||||
func init() {
|
||||
queryCmd.Flags().IntVarP(&queryLimit, "limit", "l", 5, "maximum number of results")
|
||||
queryCmd.Flags().IntVarP(&queryLimit, "limit", "n", 5, "maximum number of results")
|
||||
queryCmd.Flags().StringVarP(&queryFormat, "format", "f", "text", "output format (text, json, markdown)")
|
||||
queryCmd.Flags().Float64Var(&queryThreshold, "threshold", 0.7, "similarity threshold (0-1)")
|
||||
queryCmd.Flags().Float64Var(&queryThreshold, "threshold", 0, "minimum lexical score threshold")
|
||||
}
|
||||
|
||||
func runQuery(cmd *cobra.Command, args []string) error {
|
||||
query := args[0]
|
||||
if len(args) > 1 {
|
||||
query = fmt.Sprintf("%s", args)
|
||||
query := strings.TrimSpace(strings.Join(args, " "))
|
||||
if query == "" {
|
||||
return fmt.Errorf("query cannot be empty")
|
||||
}
|
||||
|
||||
fmt.Printf("Searching: %q\n", query)
|
||||
fmt.Printf(" Limit: %d\n", queryLimit)
|
||||
fmt.Printf(" Threshold: %.2f\n", queryThreshold)
|
||||
fmt.Println()
|
||||
cfg, err := loadAppConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO: Implement actual query logic
|
||||
// 1. Generate embedding for query
|
||||
// 2. Search vector database
|
||||
// 3. Format and return results
|
||||
engine := search.NewEngine(cfg)
|
||||
results, stats, err := engine.Search(context.Background(), query, search.SearchOptions{
|
||||
Limit: queryLimit,
|
||||
Threshold: queryThreshold,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("query failed: %w", err)
|
||||
}
|
||||
|
||||
// Placeholder results
|
||||
fmt.Println("Results:")
|
||||
fmt.Println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
|
||||
fmt.Println("⚠️ Query functionality not yet implemented")
|
||||
fmt.Println(" Index some documents first with 'devour scrape'")
|
||||
switch strings.ToLower(queryFormat) {
|
||||
case "json":
|
||||
resp := map[string]any{
|
||||
"query": query,
|
||||
"limit": queryLimit,
|
||||
"threshold": queryThreshold,
|
||||
"count": len(results),
|
||||
"results": results,
|
||||
"indexed_at": stats.LastIndexedAt,
|
||||
"documents": stats.Documents,
|
||||
}
|
||||
enc := json.NewEncoder(cmd.OutOrStdout())
|
||||
enc.SetIndent("", " ")
|
||||
return enc.Encode(resp)
|
||||
case "markdown":
|
||||
return printQueryMarkdown(cmd, query, cfg, results, stats)
|
||||
case "text":
|
||||
return printQueryText(cmd, query, cfg, results, stats)
|
||||
default:
|
||||
return fmt.Errorf("unsupported format: %s (supported: text, json, markdown)", queryFormat)
|
||||
}
|
||||
}
|
||||
|
||||
func printQueryText(cmd *cobra.Command, query string, cfg *appconfig.Config, results []search.Result, stats *search.IndexStats) error {
|
||||
fmt.Fprintf(cmd.OutOrStdout(), "Searching: %q\n", query)
|
||||
fmt.Fprintf(cmd.OutOrStdout(), " Limit: %d\n", queryLimit)
|
||||
fmt.Fprintf(cmd.OutOrStdout(), " Threshold: %.2f\n", queryThreshold)
|
||||
fmt.Fprintf(cmd.OutOrStdout(), " Indexed docs: %d\n", stats.Documents)
|
||||
fmt.Fprintf(cmd.OutOrStdout(), " Docs dir: %s\n\n", cfg.Storage.DocsDir)
|
||||
|
||||
if len(results) == 0 {
|
||||
fmt.Fprintln(cmd.OutOrStdout(), "No results found.")
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Fprintln(cmd.OutOrStdout(), "Results:")
|
||||
fmt.Fprintln(cmd.OutOrStdout(), "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
|
||||
for i, r := range results {
|
||||
fmt.Fprintf(cmd.OutOrStdout(), "%d. %s\n", i+1, r.Title)
|
||||
fmt.Fprintf(cmd.OutOrStdout(), " Score: %.3f | Type: %s | Source: %s\n", r.Score, r.Type, defaultSource(r.Source))
|
||||
if r.URL != "" {
|
||||
fmt.Fprintf(cmd.OutOrStdout(), " URL: %s\n", r.URL)
|
||||
}
|
||||
fmt.Fprintf(cmd.OutOrStdout(), " Snippet: %s\n\n", r.Snippet)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func printQueryMarkdown(cmd *cobra.Command, query string, cfg *appconfig.Config, results []search.Result, stats *search.IndexStats) error {
|
||||
fmt.Fprintf(cmd.OutOrStdout(), "# Query Results\n\n")
|
||||
fmt.Fprintf(cmd.OutOrStdout(), "- Query: `%s`\n", query)
|
||||
fmt.Fprintf(cmd.OutOrStdout(), "- Limit: `%d`\n", queryLimit)
|
||||
fmt.Fprintf(cmd.OutOrStdout(), "- Threshold: `%.2f`\n", queryThreshold)
|
||||
fmt.Fprintf(cmd.OutOrStdout(), "- Indexed docs: `%d`\n", stats.Documents)
|
||||
fmt.Fprintf(cmd.OutOrStdout(), "- Docs dir: `%s`\n\n", cfg.Storage.DocsDir)
|
||||
|
||||
if len(results) == 0 {
|
||||
fmt.Fprintln(cmd.OutOrStdout(), "_No results found._")
|
||||
return nil
|
||||
}
|
||||
|
||||
for i, r := range results {
|
||||
fmt.Fprintf(cmd.OutOrStdout(), "## %d. %s\n\n", i+1, r.Title)
|
||||
fmt.Fprintf(cmd.OutOrStdout(), "- Score: `%.3f`\n", r.Score)
|
||||
fmt.Fprintf(cmd.OutOrStdout(), "- Type: `%s`\n", r.Type)
|
||||
fmt.Fprintf(cmd.OutOrStdout(), "- Source: `%s`\n", defaultSource(r.Source))
|
||||
if r.URL != "" {
|
||||
fmt.Fprintf(cmd.OutOrStdout(), "- URL: %s\n", r.URL)
|
||||
}
|
||||
fmt.Fprintf(cmd.OutOrStdout(), "\n%s\n\n", r.Snippet)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func defaultSource(source string) string {
|
||||
source = strings.TrimSpace(source)
|
||||
if source == "" {
|
||||
return "unknown"
|
||||
}
|
||||
return source
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user