Browser-back / ai.py
Nrighton233j
Replace WebView auth backend with AI backend: summarize, smart search, related links
0cfa5c0
Raw
History Blame Contribute Delete
2.49 kB
"""
ai.py — Groq-powered reasoning for the B24 Browser AI backend.
Uses llama-3.3-70b-versatile, same model as Joy on B24 Messenger.
"""
import os
from groq import Groq
GROQ_KEY = os.environ.get("groq_key")
_client = Groq(api_key=GROQ_KEY) if GROQ_KEY else None
MODEL = "llama-3.3-70b-versatile"
def _chat(system: str, user: str, max_tokens: int = 700) -> str:
if not _client:
return "AI is not configured (missing groq_key secret)."
completion = _client.chat.completions.create(
model=MODEL,
messages=[
{"role": "system", "content": system},
{"role": "user", "content": user},
],
max_tokens=max_tokens,
temperature=0.4,
)
return completion.choices[0].message.content.strip()
def summarize_page(url: str, text: str) -> str:
text = (text or "")[:12000]
system = (
"You summarize web pages clearly and concisely for someone browsing "
"on a phone. Use short paragraphs or bullet points. No fluff."
)
user = f"URL: {url}\n\nPage content:\n{text}\n\nSummarize this page."
return _chat(system, user, max_tokens=500)
def synthesize_search(query: str, results: list) -> str:
listing = "\n".join(
f"- {r['title']}: {r['snippet']} ({r['url']})" for r in results[:8]
)
system = (
"You are a smart search assistant. Given raw search results, write "
"a short, direct answer to the user's query, citing which result(s) "
"back it up by title. Keep it tight — a few sentences."
)
user = f"Query: {query}\n\nSearch results:\n{listing}\n\nAnswer the query."
return _chat(system, user, max_tokens=400)
def suggest_related(url: str, text: str) -> list:
text = (text or "")[:6000]
system = (
"Given a web page's content, suggest 5 short, specific search "
"queries a curious reader might want to explore next. "
"Return ONLY a JSON array of strings, nothing else."
)
user = f"URL: {url}\n\nPage content:\n{text}"
raw = _chat(system, user, max_tokens=200)
import json
try:
cleaned = raw.strip().strip("`").replace("json", "", 1) if raw.strip().startswith("```") else raw
parsed = json.loads(cleaned)
if isinstance(parsed, list):
return [str(x) for x in parsed[:5]]
except (json.JSONDecodeError, ValueError):
pass
lines = [l.strip("-• ").strip() for l in raw.splitlines() if l.strip()]
return lines[:5]