Skip to main content

Ahead-of-time compiler/linker for LLM agent prompts — compose instruction sets from interchangeable parts.

Project description

prompt-linker

PyPI Downloads Python License: MIT

Compile an LLM agent's instruction set from interchangeable parts — the way a program is linked from objects chosen at build time.

prompt-linker is an ahead-of-time compiler/linker for agent prompts. You write a stable algorithm as skeletons with named slots, write the variable behavior as interchangeable implementations, and declare which implementation fills each slot in a build manifest. The linker inlines the chosen implementations into the skeletons and emits one flat, fully-resolved instruction that the agent runs with zero runtime indirection.

Why

Configurable agent pipelines usually rot in one of two ways:

  • inline conditionals (if mode == X …) entangle every variation into one monolith;
  • runtime resolution pays a tool-call + tokens for every slot, on every iteration.

prompt-linker pays its indirection once, in deterministic code (zero model tokens), and hands the agent a single readable artifact. "Modes" become data — named presets over a small space of bindings — not branches in the engine. Adding a new behavior is a new implementation + a manifest line; the algorithm is never edited (Open–Closed).

Concepts

Term Is
Configuration a self-contained directory (manifest + skeletons/ + contracts/) that compiles independently; a project may hold many
Contract a named, reusable signature (inputs, postcondition, invariant); declared once, with an optional default impl
Slot an occurrence of a contract in a skeleton — {{ slot: <contract-id> }}, the hole to fill
Implementation one concrete block that satisfies a contract and fills its slots
Skeleton a prompt template containing slots
Skill a deliverable bundle (a top-level subdir of skeletons/) — a convention, not required
Manifest Linker.yaml: names the configuration, binds each contract → an impl (+ named presets)
Binding / Resolution a contract → impl pair / the resolved set of them (defaults → preset → overrides)
Linker deterministic step that inlines implementations into skeletons
Verifier proves every slot is bound once and each implementation satisfies its contract

Quick look

# Linker.yaml
preset: team
overrides: { continuation: spawn-next }   # run-local contracts only
presets:
  solo: { task-source: local,   continuation: stop }
  team: { extends: solo, task-source: tracker }
# skeletons/autonomous-agent/run.md
## Phase 1 — Acquire work
{{ slot: task-source }}

prompt-linker compile --preset team → a flat compiled/<name>-<config-hash>/autonomous-agent/run.md with the tracker implementation inlined — clean text the agent reads with no hint it was assembled from parts (the output dir is content-addressed so a host can freeze a run by recording its path); provenance lives in a GENERATED header. (compile --annotated adds per-block markers for an AI verifier — a debug build, never shipped.) Copy Examples/StarterTemplate to begin your own configuration, or read Examples/TestConfiguration for a fuller, runnable one.

Install & adopt

prompt-linker is on PyPI — consume it as an installed package, not a vendored copy:

pipx install prompt-linker            # or: uvx prompt-linker …
prompt-linker init prompts/my-config  # scaffold a configuration + install a consumer skill + patch .gitignore

Use pipx or uvx — they put the prompt-linker command on your PATH (and uvx runs it without installing at all). Plain pip install prompt-linker also works, but then you manage PATH: pip drops the command in a Scripts//bin dir that is not always on it (notably with Windows Store Python). If the bare command isn't found, run it PATH-independently with python -m prompt_linker … — that always works wherever python does.

init is the one-shot way for a host repo to adopt the tool: it scaffolds a starter configuration, appends compiled/ to your .gitignore, and installs a small Claude Code skill into .claude/skills/prompt-linker/ that teaches a host agent to consume the tool (no internals). Use --skill-only to refresh just the skill after an upgrade. From a source checkout the entry point is PYTHONPATH=src python -m prompt_linker.

Usage

Run a command against a configuration directory (its ROOT):

prompt-linker verify  Examples/TestConfiguration                  # check coherence; writes nothing
prompt-linker compile Examples/TestConfiguration --preset team    # → compiled/ (gitignored)
prompt-linker deploy  Examples/DeployExample  --root .            # install/distribute a build into host paths
prompt-linker check   Examples/TestConfiguration --security       # AI verifier (opt-in; needs [ai] extra)
prompt-linker approve Examples/TestConfiguration                  # pin the corpus → chunks.lock (review gate)

