"""2.1 demo: watch the context meter of an agent harness (DeepSeek Harness web UI) grow while you type only a few characters.

Needs a running DSH web (`pnpm dsh web --no-open`, port 3080) and its launch token in build/dsh_explore/token.txt.
Model: DeepSeek V4.1 Flash via Ollama Cloud. The session runs in the public deepseek_harness checkout and is
archived at the end. Screenshots go to assets/ch02_01/; numbers to experiments/2_1_stateless/dsh_results.json.
"""
import json, re, sys
from playwright.sync_api import sync_playwright

tok = open('build/dsh_explore/token.txt').read().strip()
memos = {m['id']: m['text'] for m in json.load(open('experiments/corpus/memos.json', encoding='utf-8'))['memos']}
turns = ['下面是我这周几条语音备忘录的转写，人名可能有错。我的同事里负责部署的叫蔺思远，后端叫韩昱。请先记住，简单回复“好的”即可，不要读写任何文件，也不要调用工具。\n\n'
         + ' '.join(memos[i] for i in ['W01', 'W07', 'W10', 'W12', 'W16', 'W17']),
         '一共提到了几个人？', '谁负责部署？', '账单为什么涨了？', '下个月谁要来？', '负责部署的同事叫什么名字？']
rows = []
with sync_playwright() as p:
    b = p.chromium.launch(); pg = b.new_page(viewport={'width': 1100, 'height': 760}, device_scale_factor=2)
    pg.goto(f'http://127.0.0.1:3080/?token={tok}'); pg.wait_for_timeout(3000)
    pg.get_by_role('button', name='Choose workspace').click(); pg.wait_for_timeout(800)
    pg.get_by_role('menuitem', name='deepseek_harness').click(); pg.wait_for_timeout(1500)
    pg.locator('button[aria-label^="Select model"]').click(); pg.wait_for_timeout(800)
    pg.locator('[role=menuitem]').filter(has_text='Model').first.click(); pg.wait_for_timeout(1500)
    print('menus', [m.inner_text()[:600].replace('\n', ' | ') for m in pg.query_selector_all('[role=menu], [role=listbox]')])
    opts = [t.strip() for t in pg.locator('[role=menuitemradio], [role=menuitem], [role=option]').all_inner_texts()]
    print('options', opts)
    pick = pg.locator('[role=menuitemradio], [role=menuitem], [role=option]').filter(has_text=re.compile('DeepSeek.?V4.?1.?Flash', re.I)).first
    pick.click(); pg.wait_for_timeout(1000)
    print('model now', pg.locator('button[aria-label^="Select model"]').get_attribute('aria-label'))
    if '--probe' in sys.argv:
        b.close(); raise SystemExit
    pg.get_by_role('button', name='Collapse sidebar').click(); pg.wait_for_timeout(600)
    for i, q in enumerate(turns, 1):
        box = pg.get_by_role('textbox').last
        box.click(); box.fill(q); pg.keyboard.press('Enter')
        pg.wait_for_timeout(3000)
        for _ in range(90):  # wait until the turn finishes (send button re-enabled and a usage line for this turn exists)
            if pg.get_by_text(re.compile(r'^Usage ')).count() >= i: break
            pg.wait_for_timeout(1000)
        pg.wait_for_timeout(1500)
        body = pg.inner_text('body')
        tot = re.findall(r'([\d.]+K?) tok\s*·\s*Cache hit (\d+)%', body)
        pct = re.findall(r'(\d+)%\s*$', body, re.M)
        meter = pg.locator('[aria-label$="of context used"]').first.get_attribute('aria-label')
        rows.append({'turn': i, 'typed_chars': len(q), 'session_tokens': tot[-1][0] if tot else None,
                     'cache_hit_pct': tot[-1][1] if tot else None, 'meter': meter})
        print(rows[-1])
        pg.screenshot(path=f'assets/ch02_01/dsh_turn{i}.png')
    json.dump({'model': 'DeepSeek V4.1 Flash (Ollama Cloud) via DSH web', 'turns': rows}, open('experiments/2_1_stateless/dsh_results.json', 'w'), ensure_ascii=False, indent=1)
    # archive the demo session so it does not linger in the user's DSH list
    pg.get_by_role('button', name=re.compile('Expand sidebar|Open sidebar|Show sidebar')).first.click(); pg.wait_for_timeout(800)
    row = pg.get_by_role('treeitem').filter(has_text='语音').first
    row.hover(); pg.wait_for_timeout(400)
    arch = row.get_by_role('button', name='Archive session')
    if arch.count(): arch.first.click(force=True); pg.wait_for_timeout(1000); print('archived')
    b.close()
