Compare commits
No commits in common. "e6d5f20f7decf74e619c0b92ac7e1cf3861dd7f5" and "9eb366f414ed18fdb87a549e7c394cbea1cf38a7" have entirely different histories.
e6d5f20f7d
...
9eb366f414
21
LICENSE
21
LICENSE
@ -1,21 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2025 Brett Fox
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
@ -549,125 +549,35 @@ show_completion() {
|
|||||||
read -r run_test
|
read -r run_test
|
||||||
if [[ ! $run_test =~ ^[Nn]$ ]]; then
|
if [[ ! $run_test =~ ^[Nn]$ ]]; then
|
||||||
run_quick_test
|
run_quick_test
|
||||||
echo ""
|
|
||||||
show_beginner_guidance
|
|
||||||
else
|
|
||||||
show_beginner_guidance
|
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Create sample project for testing
|
# Run quick test
|
||||||
create_sample_project() {
|
|
||||||
local sample_dir="$SCRIPT_DIR/.sample_test"
|
|
||||||
rm -rf "$sample_dir"
|
|
||||||
mkdir -p "$sample_dir"
|
|
||||||
|
|
||||||
# Create a few small sample files
|
|
||||||
cat > "$sample_dir/README.md" << 'EOF'
|
|
||||||
# Sample Project
|
|
||||||
|
|
||||||
This is a sample project for testing FSS-Mini-RAG search capabilities.
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
- User authentication system
|
|
||||||
- Document processing
|
|
||||||
- Search functionality
|
|
||||||
- Email integration
|
|
||||||
EOF
|
|
||||||
|
|
||||||
cat > "$sample_dir/auth.py" << 'EOF'
|
|
||||||
# Authentication module
|
|
||||||
def login_user(username, password):
|
|
||||||
"""Handle user login with password validation"""
|
|
||||||
if validate_credentials(username, password):
|
|
||||||
create_session(username)
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def validate_credentials(username, password):
|
|
||||||
"""Check username and password against database"""
|
|
||||||
# Database validation logic here
|
|
||||||
return check_password_hash(username, password)
|
|
||||||
EOF
|
|
||||||
|
|
||||||
cat > "$sample_dir/search.py" << 'EOF'
|
|
||||||
# Search functionality
|
|
||||||
def semantic_search(query, documents):
|
|
||||||
"""Perform semantic search across document collection"""
|
|
||||||
embeddings = generate_embeddings(query)
|
|
||||||
results = find_similar_documents(embeddings, documents)
|
|
||||||
return rank_results(results)
|
|
||||||
|
|
||||||
def generate_embeddings(text):
|
|
||||||
"""Generate vector embeddings for text"""
|
|
||||||
# Embedding generation logic
|
|
||||||
return process_with_model(text)
|
|
||||||
EOF
|
|
||||||
|
|
||||||
echo "$sample_dir"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Run quick test with sample data
|
|
||||||
run_quick_test() {
|
run_quick_test() {
|
||||||
print_header "Quick Test"
|
print_header "Quick Test"
|
||||||
|
|
||||||
print_info "Creating small sample project for testing..."
|
print_info "Testing on this project directory..."
|
||||||
local sample_dir=$(create_sample_project)
|
echo "This will index the FSS-Mini-RAG system itself as a test."
|
||||||
echo "Sample project created with 3 files for fast testing."
|
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# Index the sample project (much faster)
|
# Index this project
|
||||||
print_info "Indexing sample project (this should be fast)..."
|
if ./rag-mini index "$SCRIPT_DIR"; then
|
||||||
if ./rag-mini index "$sample_dir" --quiet; then
|
print_success "Indexing completed"
|
||||||
print_success "Sample project indexed successfully"
|
|
||||||
|
|
||||||
|
# Try a search
|
||||||
echo ""
|
echo ""
|
||||||
print_info "Testing search with sample queries..."
|
print_info "Testing search functionality..."
|
||||||
echo -e "${BLUE}Running search: 'user authentication'${NC}"
|
./rag-mini search "$SCRIPT_DIR" "embedding system" --limit 3
|
||||||
./rag-mini search "$sample_dir" "user authentication" --limit 2
|
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
print_success "Test completed successfully!"
|
print_success "Test completed successfully!"
|
||||||
echo -e "${CYAN}Ready to use FSS-Mini-RAG on your own projects!${NC}"
|
echo -e "${CYAN}You can now use FSS-Mini-RAG on your own projects.${NC}"
|
||||||
|
|
||||||
# Offer beginner guidance
|
|
||||||
echo ""
|
|
||||||
echo -e "${YELLOW}💡 Beginner Tip:${NC} Try the interactive mode with pre-made questions"
|
|
||||||
echo " Run: ./rag-tui for guided experience"
|
|
||||||
|
|
||||||
# Clean up sample
|
|
||||||
rm -rf "$sample_dir"
|
|
||||||
else
|
else
|
||||||
print_error "Sample test failed"
|
print_error "Test failed"
|
||||||
echo "This might indicate an issue with the installation."
|
echo "Check the error messages above for troubleshooting."
|
||||||
rm -rf "$sample_dir"
|
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Show beginner-friendly first steps
|
|
||||||
show_beginner_guidance() {
|
|
||||||
print_header "Getting Started - Your First Search"
|
|
||||||
|
|
||||||
echo -e "${CYAN}FSS-Mini-RAG is ready! Here's how to start:${NC}"
|
|
||||||
echo ""
|
|
||||||
echo -e "${GREEN}🎯 For Beginners (Recommended):${NC}"
|
|
||||||
echo " ./rag-tui"
|
|
||||||
echo " ↳ Interactive interface with sample questions"
|
|
||||||
echo ""
|
|
||||||
echo -e "${BLUE}💻 For Developers:${NC}"
|
|
||||||
echo " ./rag-mini index /path/to/your/project"
|
|
||||||
echo " ./rag-mini search /path/to/your/project \"your question\""
|
|
||||||
echo ""
|
|
||||||
echo -e "${YELLOW}📚 What can you search for?${NC}"
|
|
||||||
echo " • Code: \"authentication logic\", \"error handling\", \"API endpoints\""
|
|
||||||
echo " • Docs: \"installation guide\", \"configuration options\"
|
|
||||||
echo " • Your own files: emails, notes, research documents"
|
|
||||||
echo ""
|
|
||||||
echo -e "${CYAN}💡 Pro tip:${NC} You can drag ANY text-based documents into a folder"
|
|
||||||
echo " and search through them - emails, notes, research, chat logs!"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Main installation flow
|
# Main installation flow
|
||||||
main() {
|
main() {
|
||||||
echo -e "${CYAN}${BOLD}"
|
echo -e "${CYAN}${BOLD}"
|
||||||
|
|||||||
110
rag-tui.py
110
rag-tui.py
@ -278,37 +278,8 @@ class SimpleTUI:
|
|||||||
print(f"Project: {self.project_path.name}")
|
print(f"Project: {self.project_path.name}")
|
||||||
print()
|
print()
|
||||||
|
|
||||||
# Show sample questions for beginners
|
# Get search query
|
||||||
print("💡 Not sure what to search for? Try these sample questions:")
|
query = self.get_input("Enter search query", "").strip()
|
||||||
print()
|
|
||||||
sample_questions = [
|
|
||||||
"authentication logic",
|
|
||||||
"error handling",
|
|
||||||
"API endpoints",
|
|
||||||
"configuration settings",
|
|
||||||
"database connection",
|
|
||||||
"user management"
|
|
||||||
]
|
|
||||||
|
|
||||||
for i, question in enumerate(sample_questions[:3], 1):
|
|
||||||
print(f" {i}. {question}")
|
|
||||||
print(" 4. Enter your own question")
|
|
||||||
print()
|
|
||||||
|
|
||||||
# Let user choose a sample or enter their own
|
|
||||||
choice_str = self.get_input("Choose a number (1-4) or press Enter for custom", "4")
|
|
||||||
|
|
||||||
try:
|
|
||||||
choice = int(choice_str)
|
|
||||||
if 1 <= choice <= 3:
|
|
||||||
query = sample_questions[choice - 1]
|
|
||||||
print(f"Selected: '{query}'")
|
|
||||||
print()
|
|
||||||
else:
|
|
||||||
query = self.get_input("Enter your search query", "").strip()
|
|
||||||
except ValueError:
|
|
||||||
query = self.get_input("Enter your search query", "").strip()
|
|
||||||
|
|
||||||
if not query:
|
if not query:
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -383,38 +354,6 @@ class SimpleTUI:
|
|||||||
if len(results) > 1:
|
if len(results) > 1:
|
||||||
print("💡 To see more context or specific results:")
|
print("💡 To see more context or specific results:")
|
||||||
print(f" Run: ./rag-mini search {self.project_path} \"{query}\" --verbose")
|
print(f" Run: ./rag-mini search {self.project_path} \"{query}\" --verbose")
|
||||||
|
|
||||||
# Suggest follow-up questions based on the search
|
|
||||||
print()
|
|
||||||
print("🔍 Suggested follow-up searches:")
|
|
||||||
follow_up_questions = self.generate_follow_up_questions(query, results)
|
|
||||||
for i, question in enumerate(follow_up_questions, 1):
|
|
||||||
print(f" {i}. {question}")
|
|
||||||
|
|
||||||
# Ask if they want to run a follow-up search
|
|
||||||
print()
|
|
||||||
choice = input("Run a follow-up search? Enter number (1-3) or press Enter to continue: ").strip()
|
|
||||||
if choice.isdigit() and 1 <= int(choice) <= len(follow_up_questions):
|
|
||||||
# Recursive search with the follow-up question
|
|
||||||
follow_up_query = follow_up_questions[int(choice) - 1]
|
|
||||||
print(f"\nSearching for: '{follow_up_query}'")
|
|
||||||
print("=" * 50)
|
|
||||||
# Run another search
|
|
||||||
follow_results = searcher.search(follow_up_query, top_k=5)
|
|
||||||
|
|
||||||
if follow_results:
|
|
||||||
print(f"✅ Found {len(follow_results)} follow-up results:")
|
|
||||||
print()
|
|
||||||
for i, result in enumerate(follow_results[:3], 1): # Show top 3
|
|
||||||
try:
|
|
||||||
rel_path = result.file_path.relative_to(self.project_path)
|
|
||||||
except:
|
|
||||||
rel_path = result.file_path
|
|
||||||
print(f"{i}. {rel_path} (Score: {result.score:.3f})")
|
|
||||||
print(f" {result.content.strip()[:100]}...")
|
|
||||||
print()
|
|
||||||
else:
|
|
||||||
print("❌ No follow-up results found")
|
|
||||||
print(f" Or: ./rag-mini-enhanced context {self.project_path} \"{query}\"")
|
print(f" Or: ./rag-mini-enhanced context {self.project_path} \"{query}\"")
|
||||||
print()
|
print()
|
||||||
|
|
||||||
@ -425,45 +364,6 @@ class SimpleTUI:
|
|||||||
print()
|
print()
|
||||||
input("Press Enter to continue...")
|
input("Press Enter to continue...")
|
||||||
|
|
||||||
def generate_follow_up_questions(self, original_query: str, results) -> List[str]:
|
|
||||||
"""Generate contextual follow-up questions based on search results."""
|
|
||||||
# Simple pattern-based follow-up generation
|
|
||||||
follow_ups = []
|
|
||||||
|
|
||||||
# Based on original query patterns
|
|
||||||
query_lower = original_query.lower()
|
|
||||||
|
|
||||||
if "auth" in query_lower or "login" in query_lower:
|
|
||||||
follow_ups.extend(["password validation", "session management", "user permissions"])
|
|
||||||
elif "error" in query_lower or "exception" in query_lower:
|
|
||||||
follow_ups.extend(["error logging", "exception handling", "error messages"])
|
|
||||||
elif "api" in query_lower or "endpoint" in query_lower:
|
|
||||||
follow_ups.extend(["API documentation", "request validation", "response formatting"])
|
|
||||||
elif "database" in query_lower or "db" in query_lower:
|
|
||||||
follow_ups.extend(["database schema", "query optimization", "connection pooling"])
|
|
||||||
elif "config" in query_lower or "setting" in query_lower:
|
|
||||||
follow_ups.extend(["configuration files", "environment variables", "default values"])
|
|
||||||
else:
|
|
||||||
# Generic follow-ups
|
|
||||||
follow_ups.extend(["implementation details", "error handling", "configuration"])
|
|
||||||
|
|
||||||
# Based on file types found in results
|
|
||||||
if results:
|
|
||||||
file_extensions = set()
|
|
||||||
for result in results[:3]: # Check first 3 results
|
|
||||||
ext = result.file_path.suffix.lower()
|
|
||||||
file_extensions.add(ext)
|
|
||||||
|
|
||||||
if '.py' in file_extensions:
|
|
||||||
follow_ups.append("Python imports")
|
|
||||||
if '.js' in file_extensions:
|
|
||||||
follow_ups.append("JavaScript functions")
|
|
||||||
if '.md' in file_extensions:
|
|
||||||
follow_ups.append("documentation examples")
|
|
||||||
|
|
||||||
# Return top 3 unique follow-ups
|
|
||||||
return list(dict.fromkeys(follow_ups))[:3]
|
|
||||||
|
|
||||||
def explore_interactive(self):
|
def explore_interactive(self):
|
||||||
"""Interactive exploration interface with thinking mode."""
|
"""Interactive exploration interface with thinking mode."""
|
||||||
if not self.project_path:
|
if not self.project_path:
|
||||||
@ -782,12 +682,6 @@ class SimpleTUI:
|
|||||||
status = "✅ Indexed" if rag_dir.exists() else "❌ Not indexed"
|
status = "✅ Indexed" if rag_dir.exists() else "❌ Not indexed"
|
||||||
print(f"📁 Current project: {self.project_path.name} ({status})")
|
print(f"📁 Current project: {self.project_path.name} ({status})")
|
||||||
print()
|
print()
|
||||||
else:
|
|
||||||
# Show beginner tips when no project selected
|
|
||||||
print("🎯 Welcome to FSS-Mini-RAG!")
|
|
||||||
print(" Search through code, documents, emails, notes - anything text-based!")
|
|
||||||
print(" Start by selecting a project directory below.")
|
|
||||||
print()
|
|
||||||
|
|
||||||
options = [
|
options = [
|
||||||
"Select project directory",
|
"Select project directory",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user