Spaces:
Sleeping
Sleeping
Commit ·
3d6dd09
1
Parent(s): 1190215
Update Groq API keys with rotation logic
Browse files
app.py
CHANGED
|
@@ -52,15 +52,21 @@ SENTINEL2_API_URL = os.getenv("SENTINEL2_API_URL", "https://aniket2006-agrow-sen
|
|
| 52 |
# ============================================================================
|
| 53 |
# GROQ SETUP
|
| 54 |
# ============================================================================
|
| 55 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 56 |
GROQ_MODEL = "llama-3.3-70b-versatile"
|
| 57 |
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
logger.info(f"Groq API configured with model {GROQ_MODEL}")
|
| 61 |
-
else:
|
| 62 |
-
groq_client = None
|
| 63 |
-
logger.warning("GROQ_API_KEY not set - chatbot will return mock responses")
|
| 64 |
|
| 65 |
# Supabase
|
| 66 |
supabase = SupabaseClient()
|
|
@@ -500,39 +506,52 @@ Your analysis:"""
|
|
| 500 |
# GENERATE RESPONSE
|
| 501 |
# ============================================================================
|
| 502 |
def generate_response(user_message: str, history: List[Dict], context: Dict) -> tuple[str, List[str]]:
|
| 503 |
-
"""Generate AI response using comprehensive context."""
|
| 504 |
context = context or {}
|
| 505 |
history = history or []
|
| 506 |
context_used = context.get("data_sources", [])
|
| 507 |
|
| 508 |
-
|
| 509 |
-
|
| 510 |
-
|
| 511 |
-
|
| 512 |
-
|
| 513 |
-
|
| 514 |
-
|
| 515 |
-
|
| 516 |
-
|
| 517 |
-
|
| 518 |
-
|
| 519 |
-
|
| 520 |
-
|
| 521 |
-
|
| 522 |
-
|
| 523 |
-
|
| 524 |
-
|
| 525 |
-
|
| 526 |
-
|
| 527 |
-
|
| 528 |
-
|
| 529 |
-
|
| 530 |
-
|
| 531 |
-
|
| 532 |
-
|
| 533 |
-
|
| 534 |
-
|
| 535 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 536 |
|
| 537 |
|
| 538 |
# ============================================================================
|
|
@@ -548,7 +567,7 @@ async def root():
|
|
| 548 |
|
| 549 |
@app.get("/health")
|
| 550 |
async def health():
|
| 551 |
-
return {"status": "healthy", "groq_configured":
|
| 552 |
|
| 553 |
|
| 554 |
@app.post("/session/new", response_model=SessionResponse)
|
|
|
|
| 52 |
# ============================================================================
|
| 53 |
# GROQ SETUP
|
| 54 |
# ============================================================================
|
| 55 |
+
GROQ_API_KEYS = [
|
| 56 |
+
"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",
|
| 57 |
+
"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",
|
| 58 |
+
"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",
|
| 59 |
+
"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",
|
| 60 |
+
"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",
|
| 61 |
+
"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",
|
| 62 |
+
"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",
|
| 63 |
+
"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",
|
| 64 |
+
"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"
|
| 65 |
+
]
|
| 66 |
GROQ_MODEL = "llama-3.3-70b-versatile"
|
| 67 |
|
| 68 |
+
# Verify keys loaded
|
| 69 |
+
logger.info(f"Loaded {len(GROQ_API_KEYS)} Groq API keys")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 70 |
|
| 71 |
# Supabase
|
| 72 |
supabase = SupabaseClient()
|
|
|
|
| 506 |
# GENERATE RESPONSE
|
| 507 |
# ============================================================================
|
| 508 |
def generate_response(user_message: str, history: List[Dict], context: Dict) -> tuple[str, List[str]]:
|
| 509 |
+
"""Generate AI response using comprehensive context with API Key Rotation."""
|
| 510 |
context = context or {}
|
| 511 |
history = history or []
|
| 512 |
context_used = context.get("data_sources", [])
|
| 513 |
|
| 514 |
+
prompt = build_llm_prompt(user_message, context, history)
|
| 515 |
+
last_error = None
|
| 516 |
+
|
| 517 |
+
# Try keys sequentially with fallback on failure
|
| 518 |
+
for i, api_key in enumerate(GROQ_API_KEYS):
|
| 519 |
+
try:
|
| 520 |
+
logger.info(f"[Chatbot] Trying Groq API key {i+1}/{len(GROQ_API_KEYS)}")
|
| 521 |
+
client = Groq(api_key=api_key)
|
| 522 |
+
|
| 523 |
+
chat_completion = client.chat.completions.create(
|
| 524 |
+
messages=[
|
| 525 |
+
{
|
| 526 |
+
"role": "system",
|
| 527 |
+
"content": "You are AGROW AI, an expert agricultural advisor. Provide helpful, data-driven advice."
|
| 528 |
+
},
|
| 529 |
+
{
|
| 530 |
+
"role": "user",
|
| 531 |
+
"content": prompt
|
| 532 |
+
}
|
| 533 |
+
],
|
| 534 |
+
model=GROQ_MODEL,
|
| 535 |
+
temperature=0.7,
|
| 536 |
+
max_tokens=4096,
|
| 537 |
+
)
|
| 538 |
+
|
| 539 |
+
return chat_completion.choices[0].message.content, context_used
|
| 540 |
+
|
| 541 |
+
except Exception as e:
|
| 542 |
+
last_error = str(e)
|
| 543 |
+
logger.warning(f"[Chatbot] Key {i+1} failed: {e}")
|
| 544 |
+
# If it's not a rate limit issue, maybe we shouldn't retry?
|
| 545 |
+
# But for robustness, we'll assume any error warrants trying another key.
|
| 546 |
+
continue
|
| 547 |
+
|
| 548 |
+
# All keys failed
|
| 549 |
+
logger.error(f"[Chatbot] All {len(GROQ_API_KEYS)} keys failed. Last error: {last_error}")
|
| 550 |
+
traceback.print_exc()
|
| 551 |
+
fallback_msg = "I apologize, but I'm currently experiencing high traffic. Please try again in a moment."
|
| 552 |
+
if context.get('weather'): # Simple fallback if we have context
|
| 553 |
+
fallback_msg += f" (Weather: {context['weather'].get('current_temp')}°C)"
|
| 554 |
+
return fallback_msg, []
|
| 555 |
|
| 556 |
|
| 557 |
# ============================================================================
|
|
|
|
| 567 |
|
| 568 |
@app.get("/health")
|
| 569 |
async def health():
|
| 570 |
+
return {"status": "healthy", "groq_configured": len(GROQ_API_KEYS) > 0}
|
| 571 |
|
| 572 |
|
| 573 |
@app.post("/session/new", response_model=SessionResponse)
|