Spaces:
Sleeping
Sleeping
Add OpenRouter backup key failover
Browse files- src/humeo/hook_detector.py +42 -25
src/humeo/hook_detector.py
CHANGED
|
@@ -55,11 +55,11 @@ from humeo.env import (
|
|
| 55 |
OPENROUTER_BASE_URL,
|
| 56 |
current_llm_provider,
|
| 57 |
model_name_for_provider,
|
| 58 |
-
openrouter_default_headers,
|
| 59 |
-
resolve_gemini_api_key,
|
| 60 |
-
resolve_llm_provider,
|
| 61 |
-
|
| 62 |
-
)
|
| 63 |
from humeo.gemini_generate import gemini_generate_config
|
| 64 |
from humeo.hook_library import (
|
| 65 |
format_hook_examples,
|
|
@@ -474,26 +474,43 @@ def request_hook_decisions(
|
|
| 474 |
raise RuntimeError("Gemini returned empty response text for hook detection")
|
| 475 |
return response.text
|
| 476 |
|
| 477 |
-
|
| 478 |
-
|
| 479 |
-
|
| 480 |
-
|
| 481 |
-
|
| 482 |
-
|
| 483 |
-
|
| 484 |
-
|
| 485 |
-
|
| 486 |
-
|
| 487 |
-
|
| 488 |
-
|
| 489 |
-
|
| 490 |
-
|
| 491 |
-
|
| 492 |
-
|
| 493 |
-
|
| 494 |
-
|
| 495 |
-
|
| 496 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 497 |
decisions = _parse_decisions(raw)
|
| 498 |
return decisions, raw
|
| 499 |
|
|
|
|
| 55 |
OPENROUTER_BASE_URL,
|
| 56 |
current_llm_provider,
|
| 57 |
model_name_for_provider,
|
| 58 |
+
openrouter_default_headers,
|
| 59 |
+
resolve_gemini_api_key,
|
| 60 |
+
resolve_llm_provider,
|
| 61 |
+
resolve_openrouter_api_keys,
|
| 62 |
+
)
|
| 63 |
from humeo.gemini_generate import gemini_generate_config
|
| 64 |
from humeo.hook_library import (
|
| 65 |
format_hook_examples,
|
|
|
|
| 474 |
raise RuntimeError("Gemini returned empty response text for hook detection")
|
| 475 |
return response.text
|
| 476 |
|
| 477 |
+
keys = resolve_openrouter_api_keys()
|
| 478 |
+
last_error: Exception | None = None
|
| 479 |
+
for key_idx, api_key in enumerate(keys, start=1):
|
| 480 |
+
try:
|
| 481 |
+
client = OpenAI(
|
| 482 |
+
api_key=api_key,
|
| 483 |
+
base_url=OPENROUTER_BASE_URL,
|
| 484 |
+
default_headers=openrouter_default_headers(),
|
| 485 |
+
)
|
| 486 |
+
response = client.chat.completions.create(
|
| 487 |
+
model=model_name,
|
| 488 |
+
messages=[
|
| 489 |
+
{"role": "system", "content": system},
|
| 490 |
+
{"role": "user", "content": user_text},
|
| 491 |
+
],
|
| 492 |
+
temperature=0.2,
|
| 493 |
+
response_format={"type": "json_object"},
|
| 494 |
+
)
|
| 495 |
+
text = _openai_message_text(response.choices[0].message.content)
|
| 496 |
+
if not text:
|
| 497 |
+
raise RuntimeError("OpenRouter returned empty response text for hook detection")
|
| 498 |
+
if key_idx > 1:
|
| 499 |
+
logger.info("OpenRouter hook detection succeeded with fallback key %d/%d", key_idx, len(keys))
|
| 500 |
+
return text
|
| 501 |
+
except Exception as exc:
|
| 502 |
+
last_error = exc
|
| 503 |
+
if key_idx < len(keys):
|
| 504 |
+
logger.warning(
|
| 505 |
+
"OpenRouter hook detection failed with key %d/%d: %s; trying fallback",
|
| 506 |
+
key_idx,
|
| 507 |
+
len(keys),
|
| 508 |
+
exc,
|
| 509 |
+
)
|
| 510 |
+
assert last_error is not None
|
| 511 |
+
raise last_error
|
| 512 |
+
|
| 513 |
+
raw = _retry_llm("Gemini hook detection", _call)
|
| 514 |
decisions = _parse_decisions(raw)
|
| 515 |
return decisions, raw
|
| 516 |
|