Fix autofill: unify endpoint with filtered _autofill_values, empty-answer fallback, checkbox detection
This commit is contained in:
57
app.py
57
app.py
@@ -77,10 +77,14 @@ def _autofill_values(uid, form_id):
|
|||||||
profile = store.get_profile(uid) if uid else {}
|
profile = store.get_profile(uid) if uid else {}
|
||||||
about = profile.get("about_me", "")
|
about = profile.get("about_me", "")
|
||||||
display = profile.get("display_name", "")
|
display = profile.get("display_name", "")
|
||||||
|
# filter to a manageable set: all text fields + checkboxes with a real label (capped)
|
||||||
|
text_fields = [f for f in fm if f.get("type") != "checkbox"]
|
||||||
|
cb_fields = [f for f in fm if f.get("type") == "checkbox" and f.get("label", "").strip()]
|
||||||
|
cb_fields = cb_fields[:40]
|
||||||
|
sel = text_fields + cb_fields
|
||||||
field_desc = ", ".join(
|
field_desc = ", ".join(
|
||||||
f"{f['key']} ({f.get('label', '')})"
|
f"{f['key']} ({f.get('label', '')})" + (" [CB]" if f.get('type') == 'checkbox' else "")
|
||||||
+ (" [CHECKBOX — output 'X' to check, '' to leave blank]" if f.get('type') == 'checkbox' else "")
|
for f in sel
|
||||||
for f in fm
|
|
||||||
)
|
)
|
||||||
prompt = (
|
prompt = (
|
||||||
"You are filling a Washington State court form. Map the user's facts to the form fields.\n"
|
"You are filling a Washington State court form. Map the user's facts to the form fields.\n"
|
||||||
@@ -89,19 +93,19 @@ def _autofill_values(uid, form_id):
|
|||||||
f"User's display name: {display or '(not set)'}\n"
|
f"User's display name: {display or '(not set)'}\n"
|
||||||
f"User's information (About Me):\n{about or '(not provided)'}\n\n"
|
f"User's information (About Me):\n{about or '(not provided)'}\n\n"
|
||||||
"Output ONLY valid JSON. For text fields, output the value (or empty string if unknown). "
|
"Output ONLY valid JSON. For text fields, output the value (or empty string if unknown). "
|
||||||
"For CHECKBOX fields, output 'X' to check the box when the user's facts match that option, "
|
"For CHECKBOX fields, output 'X' ONLY when the user's facts clearly and unambiguously "
|
||||||
"otherwise output ''. Petitioner is the user themself (use the display name); "
|
"match that option; otherwise output ''. Be conservative — do not guess. "
|
||||||
"respondent is their spouse."
|
"Petitioner is the user themself (use the display name); respondent is their spouse."
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
resp = _ollama_chat(RAG_MODEL, [{"role": "user", "content": prompt}],
|
resp = _ollama_chat(RAG_MODEL, [{"role": "user", "content": prompt}],
|
||||||
temperature=0.1, num_predict=800)
|
temperature=0.1, num_predict=1600)
|
||||||
content = resp.get("message", {}).get("content", "")
|
content = resp.get("message", {}).get("content", "")
|
||||||
m = re.search(r"\{.*\}", content, re.DOTALL)
|
m = re.search(r"\{.*\}", content, re.DOTALL)
|
||||||
vals = json.loads(m.group(0)) if m else {}
|
vals = json.loads(m.group(0)) if m else {}
|
||||||
except Exception:
|
except Exception:
|
||||||
vals = {}
|
vals = {}
|
||||||
return {f["key"]: str(vals.get(f["key"], "") or "") for f in fm}
|
return {f["key"]: str(vals.get(f["key"], "") or "") for f in sel}
|
||||||
|
|
||||||
|
|
||||||
def _save_pdf_to_vault(uid, path, name):
|
def _save_pdf_to_vault(uid, path, name):
|
||||||
@@ -343,6 +347,13 @@ def _build_answer(agent, message, history, about_me, settings, uid, display_name
|
|||||||
|
|
||||||
final = resp.get("message", {})
|
final = resp.get("message", {})
|
||||||
answer = (final.get("content") or final.get("thinking") or "").strip()
|
answer = (final.get("content") or final.get("thinking") or "").strip()
|
||||||
|
if not answer:
|
||||||
|
# transient empty response — fall back to the reliable model (no tools)
|
||||||
|
try:
|
||||||
|
resp = _ollama_chat(GENERAL_MODEL, messages)
|
||||||
|
answer = (resp.get("message", {}).get("content") or "").strip()
|
||||||
|
except Exception:
|
||||||
|
answer = ""
|
||||||
answer = _strip_sources(answer)
|
answer = _strip_sources(answer)
|
||||||
return {"answer": answer, "citations": citations, "grounded": bool(context_blocks)}
|
return {"answer": answer, "citations": citations, "grounded": bool(context_blocks)}
|
||||||
|
|
||||||
@@ -552,34 +563,10 @@ def api_forms_autofill():
|
|||||||
uid = _uid()
|
uid = _uid()
|
||||||
d = request.get_json(force=True, silent=True) or {}
|
d = request.get_json(force=True, silent=True) or {}
|
||||||
form_id = d.get("form_id", "")
|
form_id = d.get("form_id", "")
|
||||||
spec = forms.FORM_NAMES.get(form_id)
|
if not forms.FORM_NAMES.get(form_id):
|
||||||
fm = forms.FIELDMAP.get(form_id, [])
|
|
||||||
if not spec:
|
|
||||||
return jsonify({"error": "unknown form"}), 400
|
return jsonify({"error": "unknown form"}), 400
|
||||||
profile = store.get_profile(uid) if uid else {}
|
values = _autofill_values(uid, form_id)
|
||||||
about = profile.get("about_me", "")
|
return jsonify({"form_id": form_id, "values": values})
|
||||||
display = profile.get("display_name", "")
|
|
||||||
field_desc = ", ".join(f"{f['key']} ({f.get('label','')})" for f in fm)
|
|
||||||
prompt = (
|
|
||||||
"You are filling a Washington State court form. Map the user's facts to the form fields.\n"
|
|
||||||
f"Form: {spec['name']}\n"
|
|
||||||
f"Fields: {field_desc}\n\n"
|
|
||||||
f"User's display name: {display or '(not set)'}\n"
|
|
||||||
f"User's information (About Me):\n{about or '(not provided)'}\n\n"
|
|
||||||
"Output ONLY valid JSON like {\"county\": \"...\", \"petitioner\": \"...\"}. "
|
|
||||||
"For any field you cannot determine, output an empty string. "
|
|
||||||
"Petitioner is the user themself (use the display name); respondent is their spouse."
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
resp = _ollama_chat(RAG_MODEL, [{"role": "user", "content": prompt}],
|
|
||||||
temperature=0.1, num_predict=800)
|
|
||||||
content = resp.get("message", {}).get("content", "")
|
|
||||||
m = re.search(r"\{.*\}", content, re.DOTALL)
|
|
||||||
vals = json.loads(m.group(0)) if m else {}
|
|
||||||
except Exception:
|
|
||||||
vals = {}
|
|
||||||
known = {f["key"]: str(vals.get(f["key"], "") or "") for f in fm}
|
|
||||||
return jsonify({"form_id": form_id, "values": known})
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/forms/fill", methods=["POST"])
|
@app.route("/api/forms/fill", methods=["POST"])
|
||||||
|
|||||||
Reference in New Issue
Block a user