Make /ask free by default, Claude synthesis is opt-in
Search results (FTS5 + Ollama embeddings) are shown immediately at no cost. AI synthesis via Claude is behind a "Synthesize" button that the user must explicitly click. Results are cached permanently so repeat visitors never trigger API calls. - Split ask into search_only() (free) and ask() (paid, cached) - GET /ask now uses search_only — no Claude tokens spent - POST /api/ask/synthesize triggers Claude (Haiku, ~$0.001) - Cached answers shown with "cached" badge, no re-generation - Template shows sources immediately + optional synthesize button Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -45,7 +45,8 @@ from webui.data import (
|
||||
get_author_network_full,
|
||||
get_citation_graph,
|
||||
get_comparison_data,
|
||||
get_ask_data,
|
||||
get_ask_search,
|
||||
get_ask_synthesize,
|
||||
global_search,
|
||||
)
|
||||
|
||||
@@ -325,20 +326,32 @@ def ask_page():
|
||||
result = None
|
||||
if question:
|
||||
top_k = request.args.get("top", 5, type=int)
|
||||
result = get_ask_data(db(), question, top_k=top_k)
|
||||
# Search only (free) — returns sources + cached answer if available
|
||||
result = get_ask_search(db(), question, top_k=top_k)
|
||||
return render_template("ask.html", question=question, result=result)
|
||||
|
||||
|
||||
@app.route("/api/ask", methods=["POST"])
|
||||
def api_ask():
|
||||
"""Answer a question via hybrid search + Claude. Returns JSON."""
|
||||
@app.route("/api/ask/synthesize", methods=["POST"])
|
||||
def api_ask_synthesize():
|
||||
"""Synthesize an answer via Claude (costs tokens, cached permanently). Returns JSON."""
|
||||
data = request.get_json(force=True, silent=True)
|
||||
if not data or "question" not in data:
|
||||
return jsonify({"error": "Missing 'question' in request body"}), 400
|
||||
question = data["question"]
|
||||
top_k = data.get("top_k", 5)
|
||||
cheap = data.get("cheap", True)
|
||||
result = get_ask_data(db(), question, top_k=top_k, cheap=cheap)
|
||||
result = get_ask_synthesize(db(), question, top_k=top_k, cheap=True)
|
||||
return jsonify(result)
|
||||
|
||||
|
||||
@app.route("/api/ask", methods=["POST"])
|
||||
def api_ask():
|
||||
"""Search only (free). Returns JSON with sources + cached answer if available."""
|
||||
data = request.get_json(force=True, silent=True)
|
||||
if not data or "question" not in data:
|
||||
return jsonify({"error": "Missing 'question' in request body"}), 400
|
||||
question = data["question"]
|
||||
top_k = data.get("top_k", 5)
|
||||
result = get_ask_search(db(), question, top_k=top_k)
|
||||
return jsonify(result)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user