File size: 4,215 Bytes
fb916fd
 
 
a6fb6cf
02e346e
a6fb6cf
fb916fd
 
3ce1649
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a6fb6cf
 
 
3ce1649
fb916fd
02e346e
a6fb6cf
 
 
3ce1649
 
a6fb6cf
 
5d9b181
3ce1649
 
 
a6fb6cf
 
 
3ce1649
 
 
a6fb6cf
3ce1649
 
117239e
a6fb6cf
5d9b181
 
a6fb6cf
 
 
3ce1649
 
 
 
 
a3bd4b6
 
 
117239e
a3bd4b6
117239e
3ce1649
 
a6fb6cf
 
 
 
3ce1649
 
 
a6fb6cf
 
 
3ce1649
 
a6fb6cf
 
 
3ce1649
a6fb6cf
 
 
3ce1649
a6fb6cf
 
 
 
 
 
 
 
 
 
5d9b181
3ce1649
 
 
 
fb916fd
117239e
a3bd4b6
02e346e
 
fb916fd
02e346e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# src/reasoning_panel.py
from __future__ import annotations

from typing import Dict, List

import streamlit as st


def _render_popover_for_item(
    label: str,
    ref_nums: List[int],
    registry: List[Dict[str, object]],
) -> None:
    if not ref_nums:
        return
    with st.expander(label, expanded=False):
        for n in ref_nums:
            rec = next((r for r in registry if int(r.get("n", r.get("rank", -1))) == int(n)), None)
            if not rec:
                continue
            title = f"[{n}] {rec.get('doc_name','')} β€” p.{rec.get('page',0)} | score {float(rec.get('score',0.0)):.3f}"
            st.markdown(f"**{title}**")
            st.write(rec.get("text", ""))
            if rec.get("source_path"):
                st.caption(rec["source_path"])


def _bullets_html(items: List[str]) -> str:
    if not items:
        return "_(none)_"
    return "\n".join([f"- {s}" for s in items])


def build_panel_data(result: Dict[str, object]) -> Dict[str, object]:
    meta = result.get("meta", {}) if isinstance(result, dict) else {}
    annotated = meta.get("annotated", {}) if isinstance(meta, dict) else {}
    claim_mapping = meta.get("claim_mapping", {}) if isinstance(meta, dict) else {}

    assess_html = annotated.get("assessment_html", []) if isinstance(annotated, dict) else []
    plan_html = annotated.get("plan_html", []) if isinstance(annotated, dict) else []

    assess_map_items = claim_mapping.get("assessment", {}).get("items", []) if isinstance(claim_mapping, dict) else []
    plan_map_items = claim_mapping.get("plan", {}).get("items", []) if isinstance(claim_mapping, dict) else []

    return {
        "assessment_html": assess_html,
        "plan_html": plan_html,
        "assessment_map": assess_map_items,
        "plan_map": plan_map_items,
        "citations": result.get("citations", []),
        "timings": meta.get("timings", {}),
        "map_mode": meta.get("map_mode", "production"),
        "registry_cap": meta.get("registry_cap", None),
        "nl_explanation": meta.get("nl_explanation", ""),
    }


def render_reasoning_panel(panel_data: Dict[str, object]) -> None:
    st.subheader("Reasoning & Evidence")

    timings = panel_data.get("timings", {})
    map_mode = panel_data.get("map_mode", "production")
    cap = panel_data.get("registry_cap", None)
    st.caption(f"Evidence mode: **{map_mode}**" + (f"  |  registry cap: {cap}" if cap else ""))

    # Explanation (only here; top-level expander removed for non-dup UX)
    expl = (panel_data.get("nl_explanation", "") or "").strip()
    if expl:
        with st.expander("🧩 Explain My Reasoning", expanded=False):
            st.write(expl)

    registry = panel_data.get("citations", [])

    col1, col2 = st.columns(2)
    with col1:
        st.markdown("**Assessment (annotated)**")
        st.markdown(_bullets_html(panel_data.get("assessment_html", [])), unsafe_allow_html=True)
        for i, it in enumerate(panel_data.get("assessment_map", []), start=1):
            _render_popover_for_item(f"[?] Evidence for Assessment #{i}", it.get("ref_nums", []), registry)

    with col2:
        st.markdown("**Plan (annotated)**")
        st.markdown(_bullets_html(panel_data.get("plan_html", [])), unsafe_allow_html=True)
        for i, it in enumerate(panel_data.get("plan_map", []), start=1):
            _render_popover_for_item(f"[?] Evidence for Plan #{i}", it.get("ref_nums", []), registry)

    st.markdown("---")
    st.markdown("**Evidence Registry** (global refs)")
    if not registry:
        st.caption("No evidence available. Build the FAISS index in Step 1 to enable mapping.")
        return

    for r in registry:
        with st.container(border=True):
            n = r.get("n", r.get("rank", "?"))
            doc = r.get("doc_name", "")
            page = r.get("page", 0)
            score = r.get("score", r.get("score_max", 0.0))
            st.write(f"**[{n}] {doc}** β€” page {page}  |  score: {float(score):.3f}")
            st.write(r.get("text", ""))
            sp = r.get("source_path", "")
            if sp:
                st.caption(sp)

    if isinstance(timings, dict):
        st.caption(f"Timings: {timings}")