Metadata-Version: 2.4
Name: vbagent
Version: 0.3.14
Summary: Physics question processing library and CLI - classification, LaTeX extraction, variant generation
Author: vaibhavblayer
Author-email: vaibhavblayer@gmail.com
Requires-Python: >=3.12
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Provides-Extra: all
Provides-Extra: dev
Provides-Extra: docs
Requires-Dist: click (>=8.1.0)
Requires-Dist: click (>=8.1.0) ; extra == "all"
Requires-Dist: hypothesis (>=6.0.0) ; extra == "dev"
Requires-Dist: jsonschema (>=4.0.0)
Requires-Dist: jsonschema (>=4.0.0) ; extra == "all"
Requires-Dist: mcp (>=1.23.1,<2.0.0)
Requires-Dist: mcp (>=1.23.1,<2.0.0) ; extra == "all"
Requires-Dist: mkdocs-material (>=9.0.0) ; extra == "docs"
Requires-Dist: mkdocstrings[python] (>=1.0.0) ; extra == "docs"
Requires-Dist: openai-agents (>=0.18.2,<0.19)
Requires-Dist: openai-agents (>=0.18.2,<0.19) ; extra == "all"
Requires-Dist: prompt-toolkit (>=3.0.53,<4.0.0)
Requires-Dist: prompt-toolkit (>=3.0.53,<4.0.0) ; extra == "all"
Requires-Dist: pydantic (>=2.0.0)
Requires-Dist: pydantic (>=2.0.0) ; extra == "all"
Requires-Dist: pymdown-extensions (>=10.0.0) ; extra == "docs"
Requires-Dist: pytest (>=8.0.0) ; extra == "dev"
Requires-Dist: pytest-asyncio (>=1.0.0) ; extra == "dev"
Requires-Dist: pyyaml (>=6.0.0)
Requires-Dist: pyyaml (>=6.0.0) ; extra == "all"
Requires-Dist: rich (>=13.0.0)
Requires-Dist: rich (>=13.0.0) ; extra == "all"
Description-Content-Type: text/markdown

# VBAgent

A multi-agent library and CLI for processing physics, chemistry, and mathematics question images. Supports classification, LaTeX extraction, TikZ diagram generation, solution generation, variant creation, paper orchestration, and LaTeX compilation.

