Prompty v2 — Prompty v2 packages are available for Python, TypeScript, Rust, and C#. The shared
.promptyformat is aligned across runtimes by generated model types and conformance vectors. Feedback welcome via Issues.
Prompty is a markdown file format (.prompty) for LLM prompts. Write your prompt once — run it from VS Code or a language runtime that shares Prompty's generated model and conformance vectors.
---
name: greeting
model:
id: gpt-4o-mini
provider: openai
connection:
kind: key
apiKey: ${env:OPENAI_API_KEY}
template:
format:
kind: jinja2
parser:
kind: prompty
---
system:
You are a friendly assistant.
user:
Say hello to {{name}}.
Python
uv pip install "prompty[jinja2,openai]"import prompty
result = prompty.invoke("greeting.prompty", inputs={"name": "Jane"})
print(result)TypeScript
npm install @prompty/core @prompty/openaiimport { invoke } from "@prompty/core";
import "@prompty/openai";
const result = await invoke("greeting.prompty", { name: "Jane" });
console.log(result);VS Code — open the .prompty file and press F5.
Prompty's openai provider can also target OpenAI-compatible control planes,
gateways, or self-hosted model servers by setting model.connection.endpoint.
The prompt asset stays portable: switch the endpoint and key at runtime without
changing the prompt body.
---
name: governed-greeting
model:
id: gpt-4o-mini
provider: openai
connection:
kind: key
endpoint: ${env:OPENAI_BASE_URL:https://api.openai.com/v1}
apiKey: ${env:OPENAI_API_KEY}
template:
format:
kind: jinja2
parser:
kind: prompty
---
system:
You are a careful assistant.
user:
Say hello to {{name}}.
For example, to route through Tuning Engines:
export OPENAI_BASE_URL=https://api.tuningengines.com/v1
export OPENAI_API_KEY=sk-te-your-inference-keyThis keeps the .prompty file unchanged while the endpoint provides routing,
policy, usage tracking, or trace correlation around OpenAI-compatible calls.
Prompty v2 keeps the prompt asset simple, then adds a shared agentic turn
runtime when your app needs tools, memory, and runtime controls. Define tools in
frontmatter, bind the actual functions in host code, and call turn() instead
of invoke() when the model should loop through tool calls before returning a
final answer.
- Tool loop — execute model-requested tools, append tool results, and retry until the model returns a final response.
- Runtime controls — guardrails, cancellation, steering messages, retries, and event callbacks live in code instead of prompt text.
- Context and memory — thread inputs, context budgets, compaction, and memory-aware turns keep long conversations portable across runtimes.
- Observable agents — every render, parse, model call, tool call, and final result can flow into traces.
from prompty import turn
result = turn(
"agent.prompty",
inputs={"question": "What's the weather in Seattle?"},
tools={"get_weather": get_weather},
)Prompty normalizes text files to LF line endings via .gitattributes. Enable the
repo hook once per clone so staged files are normalized before each commit and
whitespace errors are blocked locally:
git config core.hooksPath .githooksBefore opening a PR, you can run the same core hygiene checks directly:
git diff --check
git ls-files --eol | grep 'w/crlf'The v2 extension includes a connections sidebar, live preview, chat mode, and a redesigned trace viewer.
Right-click in the explorer → New Prompty to scaffold a new prompt file.
See the rendered prompt with live markdown rendering and template interpolation as you type.
Manage model connections from the sidebar — add OpenAI, Microsoft Foundry, or Anthropic endpoints, set a default, and browse available models.
Thread-enabled prompts automatically open an interactive chat panel with tool calling support.
Every execution generates a .tracy trace file. Click to inspect the full pipeline — render, parse, execute, process — with timing and payloads.
Prompty runtimes are kept aligned by shared, generated model types and canonical cross-runtime conformance vectors. The vectors own observable behavior — load, render, parse, provider wire shape, response processing, agent/tool behavior, memory behavior, and live provider acceptance when credentials are available — while each runtime keeps its own idiomatic implementation.
| Runtime | Packages |
|---|---|
| Python | prompty |
| TypeScript | @prompty/core, @prompty/openai, @prompty/foundry, @prompty/anthropic |
| Rust | prompty, prompty-openai, prompty-foundry, prompty-anthropic |
| C# | Prompty.Core, Prompty.OpenAI, Prompty.Foundry, Prompty.Anthropic |
| Java | com.microsoft.prompty packages |
| Go | github.com/microsoft/prompty/runtime/go/prompty |
| Swift | Prompty, PromptyOpenAI, PromptyFoundry, PromptyAnthropic |
uv pip install "prompty[all]" # everything
uv pip install "prompty[jinja2,openai]" # just OpenAI
uv pip install "prompty[jinja2,foundry]" # Microsoft Foundry
uv pip install "prompty[jinja2,anthropic]" # Anthropicimport prompty
# Full pipeline: load → render → parse → execute → process
result = prompty.invoke("my-prompt.prompty", inputs={...})
# Step-by-step
agent = prompty.load("my-prompt.prompty")
messages = prompty.prepare(agent, inputs={...})
result = prompty.run(agent, messages)
# Async
result = await prompty.invoke_async("my-prompt.prompty", inputs={...})See runtime/python/prompty/README.md for full API docs.
npm install @prompty/core @prompty/openai # OpenAI
npm install @prompty/core @prompty/foundry # Microsoft Foundry
npm install @prompty/core @prompty/anthropic # Anthropicimport { load, prepare, run, invoke } from "@prompty/core";
import "@prompty/openai"; // registers the provider
// Full pipeline
const result = await invoke("my-prompt.prompty", { name: "Jane" });
// Step-by-step
const agent = await load("my-prompt.prompty");
const messages = await prepare(agent, { name: "Jane" });
const result = await run(agent, messages);See runtime/typescript/packages/core/README.md for full API docs.
The additional runtimes use the same .prompty assets and generated model
contracts, with runtime-specific package managers and provider registration.
See the language folders under runtime/ for package-specific APIs,
test commands, and live-provider setup.
A .prompty file has two parts: YAML frontmatter (model config, inputs, tools) and a markdown body (the prompt with role markers and template syntax).
---
name: my-prompt
model:
id: gpt-4o
provider: foundry
connection:
kind: key
endpoint: ${env:AZURE_OPENAI_ENDPOINT}
apiKey: ${env:AZURE_OPENAI_API_KEY}
options:
temperature: 0.7
inputs:
- name: question
kind: string
default: What is the meaning of life?
tools:
- name: get_weather
kind: function
description: Get the current weather
parameters:
- name: location
kind: string
template:
format:
kind: jinja2
parser:
kind: prompty
---
system:
You are a helpful assistant.
user:
{{question}}
Lines starting with system:, user:, or assistant: define message boundaries.
Jinja2 ({{variable}}, {% if %}, {% for %}) or Mustache ({{variable}}, {{#section}}).
| Syntax | Purpose |
|---|---|
${env:VAR} |
Environment variable (required) |
${env:VAR:default} |
With fallback value |
${file:path.json} |
Load file content from the prompt directory tree |
${file:...} references are scoped to the containing .prompty file's directory by default. Host applications can opt into additional allowed roots through runtime load options; prompts cannot grant themselves broader filesystem access.
Prompty v1 files are automatically migrated with deprecation warnings. See the Python README for details.
See SUPPORT.md for help and CODE_OF_CONDUCT.md for community guidelines.
To release a new version, see RELEASING.md.




