dotprompt_dart
A Dart package that treats .prompt
files as executable units for LLM
interactions, providing schema validation, template rendering, and model
configuration management. This package does not execute a .prompt
file by
itself, but support for .prompt files is available in
dartantic_ai as of v0.3.0.
The dotprompt_dart package is modeled after Google's dotprompt library. Google's implementation supports Go, Java, Javascript and Python, whereas this implementation supports Dart. Also, Google's implementation is used as part of the implementation for GenKit, which also supports those other languages, but not Dart.
Unlike Google's implementation, this implementation doesn't do the execution of model prompts; instead, it uses dartantic_ai for the execution. You can absolutely use dotprompt_dart without dartantic_ai by simply using the schemas, model parameters, template expansion features, etc. and then feed all of that data into the model of your choice. That's what dartantic_ai uses it for.
Both Google's implementation and mine are based on the dotprompt
specification. There are
100+ tests currently attempting to be faithful to that specification, most of
them dedicated to the successful conversion of the Pico Schema to a JSON Schema
object. Pico Schema is a handy shorthand syntax when compared against the JSON
Schema spec, but for use in Dart code, a JsonSchema
object is much more useful
and the one from the json_schema package
particularly so. No matter which you use -- Pico Schema or JSON Schema -- you're
going to get out a JsonSchema
object for your use.
Features
- Prompt File Support: Parse and execute
.prompt
files with YAML front-matter and Handlebars templates - Schema Validation: Built-in support for Pico Schema and JSON Schema for input/output validation
- Model Configuration: Manage model settings through front-matter configuration
- Type-Safe: The generated JSON Schema can be used to validate input to the template rendering as well as to provide type info for model output
- Extension Support: Custom configuration through namespaced keys (e.g.,
myext.temperature
)
Getting Started
Add dotprompt_dart
to your pubspec.yaml
:
dependencies:
dotprompt_dart: ^0.1.0
Usage
- Create a
.prompt
file with front-matter and template:
---
name: greet
model: gemini-2.0-pro
input:
schema:
properties:
name: string, The name of the person to greet
output:
schema:
type: object
properties:
greeting:
type: string
description: The generated greeting
required: [greeting]
myext.description: A simple greeting prompt
myext.temperature: 0.7
---
Hello {{name}}! How are you today?
- Load and use the prompt in your Dart code:
import 'package:dotprompt_dart/dotprompt_dart.dart';
void main() async {
// Load from file
final greet = await DotPrompt.file('prompts/greet.prompt');
// Or load from string
final promptString = '...';
final greetFromString = DotPrompt(promptString);
// Render the template
final output = greet.render({'name': 'Chris'});
print(output); // Hello Chris! How are you today?
// Access front-matter metadata
print(greet.frontMatter.name); // greet
print(greet.frontMatter.model); // gemini-2.0-pro
// Use this info to feed your prompt execution library of choice
...
}
Schema Support
The package provides flexible schema validation through two approaches:
Pico Schema
Pico Schema is a simplified, YAML-friendly schema syntax that is automatically converted to JSON Schema. You can use it for more readable schema definitions:
input:
schema:
properties:
name: string, The name of the user
age?: integer, The age in years # Optional field with ?
settings(object): # Type annotation with ()
theme: [light, dark], Theme preference # Enum using []
notifications: boolean
tags(array): string, List of user tags # Array type
(*): any # Wildcard for additional properties
JSON Schema
You can also use standard JSON Schema syntax directly. The package detects this
by the presence of a top-level type
field which short-circuits the Pico Schema
parsing to "eject" your schema as JSON Schema:
input:
schema:
type: object
properties:
name:
type: string
description: The name of the user
age:
type: [integer, "null"] # Optional field using union type
settings:
type: object
properties:
theme:
type: string
enum: [light, dark]
notifications:
type: boolean
tags:
type: array
items:
type: string
additionalProperties: true # Equivalent to (*): any
Schema Detection and Conversion
Both Pico Schema and JSON Schema result in a valid JsonSchema
object that can
be used for:
- Input validation before template rendering
- Output validation after LLM responses
- Type-safe code generation (upcoming feature)
Input Validation and Defaults
The package validates input data against the schema during template rendering. You can also provide default values that are used when fields are not specified in the input:
input:
schema:
type: object
properties:
name:
type: string
greeting:
type: ["string", "null"] # Optional field that can be null
age:
type: integer
minimum: 0
required: [name] # Only name is required
default:
greeting: "Hello" # Used when greeting is not provided
When rendering a template:
- Default values are merged with provided input (input values take precedence)
- The combined input is validated against the schema
- If validation fails, a
ValidationException
is thrown with detailed error messages - If validation passes, the template is rendered with the combined input
For example:
final prompt = DotPrompt(promptString);
// Uses default greeting "Hello"
prompt.render({'name': 'World'}); // => "Hello World!"
// Overrides default greeting
prompt.render({'name': 'World', 'greeting': 'Hi'}); // => "Hi World!"
// Throws ValidationException - missing required 'name'
prompt.render({'greeting': 'Hi'});
Handlebar Implementation Shortcomings
The template expansion used in the current version of dotprompt_dart is based on the mustache_template package. It's a very capable and full-featured template expansion library, but unfortunately it is not spec-compliant.
Here's a list of the current short-comings that I know about:
Built-in Handlebars Helpers
#if
conditional blockselse
blocks#unless
blocks#each
iteration with@index
,@first
,@last
support
Dotprompt Helpers
json
helper for JSON serializationrole
helper for multi-message promptshistory
helper for conversation contextmedia
helper for image contentsection
helper for content positioning
Custom Helpers
- Basic helpers with positional args
- Named argument support
- Block helpers
- Context access
- Error handling
Context Variables
@metadata
access to prompt configuration@root
context reference- Message history access via
@metadata.messages
Additional Information
Contributing
Contributions are welcome! Submit your issues or your PRs today!
Libraries
- dotprompt_dart
- A library for working with .prompt files that contain structured prompts for LLMs.