| import os |
| import json |
| import csv |
| import zipfile |
| import hashlib |
| import time |
| from typing import Dict, Any, List |
| from benchmark import config |
|
|
| def calculate_sha256(file_path: str) -> str: |
| h = hashlib.sha256() |
| with open(file_path, "rb") as f: |
| while True: |
| chunk = f.read(65536) |
| if not chunk: |
| break |
| h.update(chunk) |
| return h.hexdigest() |
|
|
| def create_benchmark_package( |
| run_id: str, |
| source_metadata: Dict[str, Any], |
| questions: List[Dict[str, Any]], |
| model_pairs_meta: Dict[str, Any], |
| plain_models_list: Dict[str, Any], |
| rif_models_list: Dict[str, Any], |
| raw_logs: List[Dict[str, Any]], |
| results_summary: Dict[str, Any] |
| ) -> str: |
| """ |
| Creates a structured benchmark directory, writes JSON/CSV output files, |
| generates a checksum manifest, and compresses it into a downloadable zip file. |
| Returns: Absolute path of the ZIP package. |
| """ |
| |
| run_root_name = f"kalpana-benchmark-{run_id}" |
| run_root = os.path.join(config.RUNS_DIR, run_root_name) |
| |
| |
| subdirs = [ |
| "source", |
| "questions", |
| "model-pairs", |
| "requests", |
| "responses", |
| "results", |
| "configuration", |
| "integrity" |
| ] |
| for d in subdirs: |
| os.makedirs(os.path.join(run_root, d), exist_ok=True) |
| |
| |
| readme_content = f"""Kalpanā Independent Multi-Model Benchmark Run Package |
| Run ID: {run_id} |
| Timestamp: {time.strftime('%Y-%m-%d %H:%M:%S')} |
| Label: {results_summary.get('run_label', 'CUSTOM EVALUATOR RUN')} |
| |
| This package contains all verification details, raw prompts, API logs, and metrics. |
| No proprietary RIF implementation constants or caching layers are contained here. |
| """ |
| with open(os.path.join(run_root, "README.txt"), "w") as f: |
| f.write(readme_content) |
| |
| |
| source_dir = os.path.join(run_root, "source") |
| |
| orig_name = source_metadata.get("filename", "pasted_text.txt") |
| with open(os.path.join(source_dir, f"original-upload_{orig_name}"), "w", encoding="utf-8") as f: |
| f.write(source_metadata.get("original_text", "")) |
| |
| with open(os.path.join(source_dir, "extracted-source.txt"), "w", encoding="utf-8") as f: |
| f.write(source_metadata.get("extracted_text", "")) |
| |
| with open(os.path.join(source_dir, "normalized-source.txt"), "w", encoding="utf-8") as f: |
| f.write(source_metadata.get("normalized_text", "")) |
| |
| |
| if source_metadata.get("synthetic_records"): |
| with open(os.path.join(source_dir, "generated-records.jsonl"), "w") as f: |
| for r in source_metadata["synthetic_records"]: |
| f.write(json.dumps(r) + "\n") |
| |
| source_manifest = { |
| "filename": orig_name, |
| "char_count": len(source_metadata.get("original_text", "")), |
| "sha256": hashlib.sha256(source_metadata.get("original_text", "").encode("utf-8")).hexdigest(), |
| "source_style": source_metadata.get("style", "custom"), |
| "generation_parameters": source_metadata.get("generation_params", {}) |
| } |
| with open(os.path.join(source_dir, "source-manifest.json"), "w") as f: |
| json.dump(source_manifest, f, indent=2) |
| |
| |
| quest_dir = os.path.join(run_root, "questions") |
| with open(os.path.join(quest_dir, "questions.jsonl"), "w") as f: |
| for q in questions: |
| |
| q_stripped = q.copy() |
| q_stripped.pop("expected_answer", None) |
| q_stripped.pop("acceptable_answers", None) |
| f.write(json.dumps(q_stripped) + "\n") |
| |
| with open(os.path.join(quest_dir, "answer-key.jsonl"), "w") as f: |
| for q in questions: |
| f.write(json.dumps({ |
| "question_id": q["question_id"], |
| "expected_answer": q.get("expected_answer", ""), |
| "acceptable_answers": q.get("acceptable_answers", []), |
| "supporting_fact_ids": q.get("supporting_fact_ids", []) |
| }) + "\n") |
| |
| |
| mp_dir = os.path.join(run_root, "model-pairs") |
| with open(os.path.join(mp_dir, "model-pair-registry.json"), "w") as f: |
| json.dump(model_pairs_meta, f, indent=2) |
| with open(os.path.join(mp_dir, "plain-api-models.json"), "w") as f: |
| json.dump(plain_models_list, f, indent=2) |
| with open(os.path.join(mp_dir, "rif-api-models.json"), "w") as f: |
| json.dump(rif_models_list, f, indent=2) |
| |
| |
| req_dir = os.path.join(run_root, "requests") |
| resp_dir = os.path.join(run_root, "responses") |
| |
| |
| for log in raw_logs: |
| model_name = log.get("model_pair_id", "default_model") |
| system_type = log.get("system", "plain") |
| |
| req_file = os.path.join(req_dir, f"{model_name}-{system_type}-requests.jsonl") |
| resp_file = os.path.join(resp_dir, f"{model_name}-{system_type}-responses.jsonl") |
| |
| with open(req_file, "a") as f_req, open(resp_file, "a") as f_resp: |
| f_req.write(json.dumps(log.get("raw_request", {})) + "\n") |
| f_resp.write(json.dumps(log.get("raw_response", {})) + "\n") |
| |
| |
| res_dir = os.path.join(run_root, "results") |
| |
| |
| csv_headers = [ |
| "question_id", "question", "expected", "model_pair", |
| "plain_answer", "plain_em", "plain_f1", "plain_latency_ms", "plain_prompt_tokens", "plain_truncated", |
| "rif_answer", "rif_em", "rif_f1", "rif_latency_ms", "rif_prompt_tokens", "rif_truncated", |
| "source_position", "first_called" |
| ] |
| |
| per_q_results = results_summary.get("per_question", []) |
| csv_path = os.path.join(res_dir, "per-question-results.csv") |
| with open(csv_path, "w", newline="") as f: |
| writer = csv.writer(f) |
| writer.writerow(csv_headers) |
| for item in per_q_results: |
| writer.writerow([ |
| item.get("question_id"), |
| item.get("question"), |
| item.get("expected"), |
| item.get("model_pair"), |
| item.get("plain_answer"), |
| item.get("plain_em"), |
| item.get("plain_f1"), |
| item.get("plain_latency_ms"), |
| item.get("plain_prompt_tokens"), |
| item.get("plain_truncated"), |
| item.get("rif_answer"), |
| item.get("rif_em"), |
| item.get("rif_f1"), |
| item.get("rif_latency_ms"), |
| item.get("rif_prompt_tokens"), |
| item.get("rif_truncated"), |
| item.get("source_position"), |
| item.get("first_called") |
| ]) |
| |
| |
| with open(os.path.join(res_dir, "overall-summary.json"), "w") as f: |
| json.dump(results_summary.get("overall", {}), f, indent=2) |
| |
| |
| cfg_dir = os.path.join(run_root, "configuration") |
| with open(os.path.join(cfg_dir, "benchmark-config.json"), "w") as f: |
| json.dump(results_summary.get("config", {}), f, indent=2) |
| with open(os.path.join(cfg_dir, "execution-order.json"), "w") as f: |
| json.dump(results_summary.get("execution_order", []), f, indent=2) |
| with open(os.path.join(cfg_dir, "hardware-comparison.json"), "w") as f: |
| json.dump(results_summary.get("hardware_comparison", {}), f, indent=2) |
| |
| |
| zip_path = os.path.join(config.RUNS_DIR, f"{run_root_name}.zip") |
| |
| |
| with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED) as zipf: |
| for root, dirs, files in os.walk(run_root): |
| for file in files: |
| file_abs = os.path.join(root, file) |
| |
| if "sha256-checksums.txt" in file: |
| continue |
| arcname = os.path.relpath(file_abs, run_root) |
| zipf.write(file_abs, os.path.join(run_root_name, arcname)) |
| |
| |
| checksum_lines = [] |
| |
| zip_hash = calculate_sha256(zip_path) |
| checksum_lines.append(f"{zip_hash} {run_root_name}.zip\n") |
| |
| |
| for root, dirs, files in os.walk(run_root): |
| for file in files: |
| file_abs = os.path.join(root, file) |
| if "sha256-checksums.txt" in file: |
| continue |
| f_hash = calculate_sha256(file_abs) |
| rel_path = os.path.relpath(file_abs, run_root) |
| checksum_lines.append(f"{f_hash} {rel_path}\n") |
| |
| checksum_file_path = os.path.join(run_root, "integrity", "sha256-checksums.txt") |
| with open(checksum_file_path, "w") as f: |
| f.writelines(checksum_lines) |
| |
| |
| with zipfile.ZipFile(zip_path, "a") as zipf: |
| zipf.write(checksum_file_path, os.path.join(run_root_name, "integrity", "sha256-checksums.txt")) |
| |
| return zip_path |
|
|