#!/usr/bin/env python3 """ COPILOT SETUP SCRIPT Sets up API keys and validates copilot configuration Usage: python setup_copilot.py """ import os import sys from pathlib import Path def print_header(text: str): """Print formatted header""" print("\n" + "=" * 70) print(f" {text}") print("=" * 70 + "\n") def get_user_input(prompt: str, is_required: bool = False) -> str: """Get input from user with validation""" while True: value = input(prompt).strip() if not value and is_required: print("[FAIL] This field is required. Please enter a value.\n") continue return value def setup_groq_keys(): """Guide user through Groq API key setup""" print_header("GROQ API KEYS SETUP") print("Groq provides free access to Llama 3.1 models") print("Get free API keys from: https://console.groq.com/keys\n") groq_keys = [] for i in range(1, 6): print(f"\n[NOTE] Groq API Key #{i}") print(" (Leave blank to skip additional keys, need at least 1)") key = get_user_input("Enter GROQ_API_KEY_" + str(i) + ": ") if not key: if i == 1: print("[FAIL] At least one Groq API key is required!") continue else: break if len(key) < 10: print("[FAIL] Key seems too short, are you sure? (y/n): ", end="") if input().lower() != "y": continue groq_keys.append((f"GROQ_API_KEY_{i}", key)) print(f"[OK] Key {i} saved (masked: {key[:10]}...{key[-5:]})") return groq_keys def setup_gemini_key(): """Guide user through Gemini API key setup""" print_header("GEMINI API KEY SETUP") print("Gemini 1.5 Flash provides free access (1M tokens/month)") print("Get free API key from: https://ai.google.dev/\n") while True: key = get_user_input("Enter GEMINI_API_KEY: ", is_required=True) if len(key) < 10: print("[FAIL] Key seems too short, are you sure? (y/n): ", end="") if input().lower() != "y": continue print(f"[OK] Key saved (masked: {key[:10]}...{key[-5:]})") return [("GEMINI_API_KEY", key)] def setup_pinecone_key(): """Guide user through Pinecone setup (optional)""" print_header("PINECONE VECTOR DB SETUP (Optional)") print("Pinecone is optional - can use SQLite embeddings instead") print("Get free API key from: https://www.pinecone.io/\n") use_pinecone = input("Do you want to use Pinecone? (y/n) [default: n]: ").lower() if use_pinecone != "y": print("[WARN] Skipping Pinecone - will use SQLite embeddings (local)") return [] api_key = get_user_input("Enter PINECONE_API_KEY: ", is_required=True) index_name = get_user_input("Enter PINECONE_INDEX_NAME [default: aml-alerts]: ") if not index_name: index_name = "aml-alerts" environment = get_user_input("Enter PINECONE_ENVIRONMENT (optional): ") pinecone_config = [ ("PINECONE_API_KEY", api_key), ("PINECONE_INDEX_NAME", index_name), ] if environment: pinecone_config.append(("PINECONE_ENVIRONMENT", environment)) print(f"[OK] Pinecone configured (Index: {index_name})") return pinecone_config def setup_anthropic_key(): """Guide user through Anthropic setup (optional)""" print_header("ANTHROPIC API KEY SETUP (Optional)") print("Anthropic provides Claude models (optional fallback)") print("Get API key from: https://console.anthropic.com/\n") use_anthropic = input("Do you want to add Anthropic API key? (y/n) [default: n]: ").lower() if use_anthropic != "y": print("[WARN] Skipping Anthropic - Groq will be used as primary") return [] api_key = get_user_input("Enter ANTHROPIC_API_KEY: ", is_required=True) print(f"[OK] Anthropic key saved (masked: {api_key[:10]}...{api_key[-5:]})") return [("ANTHROPIC_API_KEY", api_key)] def write_env_file(api_keys_dict: dict): """Write API keys to .env.copilot""" env_file = Path(__file__).parent / ".env.copilot" # Read existing template template_file = Path(__file__).parent / ".env.copilot" if template_file.exists(): with open(template_file, 'r') as f: content = f.read() else: content = "# Copilot Configuration\n" # Update with user values for key, value in api_keys_dict.items(): # Replace or add key lines = content.split('\n') found = False for i, line in enumerate(lines): if line.startswith(f"{key}="): lines[i] = f"{key}={value}" found = True break if not found: # Add at end (before EOF) lines.insert(-1, f"{key}={value}") content = '\n'.join(lines) # Write to file with open(env_file, 'w') as f: f.write(content) print(f"[OK] Configuration saved to: {env_file}") def main(): """Main setup flow""" os.system('clear' if os.name == 'posix' else 'cls') print("\n" + "=" * 70) print(" [ROCKET] UNION BANK AML COPILOT - API SETUP") print("=" * 70) print("\nThis wizard will help you configure API keys for the AML Copilot") print("All keys will be saved to .env.copilot (do not commit to git)\n") # Collect all keys all_keys = {} # Required: Groq groq_keys = setup_groq_keys() all_keys.update(dict(groq_keys)) if not groq_keys: print("\n[FAIL] At least one Groq API key is required!") sys.exit(1) # Required: Gemini gemini_keys = setup_gemini_key() all_keys.update(dict(gemini_keys)) # Optional: Pinecone pinecone_keys = setup_pinecone_key() all_keys.update(dict(pinecone_keys)) # Optional: Anthropic anthropic_keys = setup_anthropic_key() all_keys.update(dict(anthropic_keys)) # Save to file print_header("SAVING CONFIGURATION") write_env_file(all_keys) # Validate print_header("VALIDATING CONFIGURATION") print("Loading and validating all API keys...") print("(This will show the status of each provider)\n") # Need to reload config after writing from importlib import reload import src.copilot.config as config_module reload(config_module) from src.copilot.config import config as updated_config updated_config.print_status() if updated_config.is_ready(): print("\n[OK] SETUP COMPLETE!") print("\nYour copilot is now ready to use. Next steps:") print(" 1. Start the server: python server.py") print(" 2. Open http://localhost:8000 in your browser") print(" 3. Click the copilot button (bottom right)") print(" 4. Ask any question about accounts or alerts!") else: print("\n[WARN] Setup incomplete - some required keys are missing") print("Please fill in missing keys and run this script again") sys.exit(1) if __name__ == "__main__": try: main() except KeyboardInterrupt: print("\n\n[FAIL] Setup cancelled by user") sys.exit(0) except Exception as e: print(f"\n[FAIL] Error during setup: {e}") import traceback traceback.print_exc() sys.exit(1)