Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
[![npm](https://img.shields.io/npm/v/@prompty/core?label=typescript)](https://www.npmjs.com/package/@prompty/core)
[![VS Code](https://img.shields.io/visual-studio-marketplace/v/ms-toolsai.prompty?label=vs%20code)](https://marketplace.visualstudio.com/items?itemName=ms-toolsai.prompty)

> **⚠️ v2 Alpha** — This is the v2 branch of Prompty, currently in alpha. The API, file format, and tooling are under active development and may change. Feedback welcome via [Issues](https://github.com/microsoft/prompty/issues).
> **Prompty v2** — Prompty v2 packages are available for Python, TypeScript,
> Rust, and C#. The shared `.prompty` format is aligned across runtimes by
> generated model types and conformance vectors. Feedback welcome via
> [Issues](https://github.com/microsoft/prompty/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.

Expand Down Expand Up @@ -42,7 +45,7 @@ Say hello to {{name}}.

**Python**
```bash
pip install "prompty[jinja2,openai]"
uv pip install "prompty[jinja2,openai]"
```
```python
import prompty
Expand Down Expand Up @@ -177,10 +180,10 @@ while each runtime keeps its own idiomatic implementation.
### Python

```bash
pip install "prompty[all]" # everything
pip install "prompty[jinja2,openai]" # just OpenAI
pip install "prompty[jinja2,foundry]" # Microsoft Foundry
pip install "prompty[jinja2,anthropic]" # Anthropic
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]" # Anthropic
```

```python
Expand Down
8 changes: 4 additions & 4 deletions runtime/csharp/scripts/release.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
"""Version bump and tag script for the Prompty C# NuGet packages.

Usage:
python scripts/release.py # patch: 2.0.0-alpha.8 → 2.0.0-alpha.9
python scripts/release.py --bump minor # minor: 2.0.0-alpha.8 → 2.1.0-alpha.1
python scripts/release.py --bump major # major: 2.0.0-alpha.8 → 3.0.0-alpha.1
python scripts/release.py # patch: 2.0.0 → 2.0.1
python scripts/release.py --bump minor # minor: 2.0.0 → 2.1.0
python scripts/release.py --bump major # major: 2.0.0 → 3.0.0
python scripts/release.py --version 2.0.0 # explicit version (exits prerelease)
python scripts/release.py --dry-run # show what would happen without doing it

Expand Down Expand Up @@ -40,7 +40,7 @@ def get_current_version() -> str:


def bump_version(current: str, bump: str) -> str:
# Semver prerelease: 2.0.0-alpha.8
# Semver prerelease suffix handling.
pre_match = re.match(r"^(\d+)\.(\d+)\.(\d+)-([a-z]+)\.(\d+)$", current)
stable_match = re.match(r"^(\d+)\.(\d+)\.(\d+)$", current)

Expand Down
8 changes: 4 additions & 4 deletions runtime/python/prompty/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ executes these files. Every `.prompty` file becomes a typed

```bash
# Core + Jinja2 renderer + OpenAI provider
pip install prompty[jinja2,openai]
uv pip install "prompty[jinja2,openai]"

# Core + Microsoft Foundry provider
pip install prompty[jinja2,foundry]
uv pip install "prompty[jinja2,foundry]"

# Core + Anthropic provider
pip install prompty[jinja2,anthropic]
uv pip install "prompty[jinja2,anthropic]"

# Everything (all renderers, providers, OpenTelemetry)
pip install prompty[all]
uv pip install "prompty[all]"
```

### Extras
Expand Down
8 changes: 4 additions & 4 deletions runtime/rust/scripts/release.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
"""Version bump and tag script for the prompty Rust crates.

Usage:
python scripts/release.py # patch: 2.0.0-alpha.8 → 2.0.0-alpha.9
python scripts/release.py --bump minor # minor: 2.0.0-alpha.8 → 2.1.0-alpha.1
python scripts/release.py --bump major # major: 2.0.0-alpha.8 → 3.0.0-alpha.1
python scripts/release.py # patch: 2.0.1 → 2.0.2
python scripts/release.py --bump minor # minor: 2.0.1 → 2.1.0
python scripts/release.py --bump major # major: 2.0.1 → 3.0.0
python scripts/release.py --version 2.0.0 # explicit version (exits prerelease)
python scripts/release.py --dry-run # show what would happen without doing it

Expand Down Expand Up @@ -55,7 +55,7 @@ def get_current_version() -> str:


def bump_version(current: str, bump: str) -> str:
# Semver prerelease: 2.0.0-alpha.8
# Semver prerelease suffix handling.
pre_match = re.match(r"^(\d+)\.(\d+)\.(\d+)-([a-z]+)\.(\d+)$", current)
stable_match = re.match(r"^(\d+)\.(\d+)\.(\d+)$", current)

Expand Down
6 changes: 3 additions & 3 deletions runtime/typescript/scripts/release.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
* Version bump and tag script for @prompty/* packages.
*
* Usage:
* npm run release # patch: 2.0.0-alpha.1 → 2.0.0-alpha.2
* npm run release -- --bump minor # minor: 2.0.0-alpha.2 → 2.1.0-alpha.1
* npm run release -- --bump major # major: 2.1.0-alpha.1 → 3.0.0-alpha.1
* npm run release # patch: 2.0.0 → 2.0.1
* npm run release -- --bump minor # minor: 2.0.0 → 2.1.0
* npm run release -- --bump major # major: 2.0.0 → 3.0.0
* npm run release -- --version 2.0.0 # explicit version (exits prerelease)
* npm run release -- --dry-run # show what would happen without doing it
*
Expand Down
4 changes: 2 additions & 2 deletions web/docs-examples/rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ edition = "2024"
publish = false

[dependencies]
prompty = { version = "2.0.0-alpha.8" }
prompty-openai = { version = "2.0.0-alpha.8" }
prompty = { version = "2.0.1" }
prompty-openai = { version = "2.0.1" }
serde_json = "1"
tokio = { version = "1", features = ["full"] }

Expand Down
26 changes: 13 additions & 13 deletions web/docs-examples/rust/examples/agent_tool_calling.rs
Original file line number Diff line number Diff line change
@@ -1,37 +1,37 @@
use prompty::TurnOptions;
use prompty::{AgentEvent, TurnOptions};
use serde_json::json;
use std::sync::Arc;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
prompty::register_defaults();
prompty_openai::register();

// Register tool handlers
prompty::register_tool_handler("get_weather", |args| {
prompty::register_tool("get_weather", |args: serde_json::Value| {
Box::pin(async move {
let city = args["city"].as_str().unwrap_or("unknown");
Ok(json!(format!("72°F and sunny in {city}")))
Ok(format!("72°F and sunny in {city}"))
})
});

prompty::register_tool_handler("get_time", |args| {
prompty::register_tool("get_time", |args: serde_json::Value| {
Box::pin(async move {
let timezone = args["timezone"].as_str().unwrap_or("UTC");
Ok(json!(format!("2025-01-15T10:30:00 {timezone}")))
Ok(format!("2025-01-15T10:30:00 {timezone}"))
})
});

// Load agent and run with tool-calling loop
let agent = prompty::load("weather_agent.prompty")?;

let options = TurnOptions {
max_iterations: Some(10),
events: Some(Arc::new(|event| {
println!("Agent event: {event:?}");
})),
..Default::default()
};
let options = TurnOptions::builder()
.max_iterations(10)
.on_event(Box::new(|event| {
if let AgentEvent::Status(message) = event {
println!("Agent status: {message}");
}
}))
.build();

let result = prompty::turn(
&agent,
Expand Down
16 changes: 2 additions & 14 deletions web/docs-examples/rust/examples/streaming.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use prompty::StreamChunk;
use serde_json::json;

#[tokio::main]
Expand All @@ -10,20 +9,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let agent = prompty::load("chat.prompty")?;
let messages = prompty::prepare(&agent, Some(&json!({ "question": "Tell me a joke" }))).await?;

// Run returns a PromptyStream when stream: true is set
// When stream: true is set, run consumes the stream and returns accumulated text
let result = prompty::run(&agent, &messages).await?;

// Process streaming chunks
let stream = prompty::from_structured_value::<prompty::PromptyStream>(&result)?;
prompty::consume_stream_chunks(stream, |chunk| match chunk {
StreamChunk::Text(text) => print!("{text}"),
StreamChunk::Thinking(thought) => print!("[thinking] {thought}"),
StreamChunk::Tool(tc) => println!("[tool call] {}: {}", tc.name, tc.arguments),
StreamChunk::Error(message) => eprintln!("[error] {message}"),
StreamChunk::Failure(failure) => eprintln!("[error] {}", failure.message()),
})
.await;

println!();
println!("{result}");
Ok(())
}
14 changes: 7 additions & 7 deletions web/docs-examples/typescript/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 4 additions & 12 deletions web/src/content/docs/core-concepts/streaming.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -209,22 +209,14 @@ user:
</TabItem>
<TabItem label="Rust">
```rust
use prompty::{StreamChunk, PromptyStream, consume_stream_chunks};

let agent = prompty::load("chat.prompty")?;
let inputs = serde_json::json!({"question": "Tell me a joke"});
let messages = prompty::prepare(&agent, Some(&inputs)).await?;
let result = prompty::run(&agent, &messages).await?;

// Process streaming chunks
let stream = prompty::from_structured_value::<PromptyStream>(&result)?;
consume_stream_chunks(stream, |chunk| match chunk {
StreamChunk::Text(text) => print!("{text}"),
StreamChunk::Thinking(thought) => print!("[thinking] {thought}"),
StreamChunk::Tool(tc) => println!("[tool] {}: {}", tc.name, tc.arguments),
StreamChunk::Error(err) => eprintln!("[error] {err}"),
}).await;
println!();
// Rust run() consumes a streaming provider response and returns
// the accumulated text result.
let result = prompty::run(&agent, &messages).await?;
println!("{result}");
```
</TabItem>
</Tabs>
Expand Down
4 changes: 2 additions & 2 deletions web/src/content/docs/core-concepts/tracing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ and more.
<Tabs>
<TabItem label="Python">
```bash
pip install prompty[otel]
uv pip install "prompty[otel]"
```
</TabItem>
<TabItem label="TypeScript">
Expand All @@ -304,7 +304,7 @@ and more.
</TabItem>
<TabItem label="C#">
```bash
dotnet add package Prompty.Core --prerelease
dotnet add package Prompty.Core
# OTel support is built into Prompty.Core
```
</TabItem>
Expand Down
8 changes: 2 additions & 6 deletions web/src/content/docs/getting-started/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,9 @@ rendered instructions that are parsed into chat messages.
</TabItem>
<TabItem label="C#">
```bash
dotnet add package Prompty.Core --prerelease
dotnet add package Prompty.OpenAI --prerelease # or Prompty.Foundry, Prompty.Anthropic
dotnet add package Prompty.Core
dotnet add package Prompty.OpenAI # or Prompty.Foundry, Prompty.Anthropic
```

<Aside type="note">
C# packages are in **alpha preview**. Install with `--prerelease` to get the latest version.
</Aside>
</TabItem>
<TabItem label="Rust">
```bash
Expand Down
4 changes: 2 additions & 2 deletions web/src/content/docs/how-to/anthropic.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ import { Aside, Tabs, TabItem } from '@astrojs/starlight/components';
</TabItem>
<TabItem label="C#">
```bash
dotnet add package Prompty.Core --prerelease
dotnet add package Prompty.Anthropic --prerelease
dotnet add package Prompty.Core
dotnet add package Prompty.Anthropic
```
</TabItem>
<TabItem label="Rust">
Expand Down
4 changes: 2 additions & 2 deletions web/src/content/docs/how-to/foundry.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ import { Aside, Tabs, TabItem } from '@astrojs/starlight/components';
</TabItem>
<TabItem label="C#">
```bash
dotnet add package Prompty.Core --prerelease
dotnet add package Prompty.Foundry --prerelease
dotnet add package Prompty.Core
dotnet add package Prompty.Foundry
```
</TabItem>
<TabItem label="Rust">
Expand Down
4 changes: 2 additions & 2 deletions web/src/content/docs/how-to/openai.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ import { Aside, Tabs, TabItem } from '@astrojs/starlight/components';
</TabItem>
<TabItem label="C#">
```bash
dotnet add package Prompty.Core --prerelease
dotnet add package Prompty.OpenAI --prerelease
dotnet add package Prompty.Core
dotnet add package Prompty.OpenAI
```
</TabItem>
<TabItem label="Rust">
Expand Down
10 changes: 5 additions & 5 deletions web/src/content/docs/implementation/csharp.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@ implementations: **Renderer → Parser → Executor → Processor**.

## Installation

All packages are available on NuGet at version **2.0.0-alpha.6**.
All packages are available on NuGet at version **2.0.0**.

```bash
# Core — required
dotnet add package Prompty.Core --prerelease
dotnet add package Prompty.Core

# Pick one or more providers
dotnet add package Prompty.OpenAI --prerelease
dotnet add package Prompty.Foundry --prerelease
dotnet add package Prompty.Anthropic --prerelease
dotnet add package Prompty.OpenAI
dotnet add package Prompty.Foundry
dotnet add package Prompty.Anthropic
```

| Package | Description |
Expand Down
Loading
Loading