📚 **[Documentation](https://vaibhavblayer.github.io/vbagent/)** | 🐛 **[Issues](https://github.com/vaibhavblayer/vbagent/issues)** | 💬 **[Discussions](https://github.com/vaibhavblayer/vbagent/discussions)**

## Installation

```bash
pip install -e ".[dev]"
```

## Requirements

- Python 3.12+
- API key for your provider (set as env variable)
- For compilation: `pdflatex` (TeX Live or MacTeX)

### Supported Providers

| Provider | Env Variable | Models |
|----------|-------------|--------|
| OpenAI | `OPENAI_API_KEY` | gpt-5.6-sol, gpt-5.6-terra, gpt-5.6-luna, gpt-5.5, gpt-5.4, gpt-5.4-mini |
| xAI | `XAI_API_KEY` | grok-4, grok-4-1-fast-reasoning, grok-3, grok-3-mini |
| Google | `GOOGLE_API_KEY` | gemini-2.5-pro, gemini-2.5-flash, gemini-3-flash-preview |

### Default Models (OpenAI)

| Role | Model |
|------|-------|
| Classification and routine checking | `gpt-5.6-luna` |
| Scanning | `gpt-5.6-luna` |
| Conversion | `gpt-5.6-terra` |
| Solution and all diagram generation | `gpt-5.6-sol` |

Switch provider or model easily:
```bash
vbagent config provider xai              # Switch to xAI
vbagent config provider google           # Switch to Google
vbagent config provider openai           # Back to OpenAI
vbagent config set solution -m gpt-5.6-sol    # Override solution model
vbagent config set tikz -m gpt-5.6-sol        # Override tikz model
vbagent config set default -m gpt-5.6-luna    # Change global default
```

Official GPT-5.6 calls automatically reuse stable agent prefixes through
explicit prompt caching. Multi-key rotation is cache-aware: declare the same
cache domain only for profiles in the same OpenAI organization and processing
region; undeclared profiles remain safely isolated.

```bash
vbagent keys add --name project-a --api-key "$OPENAI_PROJECT_A_KEY" \
  --cache-domain openai-org-main:global
vbagent keys list
```

See [configuration](docs/getting-started/configuration.md#openai-prompt-caching-and-profile-rotation)
for sharding, failover, and cache metric semantics.

## CLI Usage

### Quick Start

```bash
vbagent init                              # Initialize workspace config
vbagent scan -i question.png              # Save problem-only LaTeX under agentic/
vbagent scan -i problem_1.png --from 1 --to 12  # Same default workspace
vbagent classify -i question.png          # Classify question type
vbagent classify -i problem_1.png --item 5 # Classify one numbered image
vbagent tikz -i diagram.png -o diag.tex   # Generate TikZ
vbagent run -i question.png               # Full pipeline
vbagent run -i problem_1.png --from 1 --to 50 --parallel 3  # Image batch
vbagent run -i problems.tex --from 1 --to 50 --parallel 3  # TeX item batch
vbagent solve -t scanned.tex -o solved.tex # Generate solutions from scanned TeX
vbagent solve -t scanned-problems/ -o solved-problems/ --no-diagram
vbagent solve -t scanned-problems/ --in-place --no-diagram --from 1 --to 5 --exclude 4,3
```

When a crop contains only a bare expression and the missing task is known from
the exercise heading, use the same workspace one stage at a time:

```bash
vbagent scan -i images/problem_1.png --from 1 --to 5
vbagent check edit --from 1 --to 5 \
  --instruction 'Prefix each item with "Find the period of the function"'
vbagent solve --from 1 --to 5
vbagent compile --all-packages --from 1 --to 5
```

`scan` writes `agentic/scans/problem_N.tex` and matching classification
sidecars. `check edit` uses that directory by default, displays each diff for
approval, and protects existing mathematics. `solve` also uses that workspace
by default, recovers subject and type from the sidecars, and writes solutions
back into the selected scan files. `run` remains the one-command form.

Commands that select numbered problems share one 1-based, inclusive contract:
use `--from N --to M` for a range or `--item N` for exactly one item. Do not
combine `--item` with `--from` or `--to`. A numbered input such as
`problem_1.png` supplies the filename pattern for image ranges.

### Commands

| Section | Command | Description |
|---------|---------|-------------|
| Core | `run` | Full pipeline: classify → scan → tikz → solve |
| Core | `scan` | Extract problem-only LaTeX into the shared workspace |
| Core | `solve` | Generate solutions from an existing TeX project |
| Core | `classify` | Classify question type |
| Core | `batch` | Batch process multiple images with resume |
| Author | `author` | Plan, run, resume, review, and audit syllabus-driven creation |
| Generate | `tikz` | Generate TikZ/PGF diagrams |
| Generate | `fbd` | Free body diagram generation |
| Generate | `idea` | Extract physics concepts |
| Generate | `alternate` | Generate alternate solutions |
| Generate | `variant` | Create fully validated variants from an accepted parent |
| Generate | `convert` | Convert between question formats |
| Quality | `check` | QA review with interactive approval |
| Quality | `compile` | Compile LaTeX to PDF |
| Manage | `init` | Initialize workspace config |
| Manage | `config` | Configure models, providers, settings |
| Manage | `ref` | Manage reference context files |
| Manage | `cache` | Cache management |
| Manage | `keys` | Cache-aware OpenAI profile rotation and usage limits |
| Manage | `db` | SQLite question bank |
| Manage | `metadata` | Question bank metadata |
| Manage | `export` | Export LaTeX (flat, structured, project) |
| Manage | `dpp` | Daily Practice Problem sets |
| Manage | `util` | File utilities (rename, count, clean) |
| Manage | `extans` | Extract answers from LaTeX |
| Manage | `screenshot` | Screenshot utilities |
| Interface | `chat` | Transparent natural-language authoring with complete tool traces |
| Interface | `mcp` | Typed natural-language authoring server for MCP hosts |
| Paper | `paper` | Paper orchestration (init, generate, solve, hint, compile, export) |

### Syllabus authoring and papers

Preflight a large batch without API calls, then run it through the durable
accepted-only pipeline:

```bash
vbagent author catalogs
vbagent author preflight --exam jee_main --subject physics --chapter kinematics --count 20
vbagent author run --exam jee_main --subject physics --chapter kinematics \
  --type mcq_sc:3 --type integer:1 --count 100 --concurrency 6 \
  --output agentic/authoring
```

Bundled official 2026 catalogs cover JEE Main Mathematics, Physics, and
Chemistry, plus NEET Physics, Chemistry, and Biology.

Paper creation consumes only accepted authoring artifacts:

```bash
# Optionally initialize from existing TeX problems
vbagent paper init --from-problems ./existing --subject physics --paper-dir ./jee-paper

# Author and import accepted problems
vbagent paper generate --exam jee_main --subject physics --chapter kinematics \
  --topic "Projectile Motion" --type mcq_sc --count 20 --paper-dir ./jee-paper

# Generate solutions for all problems
vbagent paper solve --paper-dir ./jee-paper

# Generate hints
vbagent paper hint --paper-dir ./jee-paper

# Compile to main.tex (stitches problems + solutions + hints + ideas + remarks)
vbagent paper compile --pdf --paper-dir ./jee-paper

# Compile only solutions
vbagent paper compile --only solutions --paper-dir ./jee-paper

# Compile only hints
vbagent paper compile --only hints --paper-dir ./jee-paper

# Export zip for Overleaf
vbagent paper export --paper-dir ./jee-paper
```

Each candidate is independently solved, answer-adjudicated, syllabus-checked,
difficulty-checked, compiled with `pdflatex`, reviewed, and checked for novelty
before it can count as accepted coverage. Runs persist in SQLite and can be
continued by run ID after interruption. See the
[problem authoring guide](docs/user-guide/problem-generation.md).

Human copies use stable names: `agentic/generated/problem_1.tex`, `problem_2.tex`,
and so on, with one JSON sidecar per problem. Each TeX file contains the question
and its selected components. The existing CLI assembler, answer extractor, and
PDF compiler create `main.tex`, `answer_key.tex`, and `main.pdf` in the project
root, using relative inputs into `agentic/generated`. Run IDs, attempts, and
build reports stay under `agentic/authoring`.

Use `--no-idea-component` for questions with solutions only, or `--no-solution`
for questions with ideas only. Deferred solutions are not generated behind the
scenes; those files are labelled unverified drafts. Later, `vbagent author
complete --run-id RUN_ID` adds missing components to the same numbered files.
Exhausted drafts await an author decision to keep, revise, or reject; liking a
draft does not bypass its correctness checks.

For natural-language authoring, use the transparent built-in chat host:

```bash
vbagent chat --output agentic/authoring
```

It opens before loading the MCP server or Agents SDK, then uses deferred
tool-search namespaces so only relevant schemas enter model context. `You:` and
`VBAgent:` messages and all tool I/O are formatted JSON. Normal answers stay
brief, and the model/token line is intentionally compact. A direct request to
create or generate problems starts in the background immediately after the
deterministic plan is shown; plan/preflight/ambiguous intent gets a direct
confirmation question answered with `yes` or `no`. Explicit start, resume, and
document-rebuild requests authorize only that action and run. While it runs, a
toolbar polls the durable ledger and shows the live
agent stage, latest run ID, chapter/topic, status, and accepted count without a
new message. Detached agent input/output is also streamed above the live prompt.
On completion the chat reports every saved deliverable and displays full generated
LaTeX (the first 20 for a large run; `/results RUN_ID` streams all of them).
Other consequential actions ask directly for `yes` or `no`; `/approve`,
`/decline`, and `confirm` remain available as aliases. Up and Down browse the
current process's message history, and one Ctrl+C cancels cleanly.
To connect another MCP-capable host to the same workspace through stdio:

```bash
vbagent mcp --output agentic/authoring
```

The host first inspects catalogs and creates a no-model-call plan. Starting or
resuming requires explicit user authorization: either the original direct
creation instruction or a later confirmation. Execution continues in a detached
worker while status, cancellation, pagination, review, and accepted/evidence
resources remain available. The authoring agents retain their configured
GPT-5.6 Luna/Terra/Sol routing and cache-aware profile rotation.

Paper directory structure:
```
paper_dir/
├── manifest.json          # Paper state and exact authoring provenance
├── authoring/             # Durable runs, SQLite ledger, gate evidence, artifacts
├── main.tex               # Compiled output
├── scans/                 # Per-problem .tex files (problem + solution + hint + idea + remark)
│   ├── Problem_1.tex
│   ├── Problem_2.tex
│   └── ...
├── solutions/             # Raw solution .tex files
├── hints/                 # Raw hint .tex files
└── paper_export.zip       # Overleaf-ready zip
```

### Configuration

```bash
vbagent config show                       # Show all agent configs
vbagent config models                     # List available models
vbagent config provider                   # Show current provider
vbagent config provider xai               # Switch to xAI (auto-applies model group)
vbagent config provider openai            # Switch back to OpenAI
vbagent config set scanner -m gpt-5.6-luna   # Override scanner model
vbagent config set default -m gpt-5.6-luna   # Change global default
vbagent config model-group                # List all model groups
vbagent config model-group openai         # Apply OpenAI model group
vbagent config subject chemistry          # Set subject
vbagent config log-level INFO             # Verbose JSON input/usage/output logs
vbagent config debug on                   # Add tracebacks + lifecycle JSONL
vbagent config reset                      # Reset to defaults
```

Config hierarchy: global (`~/.config/vbagent/models.json`) → workspace (`.vbagent.json`).

Agent logging defaults to verbose `INFO` output with JSON input, usage, and
output panels for every agent. `vbagent config debug on` is an alias for
`log-level DEBUG`; it adds tracebacks and writes metadata-only lifecycle events
to `.vbagent/logs/agent-events.jsonl`. Set
`VBAGENT_LOG_FILE=/path/to/events.jsonl` to persist lifecycle events at any log
level, or `VBAGENT_LOG_FILE=off` to disable the DEBUG event file.

### Supported Question Types

- `mcq_sc` — MCQ Single Correct
- `mcq_mc` — MCQ Multiple Correct
- `assertion_reason` — Assertion-Reason
- `match` — Match the Following (matrix match with codes)
- `passage` — Passage/Comprehension (paragraph MCQ)
- `integer` — Integer type (`\ansint{N}`)
- `subjective` — Subjective/Numerical

## Project Structure

```
vbagent/
├── __init__.py                          # Public API with lazy imports
├── config.py                            # Configuration (models, providers, subjects)
├── compile.py                           # LaTeX compilation, validation, verbose debug
├── cache.py                             # Pipeline cache (solutions, hints, problems)
├── tex.py                               # TeX formatting utilities (format_tex, center_wrap_tikz)
│
├── cli/                                 # CLI commands (Click-based, lazy-loaded)
│   ├── main.py                          # Entry point with SectionedGroup
│   ├── common.py                        # Shared utilities (panels, prompts, formatting)
│   ├── core/
│   │   ├── init.py                      # Workspace initialization
│   │   ├── classify.py                  # Classification command
│   │   ├── scan.py                      # LaTeX extraction command
│   │   ├── process.py                   # Full pipeline command
│   │   └── batch.py                     # Batch processing command
│   ├── generation/
│   │   ├── tikz.py                      # TikZ generation command
│   │   ├── fbd.py                       # FBD generation command
│   │   ├── idea.py                      # Concept extraction command
│   │   ├── alternate.py                 # Alternate solutions command
│   │   ├── variant.py                   # Variant generation command
│   │   └── convert.py                   # Format conversion command
│   ├── quality/
│   │   └── check.py                     # QA review command
│   ├── compilation/
│   │   └── compile_main.py              # LaTeX compile command + preamble
│   ├── management/
│   │   ├── config.py                    # Config management (provider, model-group, set)
│   │   ├── ref.py                       # Reference management
│   │   ├── db.py                        # Database management
│   │   ├── metadata.py                  # Metadata management
│   │   ├── export.py                    # Export command
│   │   ├── dpp.py                       # DPP command
│   │   ├── extans.py                    # Answer extraction
│   │   ├── screenshot.py                # Screenshot utilities
│   │   └── util.py                      # File utilities
│   ├── cache/
│   │   └── cache_commands.py            # Cache management commands
│   ├── interfaces/
│   │   ├── chat.py                      # Transparent MCP-backed CLI chat
│   │   ├── mcp.py                       # Typed authoring MCP server
│   │   └── ui.py                        # UI helpers
│   └── paper/
│       └── paper_commands.py            # Paper orchestrator CLI (init, generate, solve, hint, compile, export)
│
├── agents/                              # AI agent implementations
│   ├── base.py                          # Base agent (create, run, encode image)
│   ├── classifier.py                    # Backward-compatible classifier facade
│   ├── classification/                  # Classification system
│   │   ├── question_classifier.py       # Neutral routing + subject-specific analysis
│   │   ├── diagram_classifier.py        # Standalone diagram classification
│   │   ├── difficulty_assessor.py       # Difficulty assessment
│   │   ├── latex_classifier.py          # LaTeX classification
│   │   ├── taxonomy_classifier.py       # Taxonomy classification
│   │   └── schema_builder.py            # Schema builder
│   ├── content_generation/
│   │   ├── scanner.py                   # LaTeX extraction agent
│   │   ├── alternate.py                 # Alternate solution agent
│   │   ├── converter.py                 # Format converter agent
│   │   ├── idea.py                      # Concept extractor agent
│   │   ├── idea_generator.py            # Idea-to-problem generator
│   │   ├── idea_curator.py              # Idea-bank curator
│   │   ├── idea_combiner.py             # Multi-idea problem designer
│   │   ├── problem_combiner.py          # Multi-problem combiner
│   │   └── solution/
│   │       └── __init__.py              # Solution agent (routes by subject × question_type)
│   ├── diagram/                         # TikZ diagram agents
│   │   ├── base.py                      # Base diagram agent (600s timeout, style discipline)
│   │   ├── tikz.py                      # Generic TikZ agent
│   │   ├── tikz_router.py              # TikZ agent routing
│   │   ├── tikz_checker.py             # TikZ validation agent
│   │   ├── mcq_option_coordinator.py   # MCQ option diagram coordinator
│   │   ├── physics/
│   │   │   ├── fbd.py                   # Free body diagram
│   │   │   ├── circuit.py               # Circuit diagram
│   │   │   ├── graph.py                 # Physics graph
│   │   │   └── optics.py               # Optics diagram
│   │   ├── chemistry/
│   │   │   ├── organic_structure.py     # Organic structure
│   │   │   ├── organic_orchestrator.py  # Organic multi-step orchestrator
│   │   │   ├── organic_simple.py        # Simple organic
│   │   │   ├── organic_complex.py       # Complex organic
│   │   │   ├── organic_functional.py    # Functional group
│   │   │   ├── organic_mechanism.py     # Reaction mechanism
│   │   │   ├── organic_multistep.py     # Multi-step synthesis
│   │   │   ├── organic_stereo.py        # Stereochemistry
│   │   │   ├── chemical_equation.py     # Chemical equation
│   │   │   ├── energy_diagram.py        # Energy diagram
│   │   │   ├── lewis_structure.py       # Lewis structure
│   │   │   ├── orbital.py              # Orbital diagram
│   │   │   └── reaction_mechanism.py    # Reaction mechanism
│   │   └── mathematics/
│   │       ├── coordinate_geometry.py   # Coordinate geometry
│   │       ├── function_graph.py        # Function graph
│   │       ├── geometric_figure.py      # Geometric figure
│   │       ├── number_line.py           # Number line
│   │       └── venn_diagram.py          # Venn diagram
│   ├── orchestration/
│   │   ├── problem_orchestrator.py      # Problem orchestrator
│   │   └── solution_orchestrator.py     # Solution orchestrator
│   ├── quality/
│   │   ├── base.py                      # Base quality agent
│   │   ├── reviewer.py                  # QA reviewer
│   │   ├── solution_checker.py          # Solution checker
│   │   ├── grammar_checker.py           # Grammar checker
│   │   ├── clarity_checker.py           # Clarity checker
│   │   ├── format_checker.py            # Format checker
│   │   └── latex_fixer.py              # LaTeX fixer
│   ├── variants/
│   │   ├── variant.py                   # Single variant generator
│   │   ├── cross_topic.py              # Cross-topic variant
│   │   └── multi_context_variant.py    # Multi-context variant
│   ├── selection/
│   │   └── selector.py                 # Problem selector
│   └── metadata/
│       └── enricher.py                 # Metadata enricher
│
├── prompts/                             # LLM prompt templates
│   ├── classification/
│   │   ├── classifier.py                # Base classifier prompt
│   │   ├── question_classifier.py       # Question classifier prompt
│   │   ├── diagram_classifier.py        # Diagram classifier prompt
│   │   ├── question_types.py            # Question type definitions
│   │   └── taxonomy.py                  # Taxonomy definitions
│   ├── content_generation/
│   │   ├── alternate.py                 # Alternate solution prompt
│   │   ├── converter.py                 # Converter prompt
│   │   ├── idea.py                      # Idea extraction prompt
│   │   ├── idea_generator.py            # Idea generator prompt
│   │   ├── idea_curator.py              # Idea curator prompt
│   │   ├── idea_combiner.py             # Idea combiner prompt
│   │   ├── problem_combiner.py           # Problem combiner prompt
│   │   ├── scanner/                     # Scanner prompts (per subject × question type)
│   │   │   ├── _shared.py               # Shared scanner rules
│   │   │   ├── physics/
│   │   │   │   ├── common.py            # Physics common rules
│   │   │   │   ├── formatting_rules.py  # Physics formatting
│   │   │   │   ├── mcq_sc.py, mcq_mc.py, subjective.py
│   │   │   │   ├── assertion_reason.py, match.py, passage.py
│   │   │   │   ├── problem_only.py, solution_only.py
│   │   │   │   └── __init__.py          # Router
│   │   │   ├── chemistry/               # (same structure as physics)
│   │   │   └── mathematics/             # (same structure as physics)
│   │   └── solution/                    # Solution prompts (per subject × question type)
│   │       ├── __init__.py              # Top-level router
│   │       ├── physics/
│   │       │   ├── common.py            # Physics solution rules
│   │       │   ├── mcq_sc.py, mcq_mc.py, subjective.py
│   │       │   ├── assertion_reason.py, match.py, passage.py
│   │       │   └── __init__.py          # Router
│   │       ├── chemistry/               # (same structure as physics)
│   │       └── mathematics/             # (same structure as physics)
│   ├── diagram/
│   │   ├── _style_discipline.py         # TikZ style rules (no colors, no inline overrides)
│   │   ├── tikz_checker.py              # TikZ checker prompt
│   │   ├── physics/
│   │   │   ├── fbd.py, circuit.py, graph.py, optics.py, generic.py
│   │   │   └── __init__.py
│   │   ├── chemistry/
│   │   │   ├── organic_structure.py, organic_simple.py, organic_complex.py
│   │   │   ├── organic_functional.py, organic_mechanism.py, organic_multistep.py
│   │   │   ├── organic_stereo.py, chemical_equation.py, energy_diagram.py
│   │   │   ├── lewis_structure.py, orbital.py, reaction_mechanism.py
│   │   │   └── __init__.py
│   │   └── mathematics/
│   │       ├── coordinate_geometry.py, function_graph.py, geometric_figure.py
│   │       ├── number_line.py, venn_diagram.py
│   │       └── __init__.py
│   ├── quality/
│   │   ├── reviewer.py, solution_checker.py, grammar_checker.py
│   │   ├── clarity_checker.py, format_checker.py
│   │   └── __init__.py
│   ├── variants/
│   │   ├── numerical.py, context.py, conceptual.py
│   │   ├── conceptual_calculus.py, cross_topic.py, multi_context.py
│   │   └── __init__.py
│   └── subjects/
│       └── __init__.py                  # Subject-specific context
│
├── models/                              # Pydantic data models
│   ├── classification.py                # Classification models
│   ├── content.py                       # Content models
│   ├── diagram.py                       # Diagram models
│   ├── diff.py                          # Diff models
│   ├── metadata.py                      # Metadata models
│   ├── orchestration.py                 # Orchestration models
│   ├── pipeline.py                      # Pipeline models
│   ├── quality.py                       # Quality models
│   ├── review.py                        # Review models
│   ├── solution.py                      # Solution models
│   ├── version_store.py                 # Version store models
│   └── workflow.py                      # Workflow models
│
├── paper/                               # Paper orchestrator
│   ├── __init__.py
│   ├── models.py                        # Paper data models
│   ├── manifest.py                      # Atomic JSON manifest handling
│   ├── syllabus.py                      # Syllabus topic definitions
│   ├── orchestrator.py                  # Accepted-authoring consumer, compile, export, assemble
│   └── qa.py                            # Paper QA
│
├── pipeline/                            # Processing pipeline
│   ├── __init__.py
│   ├── io.py                            # Pipeline I/O
│   ├── runner.py                        # Pipeline runner
│   └── stages.py                        # Pipeline stages
│
├── database/                            # SQLite question bank
│   ├── store.py                         # QuestionDatabase
│   ├── extractor.py                     # ContentExtractor
│   ├── reconstructor.py                 # LaTeX reconstruction
│   └── metadata_helper.py              # Agent metadata population
│
├── references/                          # Reference context management
│   ├── store.py                         # Reference store
│   ├── context.py                       # Context builder
│   ├── tikz_store.py                    # TikZ reference store
│   └── samples/                         # Sample references
│       ├── physics/                     # assertion_reason.tex, mcq_mc.tex, mcq_sc.tex, subjective.tex
│       ├── chemistry/                   # mcq_mc.tex, mcq_sc.tex, subjective.tex
│       └── mathematics/                 # mcq_mc.tex, mcq_sc.tex, subjective.tex
│
├── storage/                             # Content storage
│   ├── content_cache.py                 # Content cache
│   └── metadata_manager.py             # Metadata manager
│
├── orchestrator/                        # Generic tool adapters
│   ├── conversation.py                  # Legacy conversation handler
│   ├── tools.py                         # Tool definitions
│   └── tool_wrappers.py               # Tool wrappers
│
├── dpp/
│   └── builder.py                       # DPP builder
│
├── export/
│   └── exporter.py                      # LaTeX exporter
│
├── mcp/
│   ├── chat.py                          # Cache-aware FastMCP chat bridge
│   └── server.py                        # FastMCP authoring server
│
├── metadata/
│   └── store.py                         # Metadata store
│
├── templates/
│   └── agentic_context.py              # CONTEXT.md generator
│
├── ui/                                  # Terminal UI
│   ├── components.py                    # UI components
│   ├── logging.py                       # Logging
│   ├── styles.py                        # Styles
│   └── tables.py                        # Tables
│
└── utils/
    ├── formatting.py                    # Formatting utilities
    └── latex.py                         # LaTeX utilities

tests/
├── agents/
│   ├── classification/                  # test_classification.py, test_database.py, test_models.py, test_router.py
│   ├── content_generation/              # test_alternate.py, test_converter.py, test_idea.py, test_scanner.py
│   ├── diagram/                         # test_tikz.py
│   ├── metadata/                        # test_metadata.py
│   ├── orchestration/                   # test_orchestrator.py
│   ├── quality/                         # test_review.py
│   ├── selection/                       # test_selector.py
│   └── variants/                        # test_variant.py
├── cli/
│   ├── core/                            # test_batch.py, test_process.py
│   ├── interfaces/                      # test_chat_cli.py, test_mcp_server.py
│   └── management/                      # test_config.py, test_export_tools.py, test_export.py
├── integration/                         # test_context.py, test_dpp_builder.py, test_import_performance.py, ...
├── models/                              # test_version_store.py
├── paper/                               # test_cli.py, test_authoring.py, test_manifest.py, test_models.py, ...
├── ui/                                  # test_ui_components.py
└── utils/                               # test_formatting.py, test_latex.py, test_tex_parser.py
```

## LaTeX Compilation

The `-c` / `--compile` flag validates generated LaTeX by compiling with `pdflatex`. If compilation fails, the compile-fixer agent automatically attempts to fix errors (up to 2 retries).

### Compile Preamble

- `fourier[upright]` for fonts
- `\everymath{\displaystyle}` for display-style math
- `amsmath`, `amssymb`, `amsthm`, `mathtools`
- `tikz` with libraries: calc, decorations, patterns, arrows.meta, positioning, shapes, intersections, angles, quotes
- `circuitikz` (american style), `pgfplots` (compat=1.18)
- `tasks` (MCQ options), `enumitem`
- `mhchem`, `chemfig` (chemistry only)
- Auto-detected packages from `.tex` file content

### Environment Definitions

| Environment | Color | Symbol |
|-------------|-------|--------|
| `solution` | red | `$\Rightarrow$` |
| `alternatesolution` | blue | `$\Rrightarrow$` |
| `hint` | maroon | `$\looparrowright$` |
| `idea` | violet | `$\diamond$` |
| `remark` | teal | `$\circ$` |

## License

MIT

