Skip to main content

Version control for LLM prompts. Zero dependencies, works offline, embeds in any project.

Project description

Graver

CI Python License: MIT

Version control for LLM prompts. Zero dependencies, works offline, embeds in any project.


Why graver?

vs. cloud-based prompt management platforms

Most prompt management tools are cloud services: they require a signup, an API key, and your prompts leave your machine. They're built around dashboards, collaboration features, and A/B testing infrastructure, useful at scale, but heavy when you just want to track how a prompt evolves.

Graver is the opposite: install it, import it, start versioning. No server, no account, no data leaving your codebase. It's fast to set up, fast to use, and stays out of your way.

vs. just using git

Git tracks files. Graver tracks prompt content - independently of your code.

  • Save a new version from inside your code without creating a commit
  • Pin one version as your stable "main" while others keep evolving
  • Compare prompt changes in isolation, not buried in a diff full of source code
  • Works inside notebooks, scripts, and pipelines without touching your repo

If your prompts live in .txt files committed alongside code, you'll feel the friction immediately: every prompt tweak becomes a commit, rollback means git checkout, and git diff mixes logic changes with wording changes.

vs. building it yourself

Prompt versioning looks simple until you handle edge cases: version numbering after deletions, pinning a canonical version independently of the latest, history that survives partial deletions. Graver handles all of this. One pip install, zero boilerplate.


Installation

pip install graver

Quick Start

from graver import Prompt

p = Prompt("system")

p.save("You are a helpful assistant.")
p.save("You are an expert analyst. Be concise and data-driven.")

# See what changed
print(p.changes())

# Pin a stable version
p.set_main("v1")

# Always retrieve the pinned version, regardless of newer saves
content = p.get_main()

CLI

gr save system prompt.txt        # save a file as a new version
gr log system                    # show version history
gr show system v2                # show a specific version
gr changes system                # diff the last two versions
gr set-main system v1            # pin a version as main
gr get-main system               # print the pinned version
gr list                          # list all saved prompts
gr delete system v2              # delete a version
gr delete-prompt system          # delete a prompt entirely

Use --base-dir to point to a custom storage directory:

gr --base-dir ./prompts log system

How It Works

Every Prompt writes to a .graver/ folder in your working directory. No database, no server, no configuration.

.graver/
  system/
    v1.txt
    v2.txt
    history.json   ← version index with timestamps
    main.json      ← pointer to the pinned version

Versions are never overwritten, only explicitly deleted. Version numbers never collide even if you delete intermediate versions.


API Reference

Prompt(name, base_dir=".graver")

Parameter Type Description
name str Unique identifier for this prompt.
base_dir str Storage root. Defaults to .graver in the working directory.

Methods

Method Returns Description
save(content) str Save a new version. Returns the version string (e.g. "v3").
save_from_file(filepath) str Read from a file and save as a new version.
get(version=None) str Get a version's content. Defaults to latest.
log() list[dict] Full version history with version, timestamp, is_main.
set_main(version) None Pin a version as the canonical main.
get_main() str Get the content of the pinned main version.
changes(v1=None, v2=None) str Formatted diff. Defaults to last two versions.
diff(v1, v2) dict Raw diff with added, removed, unchanged line lists.
show(version=None) str Content with formatted header. Defaults to latest.
delete_version(version) None Delete a specific version. Clears main pointer if it was main.
delete_prompt() None Delete this prompt and all its versions.
Prompt.list_all(base_dir) list[str] List all prompt names in the given directory.

Exceptions

Exception Raised when
GraverError Base class for all graver errors.
PromptNotFoundError Prompt name or file does not exist.
VersionNotFoundError Version string does not exist.
StorageError A file system operation fails.

Examples

See examples/ for usage with OpenAI, Anthropic, and LangChain.


Contributing

Contributions are welcome. See CONTRIBUTING.md for setup instructions, code standards, and the PR process.

To report a bug or request a feature, open an issue.


License

Released under the MIT License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

graver-0.1.0.tar.gz (14.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

graver-0.1.0-py3-none-any.whl (10.6 kB view details)

Uploaded Python 3

File details

Details for the file graver-0.1.0.tar.gz.

File metadata

  • Download URL: graver-0.1.0.tar.gz
  • Upload date:
  • Size: 14.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.0

File hashes

Hashes for graver-0.1.0.tar.gz
Algorithm Hash digest
SHA256 cda3209df9fb0c372998be4290226a964d644bb9bf24b0d7473e89605da48c46
MD5 0702c8cb4624bd709a905a063425d731
BLAKE2b-256 a9fb1f6ccba8fa7af6b16e885209777cef911ed1bbc9067fd98500d8108bfc35

See more details on using hashes here.

File details

Details for the file graver-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: graver-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 10.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.0

File hashes

Hashes for graver-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4f42da213c30b3e592852ef0edf8209f5013e3a2c6a5def09697a9cc7f697040
MD5 d595f6775552e6010c286a461d91588e
BLAKE2b-256 dfaa7f5489d763e9d98cf640d04aa44649f5d12dc3c6c541dc7f80c9b27f1bf2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page