File size: 1,669 Bytes
a3c1ec2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import io
import json
import zipfile
import pandas as pd
from typing import Tuple
from .sim import World
from .kpi import compute_kpis

def export_run(w: World) -> Tuple[bytes, str]:
    """
    Returns (zip_bytes, filename)
    Contents:
      - events.jsonl
      - metrics.csv
      - run_summary.json
    """
    # events
    events_jsonl = w.events.to_jsonl().encode("utf-8")

    # metrics (single-row snapshot; you can also store per-tick KPI series later)
    kpi = compute_kpis(w)
    df = pd.DataFrame([kpi])
    metrics_csv = df.to_csv(index=False).encode("utf-8")

    # summary
    summary = {
        "run_id": w.run_id,
        "seed": w.seed,
        "tick": w.step,
        "minutes_per_tick": w.config.minutes_per_tick,
        "ledger": {
            "spend_usd": w.ledger.spend_usd,
            "llm_calls": w.ledger.llm_calls,
            "tool_calls": w.ledger.tool_calls,
            "tokens_prompt": w.ledger.tokens_prompt,
            "tokens_completion": w.ledger.tokens_completion,
        },
        "kpi": kpi,
        "alerts": w.ledger.alerts[-10:],
        "tasks_total": len(w.tasks.tasks),
        "tasks_done": len(w.tasks.done_tasks()),
        "tasks_overdue": len(w.tasks.overdue_tasks(w.step)),
    }
    summary_json = json.dumps(summary, indent=2).encode("utf-8")

    # zip
    buf = io.BytesIO()
    with zipfile.ZipFile(buf, mode="w", compression=zipfile.ZIP_DEFLATED) as z:
        z.writestr("events.jsonl", events_jsonl)
        z.writestr("metrics.csv", metrics_csv)
        z.writestr("run_summary.json", summary_json)

    buf.seek(0)
    fname = f"zen_orchestrator_export__{w.run_id}.zip"
    return buf.read(), fname