API
These notes are generated from the docstrings. A public member with no docstring is left out.
cli
Command line: run a book, open the window, bake off models, or run the Mars scenario.
The llama client and the export libraries are imported inside the command that uses them, so opening the window does not pay for them first.
build_parser()
Build the plotweaver command parser, including every subcommand.
main(argv=None)
Run one plotweaver command and return its exit code.
clidoc
Command reference rendered from the live argument parser.
render_cli_reference(parser=None)
Render the command reference from the program's argument parser.
domain
Book request and the small enums the pipeline branches on.
Language
Book language: Russian or English.
BookMode
How far the user stops the pipeline: autopilot, copilot, or manual.
ModelTier
STANDARD is the usual drafter.
LEAST_CENSORED is an installed Model Forge model. The stock drafter is the fallback.
Gender
Character gender used for speakers and voice.
ExportFormat
User-facing book files. EPUB and .vxbook are always written.
Task
Routing label on every model call. The mock backend switches on it.
BookRequest(title, language, synopsis, genre='', target_words=80000, chapter_count=None, scenes_per_chapter=2, pov='third-person limited', tense='past', dark_themes=False, tier=ModelTier.STANDARD, mode=BookMode.AUTOPILOT, reference_paths=list(), main_model_id='', least_censored_model_id='', main_gguf='', least_censored_gguf='', scene_words=None, author='', export_formats=(lambda: [ExportFormat.EPUB.value])(), created='', sound_markup=False, brief=None, prompt_override='', generation_context='')
dataclass
What the user sets when a book is created. Stored as project.json.
shape()
Return (chapters, scenes per chapter, words per scene).
parse_gender(value)
Map a model value to male, female, or unspecified.
request_to_dict(req)
Serialise a book request for project.json.
request_from_dict(data)
Read a book request back from project.json.
normalize_formats(value)
EPUB 3 is always included. Unknown names are dropped.
repo_file(name)
A path relative to the checkout, used by scenarios and the bake-off.
prompts
Fiction-framing prompts. Every call carries a TASK line the mock backend routes on.
The prompts ask for a novel. They do not ask the model to produce real-world harm, and they do not include jailbreak text.
system_message()
Return the ghostwriter system message sent with every model call.
bible_prompt(req)
Ask for the story bible as one JSON object.
outline_parts_prompt(req, bible, spans)
Ask for the part list that covers every chapter exactly once.
outline_chapters_prompt(req, bible, part, start, end, budgets)
Ask for one batch of chapters inside a single part.
outline_repair_prompt(req, bible, *, kind, start, end, missing, spans, part, budgets)
Ask again for the chapter or part numbers the previous reply skipped.
beats_prompt(req, bible, chapter, chapter_index, continuity='')
Ask for the scene beats of one chapter.
draft_prompt(req, bible, chapter, scene, previous_tail, style_card, continuity=None)
Ask for the prose of one scene, with a digest and the rolling summary.
fill_prompt(req, bible, placeholder, previous_text, next_text, continuity='')
Ask a second model to write a scene the first model left blank.
extract_prompt(req, chapter_id, prose, previous_story='')
Ask for the canon facts stated in one chapter, plus a rolling summary.
rewrite_prompt(req, prose, problems)
Ask for one rewrite that fixes the listed problems.
proofread_prompt(req, chapter_title, prose)
Ask for a spelling pass that keeps the plot.
style_prompt(req, measured, excerpt)
Ask for a neutral style card from a reference excerpt.
brief_draft_prompt(idea, language)
Ask the local model to expand notes into a version-1 book brief.
judge_prompt(packet)
Ask the judge model to score a prose packet.
bible_digest(bible)
Names, roles, voices, and the logline. Secrets and arcs stay out of later prompts.
runner
Synopsis to exported book. Checkpointed after every step. One large model at a time.
Dark-themes OFF: the main model plans, drafts, checks, and proofreads. No swap. Dark-themes ON: pass 1 leaves dark or refused scenes as placeholders. Pass 2 loads the least-censored model once, fills every placeholder, and proofreads while that model is loaded.
RunResult(status, gate, export_dir, swaps, refusals, placeholders, rewrites, output_codes=dict())
dataclass
What a book run finished with: status, gate, and the export counts.
draft_book_brief(idea, language, backend)
Expand loose notes into a full brief. The caller reviews it before writing.
run_book(project, backend, *, yes=False, approve=False, on_progress=None, export_to=None, thermal=None)
Run or resume a book. yes skips gates. approve clears the current gate.
export_book(project, backend, *, formats, sound, export_to)
Write the export bundle for a project that already has an outline.
This does not draft. Sound markup is the only step that calls a model.
store
One folder per book: JSON artefacts, a checkpoint, and the SQLite canon.
Checkpoint(path)
Steps that finished. A crash before mark() runs the step again.
Project(root)
The folder for one book: request, artefacts, checkpoint, and canon.
open_or_create(root, request)
classmethod
Create the project folder and project.json when they are missing.
request()
Read the stored book request.
save_request(request)
Write the book request back to project.json.
Canon(path)
Characters, facts, timeline, threads, knowledge. Each fact keeps its chapter.
characters()
Story-bible characters in insertion order.
export
EPUB 3, Voxprint Book, and optional FictionBook, DOCX, Markdown, and speaker marks.
RenderedParagraph(text, speaker, gender, parts=())
dataclass
One paragraph ready to write into an export.
RenderedChapter(title, paragraphs, id='')
dataclass
One chapter of rendered paragraphs.
speaker_mark(speaker, gender)
One Audiobook Builder mark: NARRATOR, MALE: Name, or FEMALE: Name.
render_markdown(chapters)
Return (book.md, speaker-marks.txt). Marks line up with paragraph blocks, not headings.
write_docx(path, chapters)
Write the chapters to a DOCX file.
fb2_schema_dir()
Vendored FictionBook 2.1 schema (BSD-2-Clause, Dmitry Gribov).
fb2_genre(raw, language)
Map a free-text genre onto a code the FictionBook schema accepts.
cover_png()
Suite mark used as the book cover. A 1×1 PNG is the last resort.
write_fb2(path, *, title, language, author, genre, synopsis, chapters, cover=None)
FictionBook 2.1: title-info, cover, annotation, and a titled section per chapter.
write_epub(path, title, language, chapters, *, author='', cover=None)
EPUB 3 package: navigation document, cover, and one XHTML file per chapter.
write_bundle(directory, title, language, chapters, overlap, *, author='', genre='', synopsis='', formats=None, created='', speakers=None)
Write book.vxbook and EPUB 3, plus any extra formats the user asked for.
publish_exports(source, dest)
Copy the export bundle to the folder the user asked for.
bind_rendered(chapters, cards)
Map canon speaker names onto vxbook ids. Inferred speech is src=auto.
export_output_names(formats, *, sound)
Files a generate or export run writes. Paths are relative to the export directory.
registry
Model registry, shared GGUF folder, and SHA-256 checks.
Weights live in <shared>/models/llm. A matching file already stored under
the older <home>/models/llm path is reused. Every entry records a confirmed
base licence. Apache-2.0 and MIT are accepted. An empty licence is refused,
including with --allow-other-license, because an untagged tune has nothing to
record. Heretic is not a registry entry.
RegistryEntry(id, role, repo, filename, sha256, size, license, min_vram_gb, context, moe, notes, revision='', base_repo='', base_revision='', base_license='', card='', tier='', default=False, enabled=True, optional=False, uncensored=False, languages=())
dataclass
One published model row from the registry file.
require_sha256(sha256, label)
Refuse a model whose registry entry has no 64-hex SHA-256.
load_registry(path)
Read the model rows from a registry TOML file.
claim_user(store, user='plotweaver')
Add this app to <models>/.users.json without dropping other suite apps.
The file is the same one Audiobook Builder and Movie Dubber share. A key that is already true is left byte-for-byte alone.
registry_path()
Path to the bundled bakeoff/models.toml registry.
is_stock(entry)
Rows in the default install: enabled and not optional.
stock_for_tier(entries, *, total_gb)
Default-install models for the detected tier only, not the other tier.
fits_vram(entry, free_gb)
Bake-off gate: the file fits free VRAM. The app uses model_offered instead.
tier_headroom_gb(total_gb)
Leave 2 GB free below 23.5 GB, and 3 GB free on a 24 GB card or larger.
tier_capacity_gb(total_gb)
VRAM available for choosing models, from the card total, ignoring other processes.
detected_tier(total_gb)
24 GB at the suite probe's 23.5 GiB cut. 8 GB and 16 GB stay on the 16 GB plan.
resolve_tier(total_gb, override=None)
Auto picks 16 GB under 23.5 GB of VRAM, and 24 GB at that size or above.
A saved 24 GB override on a smaller card falls back to the detected tier.
tier_allows(entry, selected)
A 24 GB card can still run 16 GB models. A 16 GB card cannot run 24 GB models.
model_offered(entry, *, total_gb, free_gb, override=None)
True when this card's total VRAM tier can run the file.
free_gb is accepted so callers can pass the live reading. The install
set follows the card total, not memory another process is holding.
tier_option_enabled(tier, *, total_gb, free_gb)
Settings can force 24 GB only when some published 24 GB model fits the card total.
uncensored_offer_allowed(total_vram_gb, free_gb=None)
True when this card can run a published least-censored model.
bakeoff_skip_reason(entry, *, free_gb)
The bake-off downloads every enabled candidate that fits, stock or abliterated.
stored_filename(entry)
On-disk GGUF name. A bare quant such as Q5_K_M.gguf is prefixed with the model id.
migrate_generic_weight(folder, entry)
Hardlink a verified generic quant onto the model-id name, then remove the generic name.
A file whose SHA-256 does not match is left in place. A legacy copy outside
folder is not touched.
weight_path(folder, entry)
Installed weight, after a verified generic quant has been renamed by hardlink.
VOXPrint MDL stores the bytes at <models>/blobs/<sha256>. A missing
file in folder is hardlinked from that blob when the size matches.
download_model(entry, store=None, *, allow_other=False, on_progress=None)
Return one verified local weight. Plotweaver does not download it.
Missing bytes are fetched by VOXPrint MDL. This function hardlinks a blob MDL already stored and refuses a file that is not there yet.
model_public_row(entry)
Fields a bot can rely on from plotweaver models list --json.
import_forge_manifest(manifest, registry=None, *, dry_run=False)
Fill disabled least-censored rows from a Model Forge JSON manifest.
Each object needs id, revision, sha256, and size. Optional
repo, filename, and min_vram_gb replace those fields. The row
is enabled. Stock and default-install rows are refused. dry_run validates and returns the
ids without writing the registry.
llm
Model call types and JSON completion with one grammar retry.
ChatMessage(role, content)
dataclass
One message in a model chat.
Completion(text, prompt_tokens, completion_tokens, model_id)
dataclass
Text and token counts from one model reply.
ModelSpec(id, path, context=8192, license='Apache-2.0', moe=False)
dataclass
One GGUF the worker may load. Only one large model is resident at a time.
LLMBackend
The model caller the pipeline uses.
load(spec)
Load this model, unloading any other large model first.
unload()
Drop the resident model so the next load is the only one in memory.
prepare_batch()
Re-measure VRAM before a batch. The mock does nothing.
complete(messages, *, temperature, max_tokens, json_mode, response_format=None)
One non-streaming completion.
task_of(messages)
Read the TASK line from the latest user message.
complete_json(backend, messages, *, temperature, max_tokens)
Ask for JSON. One grammar retry, then a lenient repair, then fail.
The log line names the path that succeeded: json_object, repaired,
json_schema, or json_schema-repaired.
hardware
NVIDIA detection, the driver minimum, the suite VRAM budget, and the 83 C thermal rule.
The product refuses to start a real job without an NVIDIA RTX 40-series GPU or newer (compute capability 8.9 or higher, and "RTX" in the device name). The card size uses voxprint-common's probe: 23.5 GiB and above is the 24 GB tier. The driver floor stays 570.117 on Linux and 551.61 on Windows, the CUDA builds this app ships. The suite probe's 600-series gate is not used. Tests set PLOTWEAVER_FAKE_GPU instead of calling nvidia-smi.
GpuInfo(name, compute_cap, total_mib, free_mib)
dataclass
Name, compute capability, and memory of one NVIDIA GPU.
VramHolder(pid, name, used_mib)
dataclass
One process currently using GPU memory.
DriverStatus(ok, version, minimum, message)
dataclass
Whether the installed NVIDIA driver can run the pinned CUDA runtime.
ThermalGuard(now=time.monotonic)
Full speed for 2.5 hours, then pause while the 5-minute median stays at 83 C or above.
A throttle bit held for more than 60 seconds also pauses. Work resumes at 75 C with the throttle clear. A missing sensor never pauses the job.
pause_after_batch(sample=read_nvidia_sample, sleep=time.sleep, log=lambda _message: None)
Sample and, when the rule says so, sleep until the card is cool or 10 minutes pass.
vram_headroom_gb(total_gb)
Leave at least 2 GB free, or 8 percent of the card when that is larger.
vram_budget_gb(free_gb, total_gb, fraction=None)
budget = free_now - max(2 GB, 8% of total). An optional fraction caps it further.
query_gpu()
NVIDIA GPU from nvidia-smi, or None when that probe is absent.
PLOTWEAVER_FAKE_GPU is name,compute_cap,total_mib,free_mib or none.
On a hybrid laptop the discrete NVIDIA device is used, not the iGPU.
query_vram_holders()
Processes holding GPU memory.
PLOTWEAVER_FAKE_VRAM_HOLDERS is pid,name,mib rows separated by
semicolons. An empty value or none means nothing is holding the card.
vram_short_message()
Name the processes holding GPU memory when a model cannot be loaded.
is_supported(info)
RTX 40-series (Ada, sm_89) or a newer RTX card.
minimum_driver()
Driver tuple required by the CUDA build for this operating system.
format_driver(parts)
Join a driver tuple the way nvidia-smi prints it.
parse_driver(text)
Leading integers from a driver version such as 570.117.
driver_meets(found, minimum=None)
True when found is at least minimum (the platform CUDA floor by default).
query_driver_version()
Installed NVIDIA driver, or None when nvidia-smi has nothing to report.
PLOTWEAVER_FAKE_DRIVER is a version string, or none.
driver_status()
Plain-language driver check, including NVIDIA's download page when it is too old.
driver_allows_cuda()
True when the installed driver can run the pinned CUDA llama.cpp build.
require_supported_gpu()
Return the GPU, or raise when it is not an RTX 40-series card or newer.
read_nvidia_sample()
Temperature, power, and the throttle mask. Missing sensors come back empty.
install
Default downloads, and the extra optional downloads from Settings.
The installer downloads the default models for the detected tier (rows with optional = false). A later launch only repairs a file that is missing or corrupt. Extra least-censored quants and the stock models stay out of that set until Settings asks for them. A Russian book prefers an installed T-lite file for its language. Otherwise the largest installed uncensored model for the tier is used, and the default drafter is the fallback.
ensure_default_install(*, free_gb, total_gb=None, store=None)
Count stock models for this tier that are already on disk.
VOXPrint MDL downloads the files. This function does not.
optional_notice(entry)
Size and a rough time estimate for one optional download.
ensure_uncensored_models(*, total_vram_gb, free_gb=None, store=None, on_progress=None)
Count published least-censored models for this tier that are already on disk.
assign_book_models(request, *, free_gb, store, total_gb=None)
Fill empty model paths. Explicit paths from the caller stay as they are.
prepare_real_models(request, *, store=None, on_progress=None)
Bind installed stock models. A missing file stays a models-not-ready error.
vxbook
Voxprint Book (.vxbook) writer and validator. Spec v1.0.
The archive is the Audiobook Builder hand-off. Legacy numbered speaker marks are produced from the same file by the mapping in section 7 of the spec.
BlockKind
A block in a Voxprint Book: paragraph, quote, scene, or subhead.
VxChapter(id, title, blocks=list())
dataclass
One chapter in a Voxprint Book.
VxSpeaker(id, role, name='', gender='unspecified', age_group='unspecified', aliases=(), voice_hints=None)
dataclass
One speaker record in a Voxprint Book.
VxParagraph(index, chapter, raw_line, plain, scene_start, mirrors=())
dataclass
One counted paragraph, in the order Audiobook Builder already uses.
even_utc_now()
UTC timestamp with even seconds, so the ZIP time matches the manifest.
display_name(name)
NFC display name with stress marks and invisible characters removed.
name_key(value)
Match key: NFC, stress removed, spaces collapsed, case folded.
speaker_slug(name)
Transliterate a speaker name into the vxbook id grammar.
narrator_speaker()
The narrator speaker every book includes.
coerce_age_group(value, age=None)
Story-bible age_group, or an integer age mapped onto the spec's groups.
coerce_hints(value, voice='')
Keep known voice-hint keys. A free-text bible voice becomes notes.
make_character(name, gender, used, *, age_group='unspecified', aliases=(), voice_hints=None)
Build a character speaker whose id does not collide with ids already used.
with_given_aliases(speakers)
Add a given-name alias when that given name belongs to one character.
build_character_speakers(rows)
speakers.json characters from canon rows plus optional bible fields.
bundled_cover()
Committed suite cover. Runtime encoding would make the archive drift.
pack_vxbook(path, manifest, members)
Write a reproducible stored-method archive. files is recomputed.
write_vxbook(path, *, title, author, language, chapters, speakers, created='', synopsis='', cover=None)
Write one .vxbook and refuse to leave it on disk when validation fails.
validate_vxbook(path)
Spec section 10. Warnings (offsets, a cover that will not decode) do not fail.
legacy_pair(path)
Section 7 plain text and numbered speaker marks taken from a .vxbook.
inspect_cover(data)
Decode a cover in memory and enforce the 100 megapixel cap.
emitted_chapter_id(raw, index, count)
Letter-leading chapter id. 1 and 2 become ch01 and ch02.
Numbers are zero-padded to 2 digits, or 3 when the book has more than 99 chapters.
read_archive(path)
Read a .vxbook into memory. Raises when the archive itself is unsafe.
paragraph_map(text)
Counted paragraphs, including v1.1 stacked directives.
sound
VXBOOK v1.1 + sound extension v1 (sound/1).
Schema, checks, and the Add sound markup writer live here so a later minor tweak stays in one module. Plotweaver never generates audio.
SoundIssue(severity, message)
dataclass
One sound-markup problem, as an error or a warning.
check_sound(manifest, members, paragraphs)
Validation checklist for sound extension v1. Empty when the book has none.
sound_prompt(paragraphs, locked)
English instructions for one sound-markup completion.
resolve_vxbook(path)
A .vxbook file, a project folder, or a directory that already holds the book.
add_sound(source, dest, backend, *, mirror=False)
Write a new .vxbook with sound extension v1. The source file is not modified.
assemble(paragraphs, proposed, previous)
Merge model markup with src=user scenes and cues. User items stay byte-stable.
atomic
Atomic JSON and text writes so a crash never leaves a half file.
The publish and the lock are voxprint-common. read_json stays here.
read_json(path)
Read a JSON file written by write_json.
jsontext
Pull a JSON object out of a model reply that may contain a think channel or fences.
parse_json_object(text)
Return the JSON object in a model reply, or None when it is not there.
load_json_object(text)
Return the object and plain, repaired, or none.
plain is a reply that is one JSON object. The repair pass strips a think
channel, fences, and prose, then drops trailing commas.
settings
Saved suite choices. The optional-model switch lives in Settings.
uncensored_models_preference()
Abliterated downloads stay off until Settings saves an explicit yes.
save_uncensored_models(enabled)
Save whether Settings should download abliterated models.
model_tier_override()
Advanced Settings choice: auto, 16gb, or 24gb. Missing values mean auto.
save_model_tier_override(value)
Save the advanced VRAM tier choice: auto, 16gb, or 24gb.
scenarios
Fixed scenarios shipped with the repo. The Mars run is the 4090 end-to-end sample.
mars_synopsis_path(root=None)
Path to the Mars scenario synopsis.
mars_outline_path(root=None)
Path to the Mars scenario outline.
mars_request(root=None)
Short Russian science-fiction book: invented crew, SpaceX as the company.
checks
Lightweight checks. A hit is a note for at most one rewrite, not a retry loop.
is_refusal(text)
True when the prose contains a model refusal.
is_sanitised(text)
True when the prose contains a softening phrase.
chapter_problems(text)
Deterministic problems. Empty means the chapter is left as written.
i18n
UI strings. English is the default. Russian and German cover the same keys.
ui_language()
UI language from PLOTWEAVER_LANG, or English.
tr(key, language=None)
Look up one UI string in the active language.
window
New book, progress, and result. The pipeline runs on the UI thread in the self-test and on a worker thread for a normal click, so the window can repaint.
The llama client, the model registry, and export helpers are imported inside the methods that use them. Constructing the window does not load them.
MainWindow(mock=False)
The desktop window: new book, progress, and result.
run_selftest()
Fill the form and write a one-chapter book with the mock backend.