Two surfaces, one AST.
promptel sits between your application and the provider SDK. The DSL and YAML both parse to the same AST, which is bound, expanded, and dispatched to whichever provider you pick at call time.
authoring surface one AST execution
───────────────── ─────── ─────────
reviewer.prompt ─┐
(Chevrotain) ├─▶ PromptAST ──bind──▶ typed params
reviewer.yml ───┘ - meta │
(js-yaml) - params expand technique blocks
- body (CoT / ReAct / …)
▲ - technique │
│ - constraints apply constraints
FormatConverter - harmony + harmony channels
promptToYaml │ │
yamlToPrompt ▼ ▼
createProvider ──▶ ┌─────────────────┐
│ openai / claude │
│ groq (SDKs) │
└─────────────────┘
│
structured result
(+ Harmony channels) One AST, two front doors
The .prompt DSL is parsed by a Chevrotain grammar; the YAML surface is parsed by js-yaml. Both produce the same PromptAST — meta, context, params, body, constraints, output, hooks — and execute identically. FormatConverter (promptToYaml / yamlToPrompt) moves losslessly between them, so you can review in the DSL and let tooling consume the YAML.
Binding before dispatch
Params are declared with types, optionality, and defaults. When you call executePrompt(src, params, opts), promptel binds the supplied values against the declared params and refuses to proceed if a required param is missing or mistyped — a whole class of failures caught before a token is sent.
Techniques are AST nodes
A technique like chainOfThought or reAct is a node inside body.technique, not a string convention. At execution the node is expanded into the concrete instructions the provider sees, while the source stays legible. Because the technique is structured, reviewers and tooling can reason about it directly.
The provider abstraction
createProvider is a factory over the official OpenAI, Anthropic, and Groq SDKs. Selecting { provider: "claude" } swaps the backend without touching the prompt. A harmony block declares reasoning effort and channels; multi-channel responses come back as structured fields on the result rather than prose to parse.
What promptel is not
promptel does not host a backend or inference proxy, does not ship a vector store or RAG framework, is not an eval harness (it integrates with yours), and is not an agent runtime. It is a small, declarative layer for authoring and executing prompts — nothing more.
See the surfaces side by side
The quickstart writes a real prompt; the glossary defines every block above.