Skip to main content

llguidance/
lib.rs

1//! Constrained decoding (structured outputs) for Large Language Models.
2//!
3//! This crate enforces arbitrary context-free grammars on LLM output, enabling
4//! structured generation with negligible overhead (~50μs per token for a 128k
5//! tokenizer). Context-free grammars can be provided with a Lark-like syntax,
6//! with specialised support for JSON.
7//!
8//! # Key types
9//!
10//! - [`ParserFactory`] — compiles grammars and holds shared tokenizer state.
11//! - [`TokenParser`] — built via [`ParserFactory::create_parser()`]; drives
12//!   a single generation session.
13//! - [`Constraint`] — main entry point wrapping a `TokenParser` and exposing
14//!   the sampling-loop API.
15//!
16//! # Usage pattern
17//!
18//! 1. Call [`Constraint::compute_mask()`] to obtain the set of allowed tokens.
19//!    This may take >1 ms and is best run on a background thread.
20//! 2. Sample a token from the LLM using the mask.
21//! 3. Pass the sampled token to [`Constraint::commit_token()`] (very fast).
22//! 4. Repeat until a stop result is returned.
23//!
24//! See the `sample_parser` crate for a complete usage example.
25
26#![allow(clippy::comparison_chain)]
27#![allow(clippy::needless_range_loop)]
28
29/// This is the primary interface for llguidance -- the one on which the others
30/// (FFI and LLInterpreter) are built.  While not cleanest of these interfaces,
31/// it is the  most inclusive.
32///
33/// cbindgen:ignore
34pub mod earley;
35
36mod hashcons;
37mod matcher;
38mod tokenparser;
39pub use tokenparser::TokenParser;
40pub mod api;
41pub mod output;
42pub use toktrie;
43pub mod panic_utils;
44
45mod constraint;
46mod stop_controller;
47mod tokenizer_json;
48pub use constraint::{CommitResult, Constraint};
49pub use matcher::Matcher;
50
51mod factory;
52pub use factory::ParserFactory;
53
54mod logging;
55pub use logging::Logger;
56
57pub use derivre;
58pub use derivre::{HashMap, HashSet};
59
60pub mod ffi;
61#[cfg(feature = "rayon")]
62mod ffi_par;
63
64mod grammar_builder;
65mod json;
66#[cfg(feature = "jsonschema_validation")]
67mod json_validation;
68mod regex_rewrite;
69pub mod substring;
70pub use grammar_builder::{GrammarBuilder, NodeRef};
71pub use json::compiler::JsonCompileOptions;
72pub use json::json_merge;
73pub use stop_controller::StopController;
74pub use tokenizer_json::token_bytes_from_tokenizer_json;
75
76#[cfg(feature = "lark")]
77mod lark;
78
79pub use regex_rewrite::regex_to_lark;
80
81#[cfg(feature = "wasm")]
82pub use instant::Instant;
83
84#[cfg(not(feature = "wasm"))]
85pub use std::time::Instant;
86
87#[macro_export]
88macro_rules! loginfo {
89    ($s:expr, $($arg:tt)*) => {
90        if $s.level_enabled(2) {
91            use std::fmt::Write;
92            writeln!($s.info_logger(), $($arg)*).unwrap();
93        }
94    };
95}
96
97#[macro_export]
98macro_rules! infoln {
99    ($s:expr, $($arg:tt)*) => {
100        if $s.logger.level_enabled(2) {
101            use std::fmt::Write;
102            writeln!($s.logger.info_logger(), $($arg)*).unwrap();
103        }
104    };
105}
106
107#[macro_export]
108macro_rules! warn {
109    ($s:expr, $($arg:tt)*) => {
110        if $s.logger.level_enabled(1) {
111            use std::fmt::Write;
112            $s.logger.write_warning("Warning: ");
113            writeln!($s.logger.warning_logger(), $($arg)*).unwrap();
114        }
115    };
116}
117
118#[macro_export]
119macro_rules! id32_type {
120    ($name:ident) => {
121        #[derive(serde::Serialize, serde::Deserialize, Hash, PartialEq, Eq, Clone, Copy, Debug)]
122        #[serde(transparent)]
123        pub struct $name(pub u32);
124
125        impl $name {
126            pub fn as_usize(&self) -> usize {
127                self.0 as usize
128            }
129
130            pub fn new(idx: usize) -> Self {
131                $name(idx as u32)
132            }
133        }
134    };
135}