| from __future__ import annotations |
|
|
| import json |
| from pathlib import Path |
|
|
| from .backends.image import DemoImageBackend |
| from .backends.text import DemoTextBackend |
| from .orchestrator import ForestOrchestrator |
| from .trace import TraceRecorder |
|
|
| SCENARIOS = ( |
| ("work", "starting a new design job and worried about belonging"), |
| ("study", "preparing for a difficult exam after one disappointing result"), |
| ("creative", "returning to a novel after months of feeling stuck"), |
| ) |
|
|
|
|
| def build_trace_dataset(output: Path) -> int: |
| output.unlink(missing_ok=True) |
| output.parent.mkdir(parents=True, exist_ok=True) |
| row_count = 0 |
| for index, (category, situation) in enumerate(SCENARIOS): |
| trace_id = f"forest-{index + 1:02d}" |
| temporary = output.with_name(f".{trace_id}.jsonl") |
| temporary.unlink(missing_ok=True) |
| orchestrator = ForestOrchestrator( |
| text_backend=DemoTextBackend(), |
| image_backend=DemoImageBackend(width=128, height=96), |
| trace_recorder=TraceRecorder(temporary), |
| ) |
| list(orchestrator.generate("Sample visitor", situation, seed=3407 + index * 10)) |
| records = [ |
| { |
| "stage": "scenario", |
| "scenario_category": category, |
| "public_synthetic_input": situation, |
| }, |
| *[ |
| json.loads(line) |
| for line in temporary.read_text(encoding="utf-8").splitlines() |
| ], |
| ] |
| with output.open("a", encoding="utf-8") as trace_file: |
| for sequence, record in enumerate(records): |
| row = { |
| "trace_id": trace_id, |
| "sequence": sequence, |
| "stage": record["stage"], |
| "model": record.get("model", ""), |
| "payload_json": json.dumps(record, ensure_ascii=True, sort_keys=True), |
| } |
| trace_file.write(json.dumps(row, ensure_ascii=True) + "\n") |
| row_count += 1 |
| temporary.unlink() |
| return row_count |
|
|