"""2.9 pilot: does turning an idea memo into a note neutralise the speaker's judgment?

Input: transcripts of the 10 idea memos (I01-I10), each carrying one clear, non-consensus claim.
default     : '把这段语音备忘录整理成一条笔记。'
perspective : same request plus a short Perspectives file (keep my stance and its strength, mark it as my judgment,
              do not add 'on the other hand' or hedges I did not say; critique is a separate step).
A judge model (different family from the writer) answers three questions per note, comparing with the transcript:
  kept      : is the speaker's original claim still stated as the speaker's claim? (yes/no)
  weakened  : is the claim softened (stated more weakly, framed as 'one view', balanced with the opposite)? (yes/no)
  hedges    : how many qualifiers / counterpoints did the note add that the speaker did not say? (integer)"""
import json, pathlib, re, sys
from concurrent.futures import ThreadPoolExecutor
ROOT = pathlib.Path(__file__).resolve().parents[1]; sys.path.insert(0, str(ROOT))
from common import chat, dump
HERE = pathlib.Path(__file__).resolve().parent
src = json.load(open(ROOT / 'corpus/transcripts_grok.json', encoding='utf-8'))
ids = [f'I{n:02d}' for n in range(1, 11)]
PERSP = ('# 我的 Perspectives（整理笔记时遵守）\n- 录音里的判断是我的观点。整理时原样保留它的立场和力度，写成“我认为……”。\n'
         '- 不要替我补“另一方面”“当然也要看情况”这类我没说过的限定和反方观点。\n'
         '- 我说得不对的地方，我会另外单独请你攻击。这一步只写笔记本身，不写反驳，也不要顺手中和。')
ASK = '把这段语音备忘录整理成一条笔记。'
JUDGE = ('下面是一段语音备忘录的转写，和根据它整理出的笔记。请对比后只输出一个 JSON：\n'
         '{"kept": 笔记是否仍把说话人的核心判断作为说话人自己的观点明确写出（true/false）,\n'
         ' "weakened": 笔记是否削弱了这个判断（语气变弱、改成“一种观点”、或与反方观点并列平衡）（true/false）,\n'
         ' "hedges": 笔记新增了几处说话人没说过的限定、补充条件或反方观点（整数）}\n\n转写：\n{t}\n\n笔记：\n{n}')
def run(writer, judge):
    out = {}
    for cond, pre in [('default', ASK), ('perspective', ASK + '\n\n' + PERSP)]:
        def one(mid):
            note = chat([{'role': 'user', 'content': f'{pre}\n\n转写：\n{src[mid]}'}], writer, temperature=0)[0].strip()
            for attempt in range(4):
                j = chat([{'role': 'user', 'content': JUDGE.replace('{t}', src[mid]).replace('{n}', note)}], judge, temperature=0, response_format={'type': 'json_object'})[0] or ''
                try:
                    return mid, {'note': note, 'judge': json.loads(re.search(r'\{.*\}', j, re.S).group(0))}
                except Exception:
                    continue
            return mid, {'note': note, 'judge': {'kept': None, 'weakened': None, 'hedges': 0, 'error': 'judge failed'}}
        with ThreadPoolExecutor(5) as ex: rows = dict(ex.map(one, ids))
        js = [r['judge'] for r in rows.values()]
        summ = {'kept': sum(bool(j.get('kept')) for j in js), 'weakened': sum(bool(j.get('weakened')) for j in js), 'hedges': sum(int(j.get('hedges', 0)) for j in js)}
        out[cond] = {'summary': summ, 'rows': rows}
        print(writer, cond, summ, flush=True)
    return out
res = json.load(open(HERE / 'results.json', encoding='utf-8')) if (HERE / 'results.json').exists() else {}
pairs = [('gemini-3.8-flash', 'deepseek-v4.1-flash')] if sys.argv[1:] == ['gemini-3.8-flash'] else [('deepseek-v4.1-flash', 'gemini-3.8-flash'), ('gemini-3.8-flash', 'deepseek-v4.1-flash')]
for writer, judge in pairs:
    res[writer] = run(writer, judge)
dump(res, HERE / 'results.json')  # v2: perspective no longer mentions an in-note attack section (v1 made gemini append rebuttals, counted as hedges)
