from src.cli.base import CLICommand from src.cli.display import DisplayFormatter from src.pipelines.qa import QuestionAnsweringSystem class QACommand(CLICommand): """Interactive Question Answering command""" def __init__(self): self.qa_system = None self.current_context = None self.session_questions = [] @property def name(self) -> str: return "qa" @property def description(self) -> str: return "Question Answering - Ask questions about a given text" def _initialize_qa_system(self): """Lazy initialization of the QA system""" if self.qa_system is None: print("šŸ”„ Loading Question Answering model...") self.qa_system = QuestionAnsweringSystem() DisplayFormatter.show_success("QA model loaded!") def _show_instructions(self): """Show usage instructions and examples""" print("\nā“ Question Answering System") print("Ask questions about a text context and get precise answers.") print("\nšŸ“ How it works:") print(" 1. First, provide a context (text containing information)") print(" 2. Then ask questions about that context") print(" 3. The system extracts answers directly from the text") print("\nšŸ’” Example context:") print(" 'Albert Einstein was born in 1879 in Germany. He developed the theory of relativity.'") print("šŸ’” Example questions:") print(" - When was Einstein born?") print(" - Where was Einstein born?") print(" - What theory did Einstein develop?") print("\nšŸŽ›ļø Commands:") print(" 'back' - Return to main menu") print(" 'help' - Show these instructions") print(" 'context' - Set new context") print(" 'multi' - Ask multiple questions at once") print(" 'session' - Review session history") print(" 'settings' - Adjust confidence threshold") print("-" * 70) def _set_context(self): """Allow user to set or change the context""" print("\nšŸ“„ Set Context") print("Enter the text that will serve as context for your questions.") print("You can enter multiple lines. Type 'done' when finished.") print("-" * 50) lines = [] while True: line = input("šŸ“ ").strip() if line.lower() == 'done': break if line: lines.append(line) if not lines: DisplayFormatter.show_warning("No context provided") return False self.current_context = " ".join(lines) # Analyze context analysis = self.qa_system.interactive_qa(self.current_context) if "error" in analysis: DisplayFormatter.show_error(analysis["error"]) return False formatted_analysis = DisplayFormatter.format_qa_context_analysis(analysis) print(formatted_analysis) return True def _ask_single_question(self): """Ask a single question about the current context""" if not self.current_context: DisplayFormatter.show_warning("Please set a context first using 'context' command") return question = input("\nā“ Your question: ").strip() if not question: DisplayFormatter.show_warning("Please enter a question") return DisplayFormatter.show_loading("Finding answer...") result = self.qa_system.answer(question, self.current_context) if "error" not in result: self.session_questions.append(result) formatted_result = DisplayFormatter.format_qa_result(result) print(formatted_result) def _multi_question_mode(self): """Allow asking multiple questions at once""" if not self.current_context: DisplayFormatter.show_warning("Please set a context first using 'context' command") return print("\nā“ Multiple Questions Mode") print("Enter your questions one by one. Type 'done' when finished.") print("-" * 50) questions = [] while True: question = input(f"Question #{len(questions)+1}: ").strip() if question.lower() == 'done': break if question: questions.append(question) if not questions: DisplayFormatter.show_warning("No questions provided") return DisplayFormatter.show_loading(f"Processing {len(questions)} questions...") result = self.qa_system.answer_multiple(questions, self.current_context) if "error" not in result: self.session_questions.extend(result["results"]) formatted_result = DisplayFormatter.format_qa_multiple_result(result) print(formatted_result) def _show_session_history(self): """Show the history of questions asked in this session""" if not self.session_questions: DisplayFormatter.show_warning("No questions asked in this session yet") return print(f"\nšŸ“š Session History ({len(self.session_questions)} questions)") print("=" * 60) for i, qa in enumerate(self.session_questions, 1): confidence_emoji = "āœ…" if qa["is_confident"] else "āš ļø" print(f"\n{i}. {qa['question']}") print(f" {confidence_emoji} {qa['answer']} (confidence: {qa['confidence']:.1%})") def _adjust_settings(self): """Allow user to adjust QA settings""" current_threshold = self.qa_system.confidence_threshold print(f"\nāš™ļø Current Settings:") print(f"Confidence threshold: {current_threshold:.2f}") print("\nLower threshold = more answers accepted (less strict)") print("Higher threshold = fewer answers accepted (more strict)") try: new_threshold = input(f"Enter new threshold (0.0-1.0, current: {current_threshold}): ").strip() if new_threshold: threshold = float(new_threshold) self.qa_system.set_confidence_threshold(threshold) DisplayFormatter.show_success(f"Threshold set to {threshold:.2f}") except ValueError: DisplayFormatter.show_error("Invalid threshold value") def run(self): """Run interactive Question Answering""" self._initialize_qa_system() self._show_instructions() while True: if self.current_context: context_preview = (self.current_context[:50] + "...") if len(self.current_context) > 50 else self.current_context prompt = f"\nšŸ’¬ [{context_preview}] Ask a question: " else: prompt = "\nšŸ’¬ Enter command or set context first: " user_input = input(prompt).strip() if user_input.lower() == 'back': break elif user_input.lower() == 'help': self._show_instructions() continue elif user_input.lower() == 'context': self._set_context() continue elif user_input.lower() == 'multi': self._multi_question_mode() continue elif user_input.lower() == 'session': self._show_session_history() continue elif user_input.lower() == 'settings': self._adjust_settings() continue if not user_input: DisplayFormatter.show_warning("Please enter a question or command") continue # If we have a context and user input is not a command, treat it as a question if self.current_context: DisplayFormatter.show_loading("Finding answer...") result = self.qa_system.answer(user_input, self.current_context) if "error" not in result: self.session_questions.append(result) formatted_result = DisplayFormatter.format_qa_result(result) print(formatted_result) else: DisplayFormatter.show_warning("Please set a context first using 'context' command")