Repository navigation
Expand file tree
/
Copy pathmain.py
More file actions
162 lines (127 loc) · 4.55 KB
/
Copy pathmain.py
File metadata and controls
162 lines (127 loc) · 4.55 KB
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
# uv run main.py
# http://127.0.0.1:5000/caption
import time
import os
import difflib
from flask import Flask, request, jsonify
from flask_cors import CORS
from openai import OpenAI
from dotenv import load_dotenv
load_dotenv()
app = Flask(__name__)
CORS(app)
# ==========================================
# ⚙️ CONFIGURATION ZONE (PICK ONE!)
# ==========================================
# --- OPTION 1: GOOGLE GEMINI (Fast & Free Tier) ---
# CURRENT_PROVIDER = "gemini"
# API_KEY = os.environ.get("GEMINI_API_KEY")
# BASE_URL = "https://generativelanguage.googleapis.com/v1beta/openai/"
# MODEL_NAME = "gemini-2.5-flash"
# https://dashboard.sarvam.ai/
#--- OPTION 2: SARVAM AI (Indian AI) ---
CURRENT_PROVIDER = "sarvam"
API_KEY = os.environ.get("SARVAM_API_KEY")
BASE_URL = "https://api.sarvam.ai/v1"
MODEL_NAME = "sarvam-m"
# --- OPTION 3: PERPLEXITY (Live Search Knowledge) ---
# CURRENT_PROVIDER = "perplexity"
# API_KEY = os.environ.get("PERPLEXITY_API_KEY")
# BASE_URL = "https://api.perplexity.ai"
# MODEL_NAME = "llama-3.1-sonar-small-128k-online"
# ==========================================
# Initialize the Universal Client
client = OpenAI(
api_key=API_KEY,
base_url=BASE_URL
)
MIN_CHAR_LENGTH = 5 # Don't send text shorter than this (e.g. "Hello?")
# --- UI GARBAGE TO IGNORE ---
IGNORE_PHRASES = [
"turn on microphone", "turn off microphone",
"turn on camera", "turn off camera",
"share screen", "stop sharing",
"raise hand", "lower hand",
"caption settings", "font size",
"meeting details", "people", "chat",
"you are muted", "microphone is off"
]
def load_file(filename):
try:
with open(filename, 'r', encoding='utf-8') as f:
return f.read().strip()
except FileNotFoundError:
return ""
RESUME = load_file("resume.txt")
BASE_PROMPT = load_file("system_prompt.txt")
SYSTEM_INSTRUCTION = f"""
{BASE_PROMPT}
MY RESUME:
{RESUME}
INSTRUCTIONS:
1. You are a fast, expert technical assistant.
2. Receive the raw transcript of an interviewer's question.
3. If the input is incomplete or just noise, reply with "..."
4. Otherwise, answer technically and confidently in the first person.
5. Keep it under 3 sentences.
"""
# --- GLOBAL MEMORY ---
last_processed_text = ""
last_successful_reply = ""
def is_garbage(text):
"""Returns True if text is UI noise or too short."""
text_lower = text.lower()
# 1. Length Check
if len(text) < MIN_CHAR_LENGTH:
print(f"[IGNORED] Too short ({len(text)} chars): {text}")
return True
# 2. UI Keyword Check
if any(phrase in text_lower for phrase in IGNORE_PHRASES):
print(f"[IGNORED] UI Garbage: {text}")
return True
return False
@app.route('/caption', methods=['POST'])
def receive_caption():
global last_processed_text, last_successful_reply
data = request.json
incoming_text = data.get('text', '').strip()
# --- 1. DUPLICATE CHECK ---
# If we just processed this exact text, ignore it.
if incoming_text == last_processed_text:
return jsonify({"status": "ignored", "reason": "duplicate"}), 200
last_processed_text = incoming_text
# --- 2. GARBAGE CHECK ---
if is_garbage(incoming_text):
return jsonify({"status": "ignored", "reason": "garbage"}), 200
print(f"\n[INTERVIEWER]: {incoming_text}")
try:
start_time = time.time()
# --- 3. CALL GEMINI ---
response = client.chat.completions.create(
model=MODEL_NAME,
messages=[
{"role": "system", "content": SYSTEM_INSTRUCTION},
{"role": "user", "content": incoming_text}
],
stream=False
)
reply = response.choices[0].message.content.strip()
latency = time.time() - start_time
# --- 4. EMPTY RESPONSE CHECK ---
# If AI replies with "..." or empty, don't show it
if not reply or reply == "..." or len(reply) < 2:
print(f"[AI DECIDED TO IGNORE] ({latency:.2f}s)")
return jsonify({"status": "ignored", "reason": "ai_silence"}), 200
print("="*50)
print(f"GEMINI ({latency:.2f}s): {reply}")
print("="*50 + "\n")
last_successful_reply = reply
return jsonify({"status": "success", "reply": reply})
except Exception as e:
print(f"Error: {e}")
return jsonify({"status": "error"}), 500
if __name__ == '__main__':
print(f"--- SECURE SERVER READY ({MODEL_NAME}) ---")
print(f"Min Text Length: {MIN_CHAR_LENGTH} chars")
app.run(port=5000)
#http://127.0.0.1:5000/caption