{"data":{"kind":"file","path":"README.md","version_id":"wmaxrwwz94x8izit2obv3wud","entry":{"name":"README.md","path":"README.md","is_directory":false,"size":4868,"modified_at":"2026-07-12T23:14:38.750000","content_hash":"922ab826dad40387ce14577458609661cdb94b1b74f2ccf5115e69f429cfdafa"},"entries":[],"content":"# PDF Form Fill\n\nA public-ready, procedural agentic RL environment for text-only models. The model receives plain-text profile data and uses spatial tools to fill a generated one-page PDF form.\n\nThe model never sees an image. `inspect_page` returns shuffled label text and empty regions with normalized bounding boxes, but does not reveal which label belongs to which region. The model must infer the spatial association, write the exact value, choose a readable font size that fits, and explicitly submit with `done`.\n\nThe system prompt explicitly tells the model the configured tool-call budget, including `done`.\n\n## Task\n\n- **Type:** stateful multi-turn tool use\n- **Input:** a plain-text profile and a procedurally generated PDF form\n- **Tools:** `inspect_page`, `write_text`, `clear_region`, `inspect_regions`, `done`\n- **Primary metric:** every expected value is in its correct region, every value fits, and `done` was called\n- **No OCR dependency:** the generator exposes its own text and rectangle geometry; verification uses hidden field manifests and deterministic font metrics\n\nEach seed deterministically generates:\n\n- A profile sampling a configurable 4–18 values from an 18-field pool\n- A dense mixed-layout PDF form selected from six coordinate templates\n- Shuffled label and region observations\n- Repeated generic labels such as `Name`, `Email`, and `Phone`\n- Randomized section and field order\n- A difficulty-scaled set of shuffled, non-overlapping decoy regions\n- Variable region widths, including values that require font reduction\n- A hidden label-to-region answer manifest\n\n`curriculum_tier=0` selects a calibrated introductory task with four fields\n(applicant name, manager name, date of birth, and employee ID), exactly two\ndecoys, and regions that fit their expected values at 12pt. The reward and tool\nsemantics are identical to the full environment.\n\n`curriculum_tier=1` keeps the same field composition and decoys but makes\nexactly one field require 9pt; `curriculum_tier=2` makes exactly two fields\nrequire 9pt. These add localized font-repair decisions without increasing the\nnumber of fields.\n\nTrain and evaluation use disjoint seed ranges. Evaluation starts at seed `10000`, which prevents exact form-instance memorization.\n\n## Reward\n\nThe reward is intentionally minimal. Every field is binary. A field succeeds only when:\n\n- It contains the exact expected value\n- It is the correct region\n- It uses left alignment\n- It uses at least `min(10, largest_fitting_size)`\n- It does not overflow\n\nThis accepts normal readable sizes from 10–12 while requiring smaller text only when the field cannot fit 10pt. It prevents the trivial 6pt-everywhere policy without demanding a mathematically maximal size.\n\nThe only weighted training reward is `field_success`: the fraction of sampled fields passing their binary checks. `done_called` is logged with weight zero so termination behavior can be studied without shaping it. `fields_succeeded` reports raw counts, and zero-weight binary `task_success` requires all sampled fields plus `done()`. There are no efficiency bonuses or partially weighted formatting scores.\n\n## Local development\n\n```bash\nuv sync\nuv run python -m unittest -v test_pdf_form_fill.py\nuv run python pdf_form_fill.py --seed 10000 --output-dir artifacts/demo\nprime eval run pdf-form-fill -n 5 -r 1\n```\n\nThe visualization command writes blank and gold-filled PDFs and PNG previews, plus the hidden manifest used for development.\nSaved evaluation traces can be reconstructed into model-filled PDFs and per-field diagnostics with:\n\n```bash\nuv run python analyze_results.py path/to/results.jsonl --output-dir artifacts/eval\n```\n\n## Environment arguments\n\n| Argument | Default | Description |\n| --- | ---: | --- |\n| `train_examples` | `64` | Number of deterministic training seeds |\n| `eval_examples` | `24` | Number of held-out evaluation seeds |\n| `min_fields` | `12` | Minimum fields sampled per form; supported range starts at 4 |\n| `max_fields` | `18` | Maximum fields sampled per form; supported range ends at 18 |\n| `curriculum_tier` | `None` | Set to `0`, `1`, or `2` for calibrated four-field curriculum tasks |\n| `max_turns` | `51` | Allows execution of a 50th and final tool call |\n| `max_tool_calls` | `50` | Hard tool-call budget, including `done` |\n\n## Publishing\n\nThe package contains no private data, secrets, external APIs, or model-based judge. Before publishing, update the version in `pyproject.toml`, then run:\n\n```bash\nprime env push --path .\n```\n\n## Current scope\n\nVersion 0.7 intentionally supports only single-line text fields. It adds explicit introductory curriculum tiers with zero, one, or two font-repair decisions while retaining section-aware spatial association, decoy avoidance, recovery, and termination. Checkboxes, multiline wrapping, and segmented fields belong in later difficulty levels.\n","encoding":"utf-8","truncated":false,"total_bytes":4868},"status":null}