Metadata-Version: 2.4
Name: prompt-linker
Version: 0.8.0
Summary: Ahead-of-time compiler/linker for LLM agent prompts — compose instruction sets from interchangeable parts.
Project-URL: Homepage, https://github.com/ega-ega/prompt-linker
Project-URL: Source, https://github.com/ega-ega/prompt-linker
Author: Egor Shaldov
License-Expression: MIT
License-File: LICENSE
Keywords: agent,compiler,linker,llm,pipeline,prompt
Requires-Python: >=3.11
Requires-Dist: pyyaml>=6.0
Provides-Extra: ai
Requires-Dist: anthropic<1,>=0.69; extra == 'ai'
Provides-Extra: dev
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.5; extra == 'dev'
Description-Content-Type: text/markdown

# prompt-linker

> 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

```yaml
# 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 }
```

```markdown
# 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`](./Examples/StarterTemplate)
to begin your own configuration, or read [`Examples/TestConfiguration`](./Examples/TestConfiguration)
for a fuller, runnable one.

## Usage

Run a command against a configuration directory (its ROOT). Installed via `pipx`/`uvx` the entry
point is `prompt-linker`; from a source checkout use `PYTHONPATH=src python -m prompt_linker.cli`.

```sh
prompt-linker verify  Examples/TestConfiguration                  # check coherence; writes nothing
prompt-linker compile Examples/TestConfiguration --preset team    # → compiled/ (gitignored)
prompt-linker check   Examples/TestConfiguration --security       # AI verifier (opt-in; needs [ai] extra)
```

`verify` and `compile` are deterministic and fail closed (and include a security scan); `check` is
the opt-in, model-using AI verifier (conformance, coherence, injection review). **Full command
reference: [`Docs/Commands.md`](./Docs/Commands.md).**

## Status

🚧 **Working implementation.** The deterministic linker/verifier and the opt-in AI verifier both run.
Docs: the design in [`Docs/PromptLinker.md`](./Docs/PromptLinker.md), the CLI in
[`Docs/Commands.md`](./Docs/Commands.md), verification layers in
[`Docs/Verification.md`](./Docs/Verification.md), emitted errors in [`Docs/Errors.md`](./Docs/Errors.md);
open questions and planned work in [`Roadmap/Roadmap.md`](./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](./LICENSE)
