Spaces:
Sleeping
Sleeping
| #!/usr/bin/env python3 | |
| """ | |
| Run script for Agentic Defensor. | |
| This script provides multiple ways to interact with the Agentic Defensor system: | |
| 1. API mode: Run the FastAPI server to handle queries over HTTP | |
| 2. CLI mode: Run a single query from the command line | |
| 3. Agent mode: Use the multi-agent system to process a query | |
| 4. Interactive mode: Start an interactive session to ask multiple questions | |
| """ | |
| import os | |
| import sys | |
| import json | |
| import argparse | |
| import uvicorn | |
| from dotenv import load_dotenv | |
| # Load environment variables | |
| load_dotenv() | |
| def run_api(port): | |
| """Run the API server.""" | |
| print(f"Starting Agentic Defensor API server on port {port}...") | |
| print(f"The API will be available at http://localhost:{port}") | |
| print("Press Ctrl+C to stop the server") | |
| uvicorn.run("src.api.app:app", host="0.0.0.0", port=port, reload=True) | |
| def run_cli(query, top_k, model, output, verbose): | |
| """Run a query using the standard legal agent.""" | |
| from src.main import process_query, save_result | |
| from src.utils.config import CHAT_MODEL | |
| # Ensure model is not None | |
| if model is None: | |
| model = CHAT_MODEL | |
| print(f"Processing query: {query}") | |
| print(f"Using model: {model}") | |
| result = process_query(query, top_k, model) | |
| # Print the answer | |
| print("\n--- Answer ---") | |
| print(result["answer"]) | |
| # Print additional information if verbose | |
| if verbose: | |
| print("\n--- Query Information ---") | |
| print(f"Model used: {result['model_used']}") | |
| print(f"Retrieved chunks: {len(result['retrieved_chunks'])}") | |
| # Save the result if output path is provided | |
| if output: | |
| save_result(result, output) | |
| print(f"Results saved to {output}") | |
| def run_agentic(query, top_k, model, output, verbose, debug): | |
| """Run a query using the multi-agent system.""" | |
| from src.agents.agent_director import AgentDirector | |
| from src.utils.config import CHAT_MODEL | |
| # Ensure model is not None | |
| if model is None: | |
| model = CHAT_MODEL | |
| # Initialize the agent director | |
| print("Initializing agent director...") | |
| print(f"Using model: {model}") | |
| if debug: | |
| print("Debug mode enabled: Agent reasoning will be shown") | |
| director = AgentDirector(top_k=top_k, model=model, debug=debug) | |
| # Process the query | |
| print(f"\nProcessing query: {query}") | |
| result = director.process_query(query) | |
| # Display the result | |
| print("\n" + "="*80) | |
| print("QUERY:") | |
| print(query) | |
| print("\nANSWER:") | |
| print(result["answer"]) | |
| print("="*80) | |
| # Display processing steps | |
| if verbose: | |
| print("\nPROCESSING STEPS:") | |
| if "query_analysis" in result: | |
| print("1. Query Analysis: Completed") | |
| structured_analysis = result["query_analysis"].get("structured_analysis", "") | |
| if structured_analysis: | |
| print(f" - Extracted structured information from the query") | |
| print(f"2. Retrieved {result.get('num_chunks_retrieved', 0)} document chunks") | |
| if "context_aggregation" in result: | |
| agg = result["context_aggregation"] | |
| print("3. Context Aggregation:") | |
| print(f" - Processed {agg.get('num_raw_content_items', 0)} content items") | |
| print(f" - Organized context: {agg.get('has_organized_content', False)}") | |
| print(f"4. Answer Generation: Completed") | |
| # Save results if requested | |
| if output: | |
| print(f"\nSaving results to {output}...") | |
| with open(output, "w", encoding="utf-8") as f: | |
| json.dump(result, f, ensure_ascii=False, indent=2) | |
| print(f"Results saved successfully.") | |
| def run_interactive(model, top_k, agent_mode, verbose, debug): | |
| """Run an interactive session with the user.""" | |
| from src.agents.agent_director import AgentDirector | |
| from src.agents.legal_agent import LegalAgent | |
| from src.utils.config import CHAT_MODEL | |
| # Ensure model is not None | |
| if model is None: | |
| model = CHAT_MODEL | |
| print("=== Agentic Defensor Interactive Mode ===") | |
| print("Type 'exit', 'quit', or 'q' to end the session.") | |
| print("Type 'help' or '?' for assistance.") | |
| print() | |
| if agent_mode: | |
| print("Using multi-agent system for processing queries.") | |
| if debug: | |
| print("Debug mode enabled: Agent reasoning will be shown") | |
| agent = AgentDirector(top_k=top_k, model=model, debug=debug) | |
| else: | |
| print("Using standard legal agent for processing queries.") | |
| agent = LegalAgent(model=model) | |
| print(f"Using model: {model}") | |
| print(f"Retrieving {top_k} chunks per query") | |
| history = [] | |
| while True: | |
| # Get the query from the user | |
| try: | |
| query = input("\nYour query: ").strip() | |
| except (KeyboardInterrupt, EOFError): | |
| print("\nExiting interactive mode.") | |
| break | |
| # Check for exit commands | |
| if query.lower() in ['exit', 'quit', 'q']: | |
| print("Exiting interactive mode.") | |
| break | |
| # Check for help command | |
| if query.lower() in ['help', '?']: | |
| print("\nAgentic Defensor Help:") | |
| print("- Type your legal query and press Enter to get an answer.") | |
| print("- Type 'exit', 'quit', or 'q' to end the session.") | |
| print("- Type 'history' to see your previous queries.") | |
| print("- Type 'save FILENAME' to save the session history to a file.") | |
| continue | |
| # Check for history command | |
| if query.lower() == 'history': | |
| if not history: | |
| print("No history available.") | |
| else: | |
| print("\nQuery History:") | |
| for i, item in enumerate(history, start=1): | |
| print(f"{i}. {item['query']}") | |
| continue | |
| # Check for save command | |
| if query.lower().startswith('save '): | |
| filename = query[5:].strip() | |
| if not filename: | |
| print("Please provide a filename: save FILENAME") | |
| continue | |
| if not history: | |
| print("No history to save.") | |
| continue | |
| try: | |
| with open(filename, 'w', encoding='utf-8') as f: | |
| json.dump(history, f, ensure_ascii=False, indent=2) | |
| print(f"History saved to {filename}") | |
| except Exception as e: | |
| print(f"Error saving history: {e}") | |
| continue | |
| # Skip empty queries | |
| if not query: | |
| continue | |
| # Process the query | |
| print("Processing query...") | |
| try: | |
| if agent_mode: | |
| result = agent.process_query(query) | |
| else: | |
| result = agent.answer_query(query, top_k) | |
| # Store in history | |
| history.append({ | |
| 'query': query, | |
| 'answer': result.get('answer', 'No answer available.') | |
| }) | |
| # Display the answer | |
| print("\n--- Answer ---") | |
| print(result.get('answer', 'No answer available.')) | |
| # Print additional information if verbose | |
| if verbose: | |
| if agent_mode and 'num_chunks_retrieved' in result: | |
| print(f"\nRetrieved {result['num_chunks_retrieved']} document chunks") | |
| elif not agent_mode and 'retrieved_chunks' in result: | |
| print(f"\nRetrieved {len(result['retrieved_chunks'])} document chunks") | |
| print(f"Used model: {result.get('model_used', model)}") | |
| except Exception as e: | |
| print(f"Error processing query: {e}") | |
| def main(): | |
| """Main function to parse arguments and run the appropriate mode.""" | |
| # Create the top-level parser | |
| parser = argparse.ArgumentParser(description="Agentic Defensor: Legal RAG System") | |
| parser.add_argument('--model', type=str, default=None, help='OpenAI model to use') | |
| parser.add_argument('--verbose', action='store_true', help='Print verbose output') | |
| parser.add_argument('--debug', action='store_true', help='Show agent reasoning steps') | |
| # Create subparsers for different modes | |
| subparsers = parser.add_subparsers(dest='mode', help='Operating mode') | |
| # API mode | |
| api_parser = subparsers.add_parser('api', help='Run the API server') | |
| api_parser.add_argument('--port', type=int, default=8000, help='Port to run the API server on') | |
| # CLI mode | |
| cli_parser = subparsers.add_parser('cli', help='Run a query from the command line') | |
| cli_parser.add_argument('query', type=str, help='The legal query to process') | |
| cli_parser.add_argument('--top-k', type=int, default=200, help='Number of chunks to retrieve') | |
| cli_parser.add_argument('--output', type=str, default=None, help='Output file path for saving the response') | |
| # Agent mode | |
| agent_parser = subparsers.add_parser('agent', help='Run a query using the multi-agent system') | |
| agent_parser.add_argument('query', type=str, help='The legal query to process') | |
| agent_parser.add_argument('--top-k', type=int, default=50, help='Number of chunks to retrieve') | |
| agent_parser.add_argument('--output', type=str, default=None, help='Output file path for saving the response') | |
| # Interactive mode | |
| interactive_parser = subparsers.add_parser('interactive', help='Start an interactive session') | |
| interactive_parser.add_argument('--top-k', type=int, default=50, help='Number of chunks to retrieve') | |
| interactive_parser.add_argument('--agent', action='store_true', help='Use multi-agent system') | |
| # Parse the arguments | |
| args = parser.parse_args() | |
| # Run the appropriate mode | |
| if args.mode == 'api': | |
| run_api(args.port) | |
| elif args.mode == 'cli': | |
| run_cli(args.query, args.top_k, args.model, args.output, args.verbose) | |
| elif args.mode == 'agent': | |
| run_agentic(args.query, args.top_k, args.model, args.output, args.verbose, args.debug) | |
| elif args.mode == 'interactive': | |
| run_interactive(args.model, args.top_k, args.agent, args.verbose, args.debug) | |
| else: | |
| # Default to interactive mode if no mode specified | |
| print("No mode specified, starting interactive mode...\n") | |
| run_interactive(args.model, 50, False, args.verbose, args.debug) | |
| if __name__ == "__main__": | |
| main() |