processDirectorySmart processa um diretório e seleciona partes relevantes para a consulta
(ctx context.Context, path string, query string, tokenEstimator func(string) int, maxTokens int)
| 764 | |
| 765 | // processDirectorySmart processa um diretório e seleciona partes relevantes para a consulta |
| 766 | func (cli *ChatCLI) processDirectorySmart(ctx context.Context, path string, query string, tokenEstimator func(string) int, maxTokens int) (string, error) { |
| 767 | path, err := utils.ExpandPath(path) |
| 768 | if err != nil { |
| 769 | return "", fmt.Errorf("erro ao expandir o caminho: %w", err) |
| 770 | } |
| 771 | |
| 772 | // Se a consulta estiver vazia, usar o modo de resumo |
| 773 | if query == "" { |
| 774 | return cli.processDirectorySummary(ctx, path, tokenEstimator, maxTokens) |
| 775 | } |
| 776 | |
| 777 | // Configurar opções de processamento de diretório |
| 778 | scanOptions := utils.DefaultDirectoryScanOptions(cli.logger) |
| 779 | scanOptions.OnFileProcessed = func(info utils.FileInfo) { |
| 780 | cli.animation.UpdateMessage(fmt.Sprintf("Analisando %s", info.Path)) |
| 781 | } |
| 782 | |
| 783 | files, err := utils.ProcessDirectory(ctx, path, scanOptions) |
| 784 | if err != nil { |
| 785 | return "", err |
| 786 | } |
| 787 | |
| 788 | if len(files) == 0 { |
| 789 | return "", fmt.Errorf("nenhum arquivo relevante encontrado em '%s'", path) |
| 790 | } |
| 791 | |
| 792 | // Avaliar relevância de cada arquivo para a consulta |
| 793 | type ScoredFile struct { |
| 794 | File utils.FileInfo |
| 795 | Score float64 |
| 796 | } |
| 797 | |
| 798 | scoredFiles := make([]ScoredFile, 0, len(files)) |
| 799 | |
| 800 | // Termos importantes da consulta |
| 801 | queryTerms := strings.Fields(strings.ToLower(query)) |
| 802 | |
| 803 | for _, file := range files { |
| 804 | // Cálculo simples de relevância baseado em correspondência de palavras-chave |
| 805 | fileContent := strings.ToLower(file.Content) |
| 806 | fileName := strings.ToLower(filepath.Base(file.Path)) |
| 807 | |
| 808 | var score float64 |
| 809 | |
| 810 | // Pontuação por nome de arquivo |
| 811 | for _, term := range queryTerms { |
| 812 | if strings.Contains(fileName, term) { |
| 813 | score += 5.0 // Maior peso para correspondência no nome |
| 814 | } |
| 815 | } |
| 816 | |
| 817 | // Pontuação por conteúdo |
| 818 | for _, term := range queryTerms { |
| 819 | count := strings.Count(fileContent, term) |
| 820 | score += float64(count) * 0.5 |
| 821 | } |
| 822 | |
| 823 | // Normalizar pela extensão do arquivo (favorecendo arquivos de código) |
no test coverage detected