File size: 4,170 Bytes
990895d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
"""Build coach evidence blocks and SERVER_PICKS from server math.

Formats precomputed probabilities for prompts; never invents numbers.
"""

from __future__ import annotations

from typing import Any

from app.stats_math import (
    FORMULAS,
    by_emotion,
    by_remedy,
    by_tag,
    daily_rates,
    data_thin,
    scored_entries,
    server_picks,
)


def strip_sensitive(text: str) -> str:
    """Best-effort strip of emails and long digit runs from prompt text."""

    import re

    cleaned = re.sub(
        r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b",
        "[email]",
        text,
    )
    cleaned = re.sub(r"\b\d{8,}\b", "[digits]", cleaned)
    return cleaned


def format_evidence_block(
    entries: list[dict[str, Any]],
    daily_rows: list[dict[str, Any]],
    *,
    min_n: int,
    shrink_k: float,
) -> str:
    """Render the EVIDENCE markdown block for coach prompts."""

    scored = scored_entries(entries)
    remedies = by_remedy(entries, min_n=min_n, shrink_k=shrink_k)
    tags = by_tag(entries)[:8]
    emotions = by_emotion(entries)[:8]
    rates = daily_rates(daily_rows)
    lines = [
        "EVIDENCE (server-computed; do not invent numbers)",
        f"n_scored: {len(scored)}",
        f"min_n: {min_n}",
        "TOP_REMEDIES: remedy | n | p_worked | p_helped | rank",
    ]
    if remedies:
        for row in remedies[:10]:
            lines.append(
                f"- {row['key']} | {row['n']} | {row['p_worked']:.3f} | "
                f"{row['p_helped']:.3f} | {row['rank']:.3f}"
            )
    else:
        lines.append("- (none above min_n)")
    lines.append("WORST_TAGS: tag | n | p_fail")
    if tags:
        for row in tags:
            lines.append(f"- {row['key']} | {row['n']} | {row['p_failed']:.3f}")
    else:
        lines.append("- (none)")
    lines.append("EMOTION_HITS: emotion | n | p_helped")
    if emotions:
        for row in emotions:
            lines.append(f"- {row['key']} | {row['n']} | {row['p_helped']:.3f}")
    else:
        lines.append("- (none)")
    lines.append(
        "DAILY_RATES: "
        f"p_brick_done={rates['p_brick_done']:.3f} "
        f"p_corn_ok={rates['p_corn_ok']:.3f} "
        f"p_no_fc={rates['p_no_fc']:.3f} "
        f"p_rerun_clean={rates['p_rerun_clean']:.3f} "
        f"p_court_closed={rates['p_court_closed']:.3f} "
        f"avg_points={rates['avg_points']:.3f}"
    )
    lines.append(
        "FORMULAS: "
        f"p_helped={FORMULAS['p_helped']}; rank={FORMULAS['rank']}"
    )
    lines.append(f"DATA_THIN: {str(data_thin(len(scored))).lower()}")
    return "\n".join(lines)


def format_server_picks(picks: list[dict[str, Any]]) -> str:
    """Render numbered SERVER_PICKS lines for prompts and debug paste."""

    if not picks:
        return "SERVER_PICKS: (none)"
    lines = ["SERVER_PICKS:"]
    for index, pick in enumerate(picks, start=1):
        lines.append(
            f"{index}) {pick['remedy_key']} pick={pick['pick']:.3f} "
            f"n={pick['n']} p_helped={pick['p_helped']:.3f}"
        )
    return "\n".join(lines)


def build_evidence(
    entries: list[dict[str, Any]],
    daily_rows: list[dict[str, Any]],
    current_tags: list[str],
    *,
    min_n: int,
    shrink_k: float,
    match_alpha: float,
) -> dict[str, Any]:
    """Return structured evidence plus formatted blocks and picks."""

    scored = scored_entries(entries)
    picks = server_picks(
        entries,
        current_tags,
        min_n=min_n,
        shrink_k=shrink_k,
        match_alpha=match_alpha,
    )
    block = format_evidence_block(
        entries,
        daily_rows,
        min_n=min_n,
        shrink_k=shrink_k,
    )
    picks_text = format_server_picks(picks)
    return {
        "n_scored": len(scored),
        "min_n": min_n,
        "DATA_THIN": data_thin(len(scored)),
        "by_remedy": by_remedy(entries, min_n=min_n, shrink_k=shrink_k),
        "by_tag": by_tag(entries),
        "by_emotion": by_emotion(entries),
        "daily": daily_rates(daily_rows),
        "server_picks": picks,
        "evidence_block": block,
        "server_picks_text": picks_text,
        "formulas": FORMULAS,
    }