@@ -5,8 +5,8 @@ use ::std::error::Error;
55use :: std:: fs:: File ;
66// use ::std::path::PathBuf;
77
8- use minijinja:: value:: ValueKind ;
98use minijinja:: Environment ;
9+
1010use ollama_rs:: {
1111 generation:: {
1212 chat:: { request:: ChatMessageRequest , ChatMessage , MessageRole } ,
@@ -15,37 +15,38 @@ use ollama_rs::{
1515 models:: ModelOptions ,
1616 Ollama ,
1717} ;
18+
1819use serde_json:: { from_str, to_string, Value } ;
1920use serde_norway:: from_reader;
2021use tokio:: runtime:: Runtime ;
2122
2223use crate :: pdl:: ast:: {
23- PdlBlock , PdlCallBlock , PdlModelBlock , PdlRepeatBlock , PdlTextBlock , PdlUsage , Role ,
24+ PdlBlock , PdlCallBlock , PdlModelBlock , PdlParser , PdlRepeatBlock , PdlTextBlock , PdlUsage , Role ,
2425} ;
2526
2627type Context = Vec < ChatMessage > ;
27- type Scope = HashMap < String , String > ;
28+ type Scope = HashMap < String , Value > ;
2829type Interpretation = Result < ( Context , PdlBlock ) , Box < dyn Error > > ;
2930
30- struct Interpreter < ' a > {
31+ struct Interpreter {
3132 // batch: u32,
3233 // role: Role,
3334 // cwd: Box<PathBuf>,
3435 // id_stack: Vec<String>,
35- jinja_env : Environment < ' a > ,
36+ // jinja_env: Environment<'a>,
3637 rt : Runtime ,
3738 scope : Vec < Scope > ,
3839 debug : bool ,
3940}
4041
41- impl < ' a > Interpreter < ' a > {
42+ impl Interpreter {
4243 fn new ( ) -> Self {
4344 Self {
4445 // batch: 0,
4546 // role: Role::User,
4647 // cwd: Box::new(current_dir().unwrap_or(PathBuf::from("/"))),
4748 // id_stack: vec![],
48- jinja_env : Environment :: new ( ) ,
49+ // jinja_env: Environment::new(),
4950 rt : Runtime :: new ( ) . unwrap ( ) ,
5051 scope : vec ! [ Scope :: new( ) ] ,
5152 debug : false ,
@@ -66,26 +67,41 @@ impl<'a> Interpreter<'a> {
6667 Ok ( ( messages, trace) )
6768 }
6869
69- fn eval ( & self , expr : & String ) -> Result < PdlBlock , Box < dyn Error > > {
70- let e = expr. replace ( "${ " , "" ) . replace ( " }" , "" ) ;
71- let jexpr = self . jinja_env . compile_expression ( & e) ?;
72- let result = jexpr. eval ( self . scope . last ( ) . unwrap_or ( & HashMap :: new ( ) ) ) ?;
70+ fn eval ( & self , pdl_expr : & String ) -> Result < PdlBlock , Box < dyn Error > > {
71+ let expr = pdl_expr. replace ( "${ " , "{{" ) . replace ( " }" , "}}" ) ; // FIXME regexp
72+ let mut env = Environment :: new ( ) ;
73+ env. add_template ( pdl_expr, expr. as_str ( ) ) ?;
74+ let tmpl = env. get_template ( pdl_expr) ?;
75+ let result = tmpl. render ( self . scope . last ( ) . unwrap_or ( & HashMap :: new ( ) ) ) ?;
76+ eprintln ! ( "Eval '{}' -> {}" , & expr, & result) ;
77+
78+ match from_str ( & result) {
79+ Err ( _) => {
80+ eprintln ! ( "Plain string {}" , & result) ;
81+ Ok ( PdlBlock :: String ( result) )
82+ }
83+ Ok ( x) => Ok ( x) ,
84+ }
85+ //let jexpr = self.jinja_env.compile_expression(&e)?;
86+ //let result = jexpr.eval(self.scope.last().unwrap_or(&HashMap::new()))?;
7387 //dbg!("Eval '{}' -> {:?}", e, result);
7488
75- match result. kind ( ) {
76- ValueKind :: String => Ok ( from_str ( & result. as_str ( ) . unwrap ( ) ) ?) ,
77- t => Err ( Box :: from ( format ! ( "Unexpected jinja result type {}" , t ) ) ) ,
78- }
89+ // match result.kind() {
90+ // ValueKind::String => Ok(from_str(&result.as_str().unwrap())?),
91+ // t => Err(Box::from(format!("Unexpected jinja result type: {} -> {}. {:?} ", expr, t, result ))),
92+ // }
7993 }
8094
8195 fn run_string ( & self , msg : & String , _context : Context ) -> Interpretation {
96+ let trace = self . eval ( msg) ?;
8297 if self . debug {
83- eprintln ! ( "String {}" , msg) ;
98+ eprintln ! ( "String {} -> {:?} " , msg, trace ) ;
8499 }
85- //TODO? self.eval(msg)
86100
87- let messages = vec ! [ ChatMessage :: user( msg. clone( ) ) ] ;
88- let trace = PdlBlock :: String ( msg. to_string ( ) ) ;
101+ let messages = vec ! [ ChatMessage :: user( match & trace {
102+ PdlBlock :: String ( s) => s. clone( ) ,
103+ x => to_string( & x) ?,
104+ } ) ] ;
89105
90106 Ok ( ( messages, trace) )
91107 }
@@ -222,6 +238,12 @@ impl<'a> Interpreter<'a> {
222238 }
223239 }
224240
241+ fn parse_result ( & self , parser : & PdlParser , result : & String ) -> Result < Value , Box < dyn Error > > {
242+ match parser {
243+ PdlParser :: Json => Ok ( from_str ( result) ?) ,
244+ }
245+ }
246+
225247 fn run_text ( & mut self , block : & PdlTextBlock , context : Context ) -> Interpretation {
226248 if self . debug {
227249 eprintln ! (
@@ -237,10 +259,12 @@ impl<'a> Interpreter<'a> {
237259 Some ( defs) => {
238260 // this is all non-optimal
239261 let mut scope: Scope = HashMap :: from ( cur_scope) ;
240- scope. extend (
241- defs. iter ( )
242- . map ( |( var, def) | ( var. clone ( ) , to_string ( def) . unwrap ( ) ) ) ,
243- ) ;
262+ scope. extend ( defs. iter ( ) . map ( |( var, def) | {
263+ (
264+ var. clone ( ) ,
265+ from_str ( to_string ( def) . unwrap ( ) . as_str ( ) ) . unwrap ( ) ,
266+ )
267+ } ) ) ;
244268 scope
245269 }
246270 None => cur_scope,
@@ -264,16 +288,28 @@ impl<'a> Interpreter<'a> {
264288 let mut trace = block. clone ( ) ;
265289 trace. text = output_blocks;
266290
291+ let result_string = output_messages
292+ . iter ( )
293+ . map ( |m| m. content . clone ( ) )
294+ . collect :: < Vec < _ > > ( )
295+ . join ( "\n " ) ;
296+
297+ if let Some ( def) = & block. def {
298+ let result = if let Some ( parser) = & block. parser {
299+ self . parse_result ( parser, & result_string) ?
300+ } else {
301+ Value :: from ( result_string. clone ( ) ) // TODO
302+ } ;
303+
304+ if let Some ( scope) = self . scope . last_mut ( ) {
305+ eprintln ! ( "DEF {} -> {}" , def, result) ;
306+ scope. insert ( def. clone ( ) , result) ;
307+ }
308+ }
309+
267310 Ok ( (
268311 match & block. role {
269- Some ( role) => vec ! [ ChatMessage :: new(
270- self . to_ollama_role( role) ,
271- output_messages
272- . into_iter( )
273- . map( |m| m. content)
274- . collect:: <Vec <_>>( )
275- . join( "\n " ) ,
276- ) ] ,
312+ Some ( role) => vec ! [ ChatMessage :: new( self . to_ollama_role( role) , result_string) ] ,
277313 None => output_messages,
278314 } ,
279315 PdlBlock :: Text ( trace) ,
0 commit comments