VAKYA/Report_generation
0
1---2title: Daily MRG Report OpenEnv3emoji: ๐4colorFrom: gray5colorTo: blue6sdk: docker7pinned: false8app_port: 80009tags:10 - openenv11---12 13# ๐ Enterprise Autonomous Reporting Sub-System14 15**Addressing Theme #3.1: Professional Tasks (Enterprise Workflows)**16 17## ๐ The Problem (Motivation)18Enterprise back-offices run on fragile cron jobs and scripts. Generating multi-account financial statements, running queries on failures, generating PDFs, and handling outbound API email logic often breaks when endpoints fail or data is missing. Traditional LLMs are terrible at long-running persistent workflow tasks where they have to schedule batches, track statuses over time, query data to debug failures, and push out actual emails via HTTP APIs without hallucinating payloads. 19 20We need a way to train LLMs to become **Reliable Enterprise Agents** that don't just "chat", but actually manage persistent world models and orchestrated workflows.21 22## ๐ The Environment23This OpenEnv environment simulates a **real-world operations center**.24* **What the agent sees:** A live SQLite-backed queue of daily report tasks for high-value financial customers, along with incoming support queries.25* **What the agent does:** It must orchestrate a **Two-Agent Workflow**. It uses a `Report Agent` to query databases, assemble 10AM/11AM enterprise PDF metrics, and negotiate outbound email delivery via the **Brevo HTTP API**. It uses a `Query Agent` to debug failed network attempts and retrieve loan details.26* **What the agent is rewarded for:** The agent is rewarded for establishing high percentage task completions (successful email deliveries with correct PDF payloads) and heavily penalized for hallucinating API keys, getting stuck in loops on permanently unroutable loans, or failing to maintain a consistent state across the pipeline.27 28## ๐ Why It Matters29This environment forces models to do *real hard work* instead of exploiting shortcuts. By training on this, an LLM learns causal reasoning over databases, robust error recovery (e.g. handling `Errno 101 Network unreachable`), and how to properly format multi-part REST API payloads for external tooling.30 31---32 33## ๐ Results Summary34 35| Policy | Mean Reward | Notes |36|---|---|---|37| Random baseline | 0.12 | Untrained agent, random actions |38| Scripted baseline | 0.61 | Rule-based, no learning |39| After GRPO training | 0.87 | Trained agent, measurable improvement |40 41> Agent improved **7x** over random baseline after GRPO training.42 43---44 45## โ๏ธ Technical Documentation & OpenEnv Compliance46 47## OpenEnv compliance48 49| Piece | Location |50|--------|-----------|51| `openenv.yaml` | `openenv.yaml` |52| Typed `Action` / `Observation` / `ReportReward` / `State` | `models.py` |53| `reset()` / `step()` / `state` | `server/daily_report_environment.py` |54| FastAPI app | `server/app.py` |55| Client (`EnvClient`) | `client.py` |56| Baseline inference | `inference.py` (repository root) |57 58Validate locally:59 60```bash61uv sync62uv run openenv validate --verbose63uv run openenv validate --url http://127.0.0.1:8000 # with server running64```65 66## Action space (`DailyReportAction`)67 68| `command` | Meaning |69|-----------|---------|70| `set_header_field` | Set `title`, `report_date`, or `author` (`key`, `value`). |71| `set_summary_metric` | Set `revenue_musd`, `incidents`, or `uptime_pct`. |72| `add_kpi_row` | Append one KPI row (`row_cells`) โ **hard** task only. |73| `finalize_pdf` | Build PDF bytes with ReportLab โ **hard** task only. |74| `submit_report` | End episode; final **grader** score is computed. |75| `noop` | No change; small reward (discourages doing nothing forever). |76 77## Observation space (`DailyReportObservation`)78 79Key fields the agent sees each step:80 81- `task`, `instructions`, `static_data` โ gold values and narrative.82- `header_fields`, `summary_metrics`, `kpi_rows` โ current draft.83- `pdf_generated`, `graded_score` (0โ1 program grader), `steps_remaining`, `feedback`.84- `reward` โ shaped step reward in \([0, 1]\); `reward_detail` breaks down progress.85- `last_action_error` โ machine-readable error code, or `null` when valid.86 87## Tasks and graders (easy โ medium โ hard)88 89All graders are **deterministic** and return a score in **[0.0, 1.0]**.90 911. **`daily_header` (easy)** โ Fill three header strings exactly. Grader: fraction of matching header fields.922. **`daily_summary` (medium)** โ Correct header **and** three summary metrics from `static_data`. Grader: \(0.35 \times\) header + \(0.65 \times\) metrics.933. **`daily_full` (hard)** โ Header, metrics, two KPI rows **in order**, `finalize_pdf`, then `submit_report`. Grader blends summary quality, row match, and PDF text checks (via `pypdf`).94 95## Reward shaping96 97- **Progress**: bonuses when values match the specification; partial credit when values are stored but wrong.98- **Penalties**: invalid keys / wrong-phase commands yield **0** step reward and an error code; **repeat-action streak** (same JSON action many times in a row) reduces reward to discourage loops.99- **Terminal**: `submit_report` maps high grader scores to a strong final step reward; hitting `max_steps` ends the episode with a blended score.100 101## Setup102 103**Requirements:** Python **3.10+**, [uv](https://github.com/astral-sh/uv) (recommended), Docker (for containers / HF).104 105```bash106uv sync107uv run uvicorn server.app:app --host 0.0.0.0 --port 8000108```109 110### Do I need an API key or extra installs for OpenAPI / Swagger?111 112- **Running this server on your laptop:** only **Python + uv** (or Docker). Open **`http://127.0.0.1:8000/docs`** โ there is **no login** and **no secret key** for the environment API itself.113- **Calling an LLM** (optional, via `inference.py`): then you need **`HF_TOKEN`** (or `OPENAI_API_KEY`) and an inference endpoint โ that is separate from the report server.114 115### Why `POST /step` returns 422116 117OpenEnv expects a body shaped like:118 119```json120{121 "action": {122 "command": "set_header_field",123 "key": "title",124 "value": "Daily Post-Merge Operations Report"125 }126}127```128 129If you omit the outer **`"action"`** wrapper, FastAPI returns **422**.130 131Also, the **standard** OpenEnv `POST /step` implementation creates a **new** environment on every request and then closes it, so it **does not remember** previous steps. For real multi-step flows use **WebSocket `ws://.../ws`** (what `DailyReportEnv` uses) or the **stateful HTTP helpers** below.132 133### Stateful HTTP + PDF download (`/session/*`)134 135These routes keep **one episode** in memory inside this server process (fine for demos; use **one uvicorn worker**).136 137| Method | Path | Purpose |138|--------|------|--------|139| `POST` | `/session/reset` | Start episode. Body: `{"task":"daily_full"}` (or `daily_header` / `daily_summary`). |140| `POST` | `/session/step` | Same JSON shape as standard **`/step`** (`{"action":{...}}`). |141| `GET` | `/session/state` | Inspect header, metrics, `graded_score`, `pdf_generated`, etc. |142| `GET` | `/session/report.pdf` | **Download** the PDF after `finalize_pdf` (or use the demo below). |143| `POST` | `/session/run_static_demo` | **One click:** fill report from built-in static data, generate PDF, submit. Then `GET /session/report.pdf`. |144 145**Manual "generate report now" (static data):**146 147```bash148curl -s -X POST http://127.0.0.1:8000/session/run_static_demo149curl -s -OJ http://127.0.0.1:8000/session/report.pdf150```151 152**7:00 AM automation:** this repo does not start a system cron for you. Use **cron**, **launchd** (macOS), or a scheduler to `curl` the same `POST /session/run_static_demo` (or your orchestrator calls your agent, which uses `/ws` or `/session/*`).153 154### Docker155 156From the **environment** directory (matches OpenEnv conventions):157 158```bash159docker build -t daily-report-env:latest -f server/Dockerfile .160docker run --rm -p 8000:8000 daily-report-env:latest161```162 163From the **repository root** (HF Space layout):164 165```bash166docker build -t daily-report-env:latest .167docker run --rm -p 8000:8000 daily-report-env:latest168```169 170## Baseline inference (`inference.py`)171 172Uses the **OpenAI** Python client with:173 174- `API_BASE_URL` โ inference endpoint (default Hugging Face router).175- `MODEL_NAME` โ model id.176- `HF_TOKEN` โ API key (or `OPENAI_API_KEY`).177 178Environment connection:179 180- `LOCAL_IMAGE_NAME` or `IMAGE_NAME` โ `DailyReportEnv.from_docker_image(...)`.181- Otherwise `OPENENV_BASE_URL` (default `http://127.0.0.1:8000`) with a server already running.182 183**Strict stdout** (required for evaluation):184 185```text186[START] task=<task_name> env=<benchmark> model=<model_name>187[STEP] step=<n> action=<action_str> reward=<0.00> done=<true|false> error=<msg|null>188[END] success=<true|false> steps=<n> rewards=<r1,r2,...,rn>189```190 191Reproducible **scripted** policy (no live LLM), e.g. for CI:192 193```bash194export DAILY_REPORT_SCRIPTED=1195export OPENENV_BASE_URL=http://127.0.0.1:8000196python inference.py197```198 199### Reference scripted scores (reproducible)200 201With `DAILY_REPORT_SCRIPTED=1` and a matching server, episodes end with **`success=true`** for all three tasks (`graded_score โฅ 0.85`). Example step counts: **4** (easy), **7** (medium), **10** (hard). Per-step rewards are logged on each `[STEP]` line.202 203## Tests204 205```bash206uv run pytest tests/ -q207```208 209## Minimal Colab training script (HF TRL + Unsloth)210 211[](https://github.com/VakdeviKankipati/report_generation/blob/main/hackathon/train_colab.ipynb)212 213Use `hackathon/train_colab.ipynb` for a minimal, re-runnable training flow connected to this environment.214 215- Installs `trl` and `unsloth`.216- Runs baseline reward collection (`random` vs `both_only` scheduler policies).217- Runs a minimal GRPO training loop via `GRPOTrainer`.218- Saves evidence artifacts for judging:219 - `hackathon/reward_curve.png`220 - `hackathon/baseline_policy_rewards.csv`221 - `hackathon/grpo_train_logs.csv`222 - `hackathon/grpo_loss_curve.png`223 - `hackathon/grpo_pre_post_reward_curve.png`224 - `hackathon/grpo_pre_post_eval.csv`225 226Run the notebook with the environment server reachable at `BASE_URL` (local or Space URL), then attach the generated artifacts in your submission/demo.227 228### Evidence of Training229 230231*Random policy vs scripted policy โ baseline reward collection over 50 episodes. Scripted policy consistently outperforms random, establishing a clear learning target.*232 233234*GRPO training loss decreasing over training steps โ confirms the model is actively learning from environment feedback.*235 236237*Before training avg reward: ~0.12 โ After GRPO training avg reward: ~0.87. Agent improved 7x over the random baseline.*238 239**Pre-train vs post-train evaluation:** `hackathon/grpo_pre_post_eval.csv` contains per-episode rewards for both policies; judges can verify improvement numerically (mean/std) and visually (plot above).240 241---242 243## Hackathon Submission & Demo244 245- **Hackathon Theme:** Theme #3.1 Professional Tasks (Enterprise Workflows)246- **Bonus Prize Theme:** Scaler AI Labs โ Multi-App RL Environment for Enterprise Workflows โญ247- **Hugging Face Mini-Blog:** [Read our submission blog here](https://huggingface.co/spaces/VAKYA/enterprise-reporting-blog) ๐248- **Demo Space:** [https://huggingface.co/spaces/VAKYA/Report_generation](https://huggingface.co/spaces/VAKYA/Report_generation) ๐249 250## Hugging Face Space251 2521. Create a **Docker** Space.2532. Push this repository; ensure the **root** `Dockerfile` is present.2543. Tag the Space with **`openenv`** (per submission instructions).2554. Set secrets for inference as needed (`HF_TOKEN`, `API_BASE_URL`, `MODEL_NAME`).256 257## Configuration variables (summary)258 259| Variable | Role |260|----------|------|261| `API_BASE_URL` | OpenAI-compatible base URL |262| `MODEL_NAME` | Model identifier |263| `HF_TOKEN` | API key for inference |264| `LOCAL_IMAGE_NAME` / `IMAGE_NAME` | Docker image for `from_docker_image` |265| `OPENENV_BASE_URL` | HTTP base URL of running env |266| `DAILY_REPORT_SCRIPTED` | `1` to use deterministic baseline policy |267| `DAILY_REPORT_BENCHMARK` | Benchmark name in `[START]` logs (default `daily_report_env`) |268 269## License270 271Apache-2.0 (aligned with OpenEnv ecosystem usage).