You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
154 lines
4.9 KiB
154 lines
4.9 KiB
#!/usr/bin/env python3
|
|
|
|
"""
|
|
secretchat-api-example.py
|
|
|
|
• Prints model IDs at start
|
|
• Shows which model handles each sentence, 5 sentences
|
|
|
|
Requires:
|
|
pip install requests python-dotenv
|
|
"""
|
|
|
|
import os
|
|
import random
|
|
import time
|
|
from typing import List, Union, Tuple, Optional
|
|
|
|
import requests
|
|
from dotenv import load_dotenv
|
|
|
|
|
|
# ── API-key helper ───────────────────────────────────────────────────────────
|
|
def load_api_key() -> str:
|
|
load_dotenv(os.path.join(os.path.expanduser("~"), ".secretlab.env"))
|
|
key = os.getenv("SECRETLAB_API_KEY")
|
|
if not key:
|
|
raise ValueError("SECRETLAB_API_KEY not found")
|
|
return key
|
|
|
|
|
|
# ── /api/models helper ───────────────────────────────────────────────────────
|
|
def fetch_model_ids(api_key: str, base_url: str) -> List[str]:
|
|
resp = requests.get(
|
|
f"{base_url}/api/models",
|
|
headers={"Authorization": f"Bearer {api_key}"},
|
|
timeout=300,
|
|
)
|
|
resp.raise_for_status()
|
|
raw: Union[list, dict] = resp.json()
|
|
|
|
if isinstance(raw, dict): # unwrap {"models":[...]} or similar
|
|
for key in ("models", "data", "items", "result"):
|
|
if key in raw and isinstance(raw[key], list):
|
|
raw = raw[key]
|
|
break
|
|
|
|
if not isinstance(raw, list):
|
|
raise RuntimeError("Unexpected /api/models response")
|
|
|
|
ids: List[str] = []
|
|
for item in raw:
|
|
if isinstance(item, str):
|
|
ids.append(item)
|
|
elif isinstance(item, dict):
|
|
if isinstance(item.get("model"), str):
|
|
ids.append(item["model"])
|
|
elif isinstance(item.get("ollama"), dict) and isinstance(
|
|
item["ollama"].get("model"), str
|
|
):
|
|
ids.append(item["ollama"]["model"])
|
|
if not ids:
|
|
raise RuntimeError("No model IDs found")
|
|
return ids
|
|
|
|
|
|
# ── classify helper ──────────────────────────────────────────────────────────
|
|
def classify(
|
|
sentence: str,
|
|
api_key: str,
|
|
base_url: str,
|
|
models: List[str],
|
|
retries: int = 6,
|
|
backoff: int = 2,
|
|
) -> Tuple[str, Optional[str]]:
|
|
"""Return (model_used, classification or None)."""
|
|
url = f"{base_url}/api/chat/completions"
|
|
|
|
for attempt in range(1, retries + 1):
|
|
model = random.choice(models)
|
|
payload = {
|
|
"model": model,
|
|
"messages": [
|
|
{
|
|
"role": "system",
|
|
"content": (
|
|
"Respond ONLY with 'Positive' or 'Negative'. "
|
|
"No other words or punctuation."
|
|
),
|
|
},
|
|
{"role": "user", "content": f"Classify this:\n{sentence}"},
|
|
],
|
|
"temperature": 0.0,
|
|
}
|
|
|
|
try:
|
|
r = requests.post(
|
|
url,
|
|
headers={
|
|
"Authorization": f"Bearer {api_key}",
|
|
"Content-Type": "application/json",
|
|
},
|
|
json=payload,
|
|
timeout=300,
|
|
)
|
|
if r.status_code == 200:
|
|
result = r.json()["choices"][0]["message"]["content"].strip()
|
|
return model, result
|
|
print(f"API error {r.status_code}: {r.text}")
|
|
return model, None
|
|
except requests.exceptions.RequestException as e:
|
|
print(f"Network error ({attempt}/{retries}): {e}")
|
|
if attempt < retries:
|
|
time.sleep(backoff)
|
|
backoff *= 2
|
|
else:
|
|
return model, None
|
|
|
|
|
|
# ── main loop ────────────────────────────────────────────────────────────────
|
|
def main() -> None:
|
|
api_key = load_api_key()
|
|
BASE = "https://chat.secretlab.page"
|
|
models = fetch_model_ids(api_key, BASE)
|
|
|
|
print("Models:")
|
|
for m in models:
|
|
print(m)
|
|
print("-" * 40, "\n")
|
|
|
|
sentences = [
|
|
"I love sunny days!",
|
|
"This is a bland sandwich.",
|
|
"I really hate waiting in long lines.",
|
|
"The meeting was okay, nothing special.",
|
|
"I am so excited about the upcoming holidays!",
|
|
]
|
|
|
|
for run in range(1): # repeat 1 times
|
|
print(f"\n--- Run {run+1} ---\n")
|
|
|
|
for idx, s in enumerate(sentences, 1):
|
|
model_used, res = classify(s, api_key, BASE, models)
|
|
|
|
print(f"Sentence {idx}: {s}")
|
|
print(f"Model : {model_used}")
|
|
print(f"Result : {res or 'Failed'}\n")
|
|
|
|
time.sleep(1) # optional pause between runs
|
|
|
|
print("\nAll runs complete!\n")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|
|
|