Skip to content

osrforge.estimate

Cost estimation: preprocess only, then pure arithmetic — a rough token/cost estimate with no model call.

estimate runs the real preprocess() into the given workdir — the licensing invariant forbids persisting module text outside the user's workdir, so a temp directory is not an option, and the workdir is warm for the human's next step (rerun survey continues from the rendered pages) — then does pure arithmetic: no provider, no model call.

The heuristics are pinned from measured behavior (the recorded capability probes and four recorded full-module calibration runs) and kept deliberately coarse — "rough" is the contract, and the recorded calibration band (±40% on input tokens against the measured runs) keeps the error honest. Schema retries and missing-key follow-ups are real tokens no pre-call estimate can see; the band, not the point value, is the contract.

IMAGE_TOKENS_PER_PAGE module-attribute

IMAGE_TOKENS_PER_PAGE = 905

The measured per-page image cost — DPI-independent (100/150/200 DPI cost identical tokens).

INPUT_USD_PER_TOKEN module-attribute

INPUT_USD_PER_TOKEN = 2.5 / 1000000

Input price at the ≤272K single-request tier.

LARGE_INPUT_USD_PER_TOKEN module-attribute

LARGE_INPUT_USD_PER_TOKEN = 5.0 / 1000000

Input price once a single request crosses the 272K-token cliff.

LARGE_OUTPUT_USD_PER_TOKEN module-attribute

LARGE_OUTPUT_USD_PER_TOKEN = 22.5 / 1000000

Output price once a single request crosses the 272K-token cliff.

LARGE_REQUEST_INPUT_TOKENS module-attribute

LARGE_REQUEST_INPUT_TOKENS = 272000

The single-request input size beyond which the doubled tier applies.

OUTPUT_USD_PER_TOKEN module-attribute

OUTPUT_USD_PER_TOKEN = 15.0 / 1000000

Output price at the ≤272K single-request tier.

CostEstimate dataclass

CostEstimate(
    page_count: int,
    text_tokens: int,
    image_tokens: int,
    survey_window_count: int,
    survey_input_tokens: int,
    survey_output_tokens: int,
    census_input_tokens: int,
    census_output_tokens: int,
    content_input_tokens: int,
    content_output_tokens: int,
    monsters_input_tokens: int,
    monsters_output_tokens: int,
    mapread_input_tokens: int,
    mapread_output_tokens: int,
    input_tokens: int,
    output_tokens: int,
    usd: float,
)

The estimate: per-stage token predictions and the USD figure hosts surface.

Attributes:

Name Type Description
page_count int

The source's page count.

text_tokens int

Estimated tokens in the text layers, all pages.

image_tokens int

Estimated page-image tokens, all pages.

survey_window_count int

How many requests the survey runs as — 1 at or under survey_max_pages pages, one per chunked page window above. The census runs over the same windows.

survey_input_tokens int

Estimated survey input, all windows.

survey_output_tokens int

Estimated survey output, all windows.

census_input_tokens int

Estimated census input, all windows — the survey's page-image-dominated input with a smaller overhead.

census_output_tokens int

Estimated census output, all windows.

content_input_tokens int

Estimated content-pass input, all batches.

content_output_tokens int

Estimated content output.

monsters_input_tokens int

Estimated monsters-stage input — the flat LLM tier plus the page-count-priced stat-block pass.

monsters_output_tokens int

Estimated monsters-stage output, same terms.

mapread_input_tokens int

Estimated map-reading input — one request per level, levels priced from page count.

mapread_output_tokens int

Estimated map-reading output, same terms.

input_tokens int

The input total.

output_tokens int

The output total.

usd float

The estimated cost, with each survey and census window priced at the doubled tier when that window's estimated input crosses the 272K cliff.

page_count instance-attribute

page_count: int

text_tokens instance-attribute

text_tokens: int

image_tokens instance-attribute

image_tokens: int

survey_window_count instance-attribute

survey_window_count: int

survey_input_tokens instance-attribute

survey_input_tokens: int

survey_output_tokens instance-attribute

survey_output_tokens: int

census_input_tokens instance-attribute

census_input_tokens: int

census_output_tokens instance-attribute

census_output_tokens: int

content_input_tokens instance-attribute

content_input_tokens: int

content_output_tokens instance-attribute

content_output_tokens: int

monsters_input_tokens instance-attribute

monsters_input_tokens: int

monsters_output_tokens instance-attribute

monsters_output_tokens: int

mapread_input_tokens instance-attribute

mapread_input_tokens: int

mapread_output_tokens instance-attribute

mapread_output_tokens: int

input_tokens instance-attribute

input_tokens: int

output_tokens instance-attribute

output_tokens: int

usd instance-attribute

usd: float

estimate

estimate(pdf_path: Path, workdir: Path, settings: ConversionSettings | None = None) -> CostEstimate

Price a conversion before any model call: preprocess, then pinned heuristics.

Parameters:

Name Type Description Default
pdf_path Path

The source module PDF.

required
workdir Path

The workdir root to create or rebuild — preprocess output must land in the user's workdir (the licensing invariant), and it is warm for the next step.

required
settings ConversionSettings | None

Pipeline settings; defaults to ConversionSettings().

None

Returns:

Type Description
CostEstimate

The estimate.

Raises:

Type Description
PdfError

If preprocessing rejects the source.

Examples:

from pathlib import Path

from osrforge import estimate

cost = estimate(Path("module.pdf"), Path("module.forge"))
print(f"{cost.page_count} pages, ~${cost.usd:.2f}")