Files
2026-02-08 23:15:01 +03:00

184 lines
5.2 KiB
Python

import os
import json
import requests
import sys
from pathlib import Path
OPENROUTER_URL = "https://openrouter.ai/api/v1/chat/completions"
MODEL = "arcee-ai/trinity-large-preview:free"
def get_base_dir():
if getattr(sys, "frozen", False):
return Path(sys.executable).parent
return Path(__file__).resolve().parent
BASE_DIR = get_base_dir()
PROMPT_PATH = BASE_DIR / "core" / "prompt.txt"
API_CONFIG_PATH = BASE_DIR / "config" / "api_keys.json"
def load_api_keys() -> dict:
if not os.path.exists(API_CONFIG_PATH):
return {}
try:
with open(API_CONFIG_PATH, "r", encoding="utf-8") as f:
return json.load(f)
except Exception as e:
print(f"❌ Failed to read api_keys.json: {e}")
return {}
def get_openrouter_key() -> str | None:
keys = load_api_keys()
return keys.get("openrouter_api_key")
def load_system_prompt() -> str:
try:
with open(PROMPT_PATH, "r", encoding="utf-8") as f:
return f.read()
except Exception as e:
print(f"⚠️ prompt.txt couldn't be loaded: {e}")
return "You are Jarvis, a helpful AI assistant."
SYSTEM_PROMPT = load_system_prompt()
def safe_json_parse(text: str) -> dict | None:
if not text:
return None
text = text.strip()
if "```json" in text:
try:
start = text.index("```json") + 7
end = text.index("```", start)
text = text[start:end].strip()
except:
pass
elif "```" in text:
try:
start = text.index("```") + 3
end = text.index("```", start)
text = text[start:end].strip()
except:
pass
try:
start = text.index("{")
end = text.rindex("}") + 1
json_str = text[start:end]
return json.loads(json_str)
except Exception as e:
print(f"⚠️ JSON parse error: {e}")
print(f"⚠️ Raw text preview: {text[:200]}")
return None
def get_llm_output(user_text: str, memory_block: dict | None = None) -> dict:
if not user_text or not user_text.strip():
return {
"intent": "chat",
"parameters": {},
"needs_clarification": False,
"text": "Sir, I didn't catch that.",
"memory_update": None
}
api_key = get_openrouter_key()
if not api_key:
print("❌ OPENROUTER API KEY NOT FOUND")
return {
"intent": "chat",
"parameters": {},
"needs_clarification": False,
"text": "OpenRouter API key is missing, Sir.",
"memory_update": None
}
memory_str = ""
if memory_block:
memory_str = "\n".join(f"{k}: {v}" for k, v in memory_block.items())
user_prompt = f"""User message: "{user_text}"
Known user memory:
{memory_str if memory_str else "No memory available"}"""
payload = {
"model": MODEL,
"messages": [
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": user_prompt}
],
"temperature": 0.2,
"max_tokens": 500
}
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
"HTTP-Referer": "http://localhost",
"X-Title": "Jarvis-Assistant"
}
try:
response = requests.post(
OPENROUTER_URL,
headers=headers,
json=payload,
timeout=30
)
if response.status_code != 200:
print(f"❌ OpenRouter API Error: {response.text}")
return {
"intent": "chat",
"parameters": {},
"needs_clarification": False,
"text": f"Sir, API error ({response.status_code}).",
"memory_update": None
}
data = response.json()
content = data["choices"][0]["message"]["content"]
parsed = safe_json_parse(content)
if parsed:
return {
"intent": parsed.get("intent", "chat"),
"parameters": parsed.get("parameters", {}),
"needs_clarification": parsed.get("needs_clarification", False),
"text": parsed.get("text"),
"memory_update": parsed.get("memory_update")
}
return {
"intent": "chat",
"parameters": {},
"needs_clarification": False,
"text": content,
"memory_update": None
}
except requests.exceptions.Timeout:
print("❌ OpenRouter timeout")
return {
"intent": "chat",
"parameters": {},
"needs_clarification": False,
"text": "Sir, the request timed out.",
"memory_update": None
}
except Exception as e:
print(f"❌ LLM ERROR: {e}")
return {
"intent": "chat",
"parameters": {},
"needs_clarification": False,
"text": "Sir, a system error occurred.",
"memory_update": None
}