Initial CRAN release.
rank_records() scores a corpus with an ensemble of
open-source LLMs served locally by Ollama. Every per-call score is
cached under the project’s cache directory, keyed by
digest(list(criteria_hash, model, replicate, id, temperature)).
An interrupted run resumes from the cache on the next call. Cache writes
are atomic (temp file + rename) so a crash mid-write can’t leave a
truncated file behind.on_score callback for streaming partial-run
progress into a UI without editing rank_records()
itself.default_ensemble() returns the four-LLM mean ensemble
reported as the universal ranker in Spillias et al. (2026)
(gemma3:27b, gpt-oss:20b,
mistral-small3.2:24b,
qwen3:30b-a3b-instruct-2507; three replicates each at
temperature 0.7).default_ensemble_light() returns a laptop-friendly
alternative (gemma3:4b, llama3.2:3b,
qwen3:4b, mistral:7b; ~10 GB total). Slightly
less accurate than the paper ensemble but runs on 8 GB of RAM.custom_ensemble() accepts any Ollama-served model,
replicate count, and aggregator (mean, median,
max, topk_mean).clear_cache() invalidates cached scores by model or
wholesale so a bad run can be re-done without discarding the good
models’ work.estimate_runtime() gives an order-of-magnitude
wall-clock estimate scaled by model size and hardware profile (GPU / CPU
/ throttled).plan_screening() applies the SAFE stopping rule at the
paper’s advance-choosable default (target recall 0.95, minimum coverage
0.50, run length 50, spot-check n = 200) and returns per-gate
diagnostics (which gate binds, where each gate would fire).read_records() accepts data frames, CSV, TSV, XLSX, and
RIS exports from Zotero / EndNote / Mendeley / Web of Science.find_duplicates() flags DOI matches, normalised-title
matches, and (optionally, when stringdist is installed)
fuzzy-title near-duplicates.define_criteria() builds a scope-plus-inclusions
object.build_prompt() renders the per-criterion partial-credit
prompt used in the paper. Point weights and the three scale bands
auto-scale with the number of criteria, so three-, four-, or
five-criterion reviews all sum to 100.launch_app() opens a seven-tab workflow (Setup / Corpus
/ Criteria / Rank / Plan / Screen / Report). All user artefacts persist
under tools::R_user_dir("screenllm", "data") so projects
survive across R sessions. Refuses to run as root and falls back to a
URL-only launch on headless (no-DISPLAY) systems.launch_screening_app() provides the standalone
incremental screening UI for teams working from an already-ranked
list.backend_ollama() (default): local HTTP client, no API
keys, no network egress. Fails fast on HTTP 4xx (bad model tag / auth)
and surfaces the actual error message. Handles reasoning-model families
(gpt-oss, deepseek-r1,
qwen3-thinking, phi4-reasoning) that misbehave
under Ollama’s grammar- constrained JSON mode. Suppresses
chain-of-thought via think = FALSE; recovers JSON from
mixed text via a balanced- braces fallback parser.backend_mock(): deterministic mock backend used in
examples, tests, and vignettes so nothing depends on Ollama being
installed.install_prereqs(preset = "light" | "paper" | "none")
walks a fresh machine through Ollama installation, daemon startup, and
model pulls. Detects the OS and proposes an OS-appropriate install
command (brew / winget / official install
script) which the user must confirm before it runs. Safe to re-run; a
no-op if everything is already in place.check_setup(), ollama_health(),
pull_model(), ollama_catalog() exposed for
finer-grained control.detect_gpu() + gpu_status(): hardware
detection (Apple Silicon / NVIDIA / AMD) plus live clock / VRAM / power
query, including a “throttled” flag that catches the laptop-on-battery
case where a dGPU reports 99 % utilisation but runs at idle clocks.start_rank_job(), rank_job_status(),
rank_job_cancel() spawn ranking jobs in a background R
process (via callr) so Shiny stays responsive; the worker
writes throttled progress and per-call scores back through a per-project
file.start_pull_job() / pull_job_status() /
pull_job_cancel() do the same for Ollama model
downloads.summarise_screening() summarises ranked-vs-screened
outcomes and reports SAFE-derived recall bounds.audit_disagreements() highlights strong LLM-vs-human
disagreements for reviewer follow-up. Tolerates records that carry a
pre-existing human_decision column (baked-in ground truth)
by stripping decision columns before the join.export_worksheet() writes an Excel workbook for offline
screening.export_report() renders a self-contained HTML report
(open in a browser and print-to-PDF to archive).