1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
//! Render Hugging Face `chat_template` (Jinja2) strings the way Python
//! `transformers.apply_chat_template` does.
//!
//! This crate emits a **prompt string**. Turning it into token IDs is the caller's job
//! (`tokenizers`, `tiktoken-rs`, …) — keeping that boundary is deliberate.
//!
//! ```
//! use hf_chat_template::ChatTemplate;
//! use minijinja::context;
//!
//! let tmpl = ChatTemplate::from_str(
//! "{% for m in messages %}<|{{ m.role }}|>{{ m.content }}\n{% endfor %}\
//! {% if add_generation_prompt %}<|assistant|>{% endif %}",
//! ).unwrap();
//!
//! let out = tmpl.render_value(context! {
//! messages => vec![
//! context!{ role => "user", content => "hi" },
//! ],
//! add_generation_prompt => true,
//! }).unwrap();
//! assert_eq!(out, "<|user|>hi\n<|assistant|>");
//! ```
//!
//! ## Special tokens & BOS doubling
//! Templates that emit `{{ bos_token }}` expect you to pass `bos_token` in the context, and
//! to set `add_special_tokens = false` at encode time so the tokenizer does not add BOS a
//! second time. This crate renders exactly what the template says and never strips silently.
pub use ;
pub use ;
pub use Error;
pub use ;
pub use ;
/// Re-export of the `minijinja` we build against, so downstreams can construct context
/// [`Value`](minijinja::Value)s without guessing a version. Note: `render_value` ties our
/// public API to this `minijinja` major version.
pub use minijinja;