fix: use fast model for story selection, gemma4 for summaries only

gemma4:26b under format:json ignores the bare-array instruction and returns a
reasoning object ({"thought": ...}), which broke Phase-1 selection (Unterminated
string -> silent fallback to first-5). Selection now uses ollama_select_model
(default qwen2.5:1.5b); summaries stay on gemma4:26b. Also tolerate dict-shaped
selection responses defensively.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Mortdecai
2026-06-07 13:36:20 -04:00
parent 362053f8d6
commit b901b8be6e
2 changed files with 11 additions and 2 deletions
+1
View File
@@ -4,6 +4,7 @@
"freshrss_api_key": "your-api-password",
"ollama_url": "http://your-ollama-ip:11434",
"ollama_model": "gemma4:26b",
"ollama_select_model": "qwen2.5:1.5b",
"yourls_url": "http://your-yourls-ip/yourls-api.php",
"yourls_user": "yourls-username",
"yourls_pass": "yourls-password",
+10 -2
View File
@@ -24,6 +24,10 @@ FRESHRSS_USER = config["freshrss_user"]
FRESHRSS_TOKEN = config["freshrss_api_key"]
OLLAMA_URL = config["ollama_url"]
OLLAMA_MODEL = config["ollama_model"]
# Phase-1 story selection wants a fast model that emits a bare JSON array.
# gemma4 (the summary model) ignores the format and returns reasoning objects,
# so selection uses a small, literal model by default.
OLLAMA_SELECT_MODEL = config.get("ollama_select_model", "qwen2.5:1.5b")
YOURLS_URL = config["yourls_url"]
YOURLS_USER = config["yourls_user"]
YOURLS_PASS = config["yourls_pass"]
@@ -143,12 +147,16 @@ def summarize_news(items, count=5, length="30-50 words"):
try:
resp = requests.post(
f"{OLLAMA_URL}/api/generate",
json={"model": OLLAMA_MODEL, "prompt": prompt_select, "stream": False,
json={"model": OLLAMA_SELECT_MODEL, "prompt": prompt_select, "stream": False,
"options": {"num_ctx": 16384, "temperature": 0.1}, "format": "json"},
timeout=300
).json()
data = json.loads(resp.get("response", "[]"))
selected_indices = data if isinstance(data, list) else list(data.values())[0]
if isinstance(data, list):
selected_indices = data
elif isinstance(data, dict):
# Tolerate {"stories": [...]} or similar; pick the first list value.
selected_indices = next((v for v in data.values() if isinstance(v, list)), [])
except Exception as e:
print(f"[!] Selection error: {e}")
selected_indices = list(range(min(count, len(items))))