File size: 7,333 Bytes
f70ac6a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
#!/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)