model-language (Ruby)
Ruby bindings for model-language — a typed, safe template language for AI-agent prompts. Runs the exact same engine as the JavaScript/TypeScript package via an embedded WebAssembly module: byte-for-byte identical output, guaranteed by a shared conformance suite.
▶ Live demo — try the language in a Tiptap editor (live validation, autocomplete, real-time render), powered by the same engine.
Filters format values — dates, numbers, text:
{{ user.created_at | date: "MMM D, YYYY" }} → Jul 5, 2026
{{ user.created_at | date: "h:mm A", "Europe/Kyiv" }} → 5:37 PM
{{ user.last_seen | time_ago }} → 3 days ago
require "model_language"
engine = ModelLanguage::Engine.new
out = engine.render(
"Hi {{ user.name | default: 'there' }}!",
data: { "user" => { "name" => "Vasyl" } }
)
puts out["text"] # => "Hi Vasyl!"
Directives embed machine-readable constraints in a prompt. They are stripped from
the rendered text and returned in directives:
src = <<~SRC
Help with billing.
{{verify_before: payments}}
{{identity: contact.email == payment.email}}
Greet {{contact.first_name | default: "there"}}.
SRC
out = engine.render(
src,
data: { "contact" => { "first_name" => "Vasyl" } },
schema: [
{ "path" => "contact.email", "type" => "string" },
{ "path" => "contact.first_name", "type" => "string" },
]
)
puts out["text"] # => "Help with billing.\n\nGreet Vasyl."
puts out["directives"].map { |d| d["name"] } # => ["verify_before", "identity"]
render(template, data:, schema:, options:)→{"text", "warnings", "resolvedBranches", "directives", "tokenEstimate"}validate(template, schema:, options:)→{"diagnostics", "maxTokenEstimate"}parse(template)→{"ast", "diagnostics"}
Never raises for template problems — they degrade to empty output plus a warning.
Pass options: { "now" => epoch_ms } for datetime filters.