{"data":{"kind":"file","path":"README.md","version_id":"pai3bems2ewhmy3nf91wq75y","entry":{"name":"README.md","path":"README.md","is_directory":false,"size":3669,"modified_at":"2026-02-27T23:42:30.656000","content_hash":"438e882bc356822c0b644e163c59eff35f0089407360a831fe5cf81e627ed011"},"entries":[],"content":"# roi-calculator\n\nSingle-turn **RL environment** for **Return on Investment (ROI)** analysis. This package is **only the environment** (dataset, prompt builder, rubric); training and evaluation are run by Prime Intellect (`prime eval run`, `prime rl run`) or other trainers.\n\n**Environment criteria:** **Dataset** — bundled `roi_dataset.json` (tasks with prompt + ground truth); train/eval split via `num_eval_examples`. **Harness** — single-turn chat (one prompt → one response; `vf.SingleTurnEnv`). **Rubric** — binary (1.0/0.0) or continuous (0–1) reward; optional state columns `binary_correct`, `reasoning_points`.\n\nROI measures the percentage return on an investment relative to its cost. The task is:\n\n1. **Calculating ROI** from initial investment and net profit\n2. **Annualizing ROI** for multi-year investments\n3. **Deciding INVEST or PASS** based on whether annualized ROI exceeds the hurdle rate\n4. **Explaining reasoning** in structured JSON\n\n## Reward (0–1)\n\n**Default (Prime-aligned): binary reward.**\n- Rubric returns **1.0** only when both ROI and annualized ROI are within a relative tolerance (default **5%**) of the true values *and* the decision (INVEST/PASS) is correct; otherwise **0.0**. Reasoning is **not** part of the reward.\n\n**Optional: continuous reward** (`use_binary_reward=False`).\n- **ROI accuracy** (35% of raw): exponential decay with relative error\n- **Annualized ROI accuracy** (35% of raw): exponential decay with relative error\n- **Correct decision** (20% of raw): INVEST/PASS matches expected\n- **Reasoning quality** (10% of raw): keyword heuristic\n\nRaw score 0–100 is normalized to 0–1 for the Verifiers rubric.\n\n## Dataset\n\n**~2,018 problems** in total (bundled as `roi_dataset.json`): **~99% synthetic**, plus curated real and inspired problems. Each problem has project name, initial investment, net profit, holding period, and hurdle rate.\n\n## Prompt & answer schema\n\n- **User prompt**: Project name, initial investment, net profit, holding period, hurdle rate, and instructions to return JSON.\n- **Expected answer**: Valid JSON with `roi_pct` (number), `annualized_roi_pct` (number), `decision` (\"INVEST\" or \"PASS\"), and `reasoning` (string). Markdown code blocks and `<think>...</think>` blocks are supported.\n\n## Quickstart\n\n```bash\nprime env install roi-calculator -p ./environments\nprime eval run roi-calculator -m google/gemini-2.5-flash -n 5 -r 1\n```\n\n```python\nfrom roi_calculator import load_environment\n\nenv = load_environment()\n```\n\n## Environment Arguments\n\n| Arg | Type | Default | Description |\n| --- | ---- | ------- | ----------- |\n| `dataset_path` | str or Path | `None` | Path to `roi_dataset.json`; if `None`, uses bundled dataset |\n| `num_examples` | int | `-1` | Max number of problems |\n| `num_train_examples` | int | `-1` | Max training examples |\n| `num_eval_examples` | int | `-1` | If > 0, hold out this many for eval |\n| `eval_seed` | int | `42` | Seed for train/eval split |\n| `use_binary_reward` | bool | `True` | If `True`, rubric returns 1.0 or 0.0. If `False`, continuous 0–1. |\n| `roi_tolerance` | float | `0.05` | Relative tolerance for \"correct\" ROI in binary mode (5%). |\n\n## Requirements\n\n- Python ≥3.10\n- `verifiers>=0.1.8`\n- `datasets>=2.14.0`\n\n## Changelog\n\n#### v0.1.0\n- Initial release: SingleTurnEnv with bundled ROI dataset, composite reward (ROI accuracy + annualized accuracy + decision + reasoning).\n- Binary reward (default): Rubric returns 1.0 or 0.0 (Prime Intellect–aligned).\n\n## Links\n\n- [Prime Intellect Environments](https://docs.primeintellect.ai/tutorials-environments/environments)\n- [Verifiers](https://github.com/PrimeIntellect-ai/verifiers)\n","encoding":"utf-8","truncated":false,"total_bytes":3669},"status":null}