Skip to content
Prompting Press v0.2

Prompting Press

Prompting Press is a typed, variant-aware prompt-template library for Rust, Python, and TypeScript. It parses, validates, and renders prompt text and returns content hashes for each render. All three languages bind one shared Rust engine, so a rendered prompt is byte-identical across them.

  • A focused template language (MiniJinja): interpolation ({{ name }}), conditionals ({% if %}), and loops ({% for %}). Includes, macros, and inheritance are excluded so the agreement check stays sound. See Template features.
  • Named variants. A prompt can carry alternative bodies (concise, formal, …) that share the same declared variables. A variant is selected by name at render (variant: "formal"); selection is caller-owned. See Variants.
  • Declared, typed variables. Each prompt declares its variables with a type and a trusted boolean. The shape is one JSON Schema, code-generated into a Rust struct, Pydantic model, and TypeScript type.
  • Agreement check. A template that references a variable the prompt never declared is rejected at construction (and surfaced as a CI lint via check()) rather than rendering to a silent empty string.
  • Native value validators. Render values are validated by each language’s own system — garde (Rust), Pydantic (Python), Zod (TypeScript) — before any templating runs. A variable can be marked validation_required to require that a validator covers it (enforced at construction in Python and TypeScript, at compile time in Rust).
  • trusted flag and an advisory guard. A variable is declared trusted: true or trusted: false. When the guard is enabled at render, trusted: false values are delimited in the rendered body with <untrusted>…</untrusted> markers, and a separate advisory string is returned for the downstream model. See The advisory guard.
  • Content hashes. Every render returns a template_hash and a render_hash (SHA-256), so a trace can identify which template produced which output. Both are byte-identical across the three languages.
  • Opaque metadata. A prompt and each variant carry an optional metadata map (model hints, tags, an output_model reference, selection labels). The library stores and echoes metadata; it does not interpret it, with one documented exception: the presence of a guard key suppresses the check() guard advisory.
  • An immutable Prompt. Construct it from a shape object or from YAML, JSON, or TOML text, then render, read its source, or check() it. There are no setters; derive produces a new Prompt by shallow-replacing a field and re-validating the whole. See Getting started.
  • Multi-message composition. Several Prompt objects (each with its own variables) compose into an ordered, role-tagged [{role, text}] sequence. There is no registry; the objects are passed directly. See Composition.
  • One engine, three languages. Rust, Python, and TypeScript bind the same Rust core, so rendering, validation behavior, and hashes are identical across them. The idiom is native per language; the result is not.
  • It performs no I/O. The caller reads the prompt text (or fetches it) and passes it to from_yaml, from_json, or from_toml; the library never touches the filesystem, a database, or the network.
  • It never calls an LLM, assembles a provider request body, counts tokens, or parses model output.
  • Its untrusted-input guard is advisory text, not enforcement. It names untrusted fields for the downstream model; it does not sanitize values, and the library has no model of its own.
  • Prompts stop being string literals scattered through your code. Define them as typed files (or objects) instead of inline strings buried in application logic — so a prompt gets the same diff, review, and history any other source file does.
  • You load prompts from wherever you already keep them. Prompting Press does no I/O: you hand it the definition — from a file, a database, an object store, or a string in code — and it renders. There is no storage adapter to adopt and nothing to lock into.
  • You change prompts without redeploying. Named variants let you keep parallel versions of a prompt and pick one at render time — for migrating v1→v2, honoring a per-user preference, serving different languages, or switching tone — without editing code for each.
  • Prompt typos fail your build, not production. The agreement check catches a template that references a variable the prompt never declared — before you ship, rather than as a silently empty render at runtime.
  • The same prompt renders identically on your frontend and backend. One shared engine means a prompt produces byte-identical text from Rust, Python, and TypeScript — no per-language fork of your prompt library.
  • You can prove what you sent. Every render returns a content hash of the template and the output, so a trace can pin down exactly which prompt text produced a given result.

For how Prompting Press sits alongside an agent framework, see Integrations.

See Getting started for a per-language walkthrough, or the API reference.

docs current as of 0.2.0