Two ways to consume a build: use-in-place (compile, then point the runtime agent at the printed content-addressed path — commit nothing) or install/distribute (deploy — lay the build out into host paths another tool discovers by location, recorded in a committed deploy-receipt.json; deploy --check is the CI/pre-commit freshness gate).

verify, compile, and deploy are deterministic and fail closed (and include a security scan); check is the opt-in, model-using AI verifier (conformance, coherence, injection review).

Security — chunk-hash pinning (opt-in). prompt-linker approve records the sha256 of every source chunk (contracts/ + skeletons/) into a committed chunks.lock; verify/compile then fail closed on any drift until you review the change and re-approve. It is a tripwire, not a detector — its value is realized by a review gate (e.g. CODEOWNERS on contracts/**, skeletons/**, chunks.lock) so a corpus edit cannot land unreviewed (Docs/Verification.md §3.4).

CI / scripting. Every command but init takes --json for one machine-readable result object on stdout; compile --json exposes out_dir/config_hash as the hook a launch wrapper uses to freeze a run to its content-addressed build. Full command reference: Docs/Commands.md.

Versioning & reproducibility

prompt-linker is consumed as an installed package, never vendored — so the only lever for a reproducible build is pinning the version exactly (prompt-linker==X.Y.Z). A compiler's output can shift across versions (slot handling, the GENERATED header, advisories), so identical sources can build differently under a different tool. The bump level signals intent (see the versioning policy): MAJOR = breaking surface/format/output, MINOR = backward-compatible additions (and output-correcting fixes), PATCH = no intended output/surface change. Only an exact pin guarantees byte-identical output.

  • Find the version to pin: prompt-linker --version (also stamped in the installed skill's x-prompt-linker.version).
  • Make drift loud: record linker_version: X.Y.Z in a config's Linker.yaml (init stamps it) and verify warns when the installed CLI differs.

Status

Stable — v1.0.0 on PyPI (prompt-linker; the badge above shows the current version). As of 1.0.0 the CLI surface, the emitted formats, and the Linker.yaml schema are under SemVer. The deterministic linker/verifier, the opt-in AI verifier, host adoption (init), and both consumption modes (compile / deploy) all run; --json machine-readable output and opt-in chunk-hash pinning (approve) round out the surface. Docs: the design in Docs/PromptLinker.md, the CLI in Docs/Commands.md, verification layers in Docs/Verification.md, emitted errors in Docs/Errors.md; open questions and planned work in Roadmap/Roadmap.md.

Implementation: Python 3.11+, distributed via PyPI (pipx run prompt-linker / uvx prompt-linker). The npm name is reserved; a native JS build is deferred until there is demand for embedding the linker as a JS library.

License

MIT

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

prompt_linker-1.1.0.tar.gz (124.6 kB view details)

Uploaded Source

Built Distribution

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

prompt_linker-1.1.0-py3-none-any.whl (64.3 kB view details)

Uploaded Python 3

File details

Details for the file prompt_linker-1.1.0.tar.gz.

File metadata

  • Download URL: prompt_linker-1.1.0.tar.gz
  • Upload date:
  • Size: 124.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for prompt_linker-1.1.0.tar.gz
Algorithm Hash digest
SHA256 e5aea2c08828de46aa02fede58ec43a48a15ff34aae3d44c882a34c4e32fa07b
MD5 dd202666fdb0cf2056400c3b0f532b5d
BLAKE2b-256 f57681e17bd248dd51c94ff9a9118b5d65cdfaca66d2945d5a570b18eb7df48f

See more details on using hashes here.

File details

Details for the file prompt_linker-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: prompt_linker-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 64.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for prompt_linker-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 011a27aef00ccc768aa6372a5dbd5cf731a45096c2d3d5b69016ddc5d48ec602
MD5 57355c91a783b2a13049fb04208451a1
BLAKE2b-256 ff30943befb8739f88d7020d7355feaf1f687307979fe9973d5e2099b41a8ce8

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