@@ -7,28 +7,33 @@ use asimov_module::{prelude::*, tracing};
77use core:: error:: Error ;
88use serde_json:: { Value , json} ;
99
10- #[ derive( Clone , Debug , bon:: Builder ) ]
11- #[ builder( on( String , into) ) ]
10+ #[ derive( Clone , Debug ) ]
1211pub struct Options {
1312 /// Base URL of the llama.cpp server (e.g. http://localhost:8080)
1413 pub endpoint : String ,
15-
1614 /// Model identifier (e.g. "llama3")
1715 pub model : String ,
16+ /// Optional raw GBNF grammar text to constrain decoding
17+ pub grammar : Option < String > ,
1818}
1919
20- /// Generate a response using llama.cpp’s OpenAI-compatible endpoint.
21- /// Example: POST /v1/chat/completions
20+ /// POST /v1/chat/completions with optional GBNF grammar
2221pub fn generate ( input : impl AsRef < str > , options : & Options ) -> Result < Vec < String > , Box < dyn Error > > {
2322 const UA : & str = "asimov-llamacpp-module" ;
2423 const CT_JSON : & str = "application/json" ;
2524
26- let req = json ! ( {
25+ let mut req = json ! ( {
2726 "model" : options. model,
2827 "messages" : [ { "role" : "user" , "content" : input. as_ref( ) } ] ,
2928 "stream" : false
3029 } ) ;
3130
31+ if let Some ( g) = & options. grammar {
32+ if let Value :: Object ( obj) = & mut req {
33+ obj. insert ( "grammar" . into ( ) , Value :: String ( g. clone ( ) ) ) ;
34+ }
35+ }
36+
3237 let agent = ureq:: Agent :: config_builder ( )
3338 . http_status_as_error ( false )
3439 . user_agent ( UA )
0 commit comments