# -*- coding: utf-8 -*- """Extract the windows-agent longitudinal record: 7 versions x 30 tasks. Reads only. Writes a tidy CSV to the scratchpad for analysis. """ import csv import io import json import os import re SRC = r'C:\xampp\htdocs\windows-agent\bench\results' OUT = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'wa_tasks.csv') runs = [] for fn in sorted(os.listdir(SRC)): if not fn.endswith('.json'): continue d = json.load(io.open(os.path.join(SRC, fn), encoding='utf-8')) m = re.match(r'(\d{4}-\d{2}-\d{2})_(\d{6})_(.+)\.json', fn) label = m.group(3) if m else fn vm = re.search(r'v(\d+)', label) runs.append(dict(file=fn, date=m.group(1) if m else '', label=label, version=int(vm.group(1)) if vm else None, model=d.get('model'), overall=d.get('overall'), cost=d.get('estimated_cost_usd'), elapsed=d.get('elapsed_seconds'), finished=d.get('finished_at'), results=d.get('results') or [])) runs.sort(key=lambda r: (r['version'] if r['version'] is not None else 999)) print('=' * 100) print('RUN-LEVEL RECORD') print('=' * 100) print(' %-26s %-16s %6s %8s %8s %6s %6s' % ('label', 'model', 'score', 'cost $', 'minutes', 'tasks', 'errors')) print(' ' + '-' * 96) for r in runs: errs = sum(1 for t in r['results'] if (t.get('error') or '').strip()) print(' %-26s %-16s %6.1f %8.4f %8.1f %6d %6d' % (r['label'], r['model'], r['overall'], r['cost'], r['elapsed'] / 60.0, len(r['results']), errs)) # tidy csv cols = ['version', 'label', 'date', 'model', 'run_overall', 'run_cost_usd', 'run_minutes', 'task_id', 'task_name', 'category', 'earned', 'possible', 'percent', 'penalty', 'tool_calls', 'n_tools', 'tools', 'duration_s', 'input_tokens', 'output_tokens', 'error', 'n_checks', 'checks_failed'] w = io.open(OUT, 'w', encoding='utf-8', newline='') cw = csv.DictWriter(w, fieldnames=cols) cw.writeheader() for r in runs: for t in r['results']: checks = t.get('checks') or [] cw.writerow({ 'version': r['version'], 'label': r['label'], 'date': r['date'], 'model': r['model'], 'run_overall': r['overall'], 'run_cost_usd': r['cost'], 'run_minutes': round(r['elapsed'] / 60.0, 2), 'task_id': t.get('id'), 'task_name': t.get('name'), 'category': t.get('category'), 'earned': t.get('earned'), 'possible': t.get('possible'), 'percent': t.get('percent'), 'penalty': t.get('penalty'), 'tool_calls': t.get('tool_calls'), 'n_tools': len(t.get('tools') or []), 'tools': '|'.join(t.get('tools') or []), 'duration_s': t.get('duration'), 'input_tokens': t.get('input_tokens'), 'output_tokens': t.get('output_tokens'), 'error': (t.get('error') or '').replace('\n', ' ')[:300], 'n_checks': len(checks), 'checks_failed': sum(1 for c in checks if not c.get('passed')), }) w.close() print('\n wrote %s (%d rows)' % (OUT, sum(len(r['results']) for r in runs))) # categories cats = {} for t in runs[-1]['results']: cats[t['category']] = cats.get(t['category'], 0) + 1 print(' categories:', cats)