Skip to content

Commit 8a2bfa7

Browse files
committed
PdlResult and ObjectBlock support
Signed-off-by: Nick Mitchell <[email protected]>
1 parent 1918c4b commit 8a2bfa7

File tree

5 files changed

+206
-76
lines changed

5 files changed

+206
-76
lines changed

pdl-live-react/src-tauri/src/commands/interpreter.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::pdl::interpreter::{pretty_print, run_string};
22

33
#[tauri::command]
44
pub async fn run_pdl_program(program: String, debug: bool) -> Result<String, String> {
5-
let (messages, _) = run_string(&program, debug)
5+
let (_, messages, _) = run_string(&program, debug)
66
.await
77
.map_err(|err| err.to_string())?;
88

pdl-live-react/src-tauri/src/pdl/interpreter.rs

Lines changed: 118 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,16 @@ use serde_json::{from_str, to_string, Map, Value};
2525
use serde_norway::{from_reader, from_str as from_yaml_str};
2626

2727
use crate::pdl::ast::{
28-
CallBlock, IfBlock, ListOrString, ModelBlock, PdlBlock, PdlParser, PdlUsage, PythonCodeBlock,
29-
ReadBlock, RepeatBlock, Role, StringOrBoolean, TextBlock,
28+
CallBlock, IfBlock, ListOrString, ModelBlock, ObjectBlock, PdlBlock, PdlParser, PdlUsage,
29+
PythonCodeBlock, ReadBlock, RepeatBlock, Role, StringOrBoolean, TextBlock,
3030
};
3131

32+
type PdlResult = Value;
3233
type Context = Vec<ChatMessage>;
3334
type Scope = HashMap<String, Value>;
3435
type PdlError = Box<dyn Error + Send + Sync>;
35-
type Interpretation = Result<(Context, PdlBlock), PdlError>;
36-
type InterpretationSync = Result<(Context, PdlBlock), Box<dyn Error>>;
36+
type Interpretation = Result<(PdlResult, Context, PdlBlock), PdlError>;
37+
type InterpretationSync = Result<(PdlResult, Context, PdlBlock), Box<dyn Error>>;
3738

3839
struct Interpreter<'a> {
3940
// batch: u32,
@@ -80,11 +81,18 @@ impl<'a> Interpreter<'a> {
8081
let prior_emit = self.emit;
8182
self.emit = emit;
8283

83-
let (messages, trace) = match program {
84+
let (result, messages, trace) = match program {
85+
PdlBlock::Number(n) => Ok((
86+
Value::Number(n.clone()),
87+
vec![ChatMessage::user(format!("{n}"))],
88+
PdlBlock::Number(n.clone()),
89+
)),
90+
PdlBlock::Function(f) => Ok((Value::Null, vec![], PdlBlock::Function(f.clone()))),
8491
PdlBlock::String(s) => self.run_string(s, context).await,
8592
PdlBlock::Call(block) => self.run_call(block, context).await,
8693
PdlBlock::If(block) => self.run_if(block, context).await,
8794
PdlBlock::Model(block) => self.run_model(block, context).await,
95+
PdlBlock::Object(block) => self.run_object(block, context).await,
8896
PdlBlock::PythonCode(block) => self.run_python_code(block, context).await,
8997
PdlBlock::Read(block) => self.run_read(block, context).await,
9098
PdlBlock::Repeat(block) => self.run_repeat(block, context).await,
@@ -101,7 +109,7 @@ impl<'a> Interpreter<'a> {
101109
}
102110
self.emit = prior_emit;
103111

104-
Ok((messages, trace))
112+
Ok((result, messages, trace))
105113
}
106114

107115
#[async_recursion]
@@ -177,12 +185,13 @@ impl<'a> Interpreter<'a> {
177185
eprintln!("String {} -> {:?}", msg, trace);
178186
}
179187

180-
let messages = vec![ChatMessage::user(match &trace {
188+
let result = match &trace {
181189
PdlBlock::String(s) => s.clone(),
182190
x => to_string(&x)?,
183-
})];
191+
};
192+
let messages = vec![ChatMessage::user(result.clone())];
184193

185-
Ok((messages, trace))
194+
Ok((Value::String(result), messages, trace))
186195
}
187196

188197
fn path_to(&self, file_path: &String) -> PathBuf {
@@ -194,25 +203,32 @@ impl<'a> Interpreter<'a> {
194203
fn def(
195204
&mut self,
196205
variable: &Option<String>,
197-
value: &String,
206+
value: &Value,
198207
parser: &Option<PdlParser>,
199-
) -> Result<(), PdlError> {
200-
if let Some(def) = &variable {
201-
let result = if let Some(parser) = parser {
202-
self.parse_result(parser, &value)?
208+
) -> Result<PdlResult, PdlError> {
209+
let result = if let Some(parser) = parser {
210+
if let Value::String(s) = value {
211+
self.parse_result(parser, s)
203212
} else {
204-
Value::from(value.clone()) // TODO
205-
};
213+
Err(Box::from(format!(
214+
"Cannot parse as {:?} a non-string value {:?}",
215+
parser, value
216+
)))
217+
}
218+
} else {
219+
Ok(value.clone())
220+
}?;
206221

222+
if let Some(def) = &variable {
207223
if let Some(scope) = self.scope.last_mut() {
208224
if self.debug {
209225
eprintln!("Def {} -> {}", def, result);
210226
}
211-
scope.insert(def.clone(), result);
227+
scope.insert(def.clone(), result.clone());
212228
}
213229
}
214230

215-
Ok(())
231+
Ok(result)
216232
}
217233

218234
/// Run a PdlBlock::Read
@@ -236,9 +252,13 @@ impl<'a> Interpreter<'a> {
236252
))),
237253
}?;
238254

239-
self.def(&block.def, &buffer, &block.parser)?;
255+
let result = self.def(&block.def, &buffer.clone().into(), &block.parser)?;
240256

241-
Ok((vec![ChatMessage::user(buffer)], PdlBlock::Read(trace)))
257+
Ok((
258+
result,
259+
vec![ChatMessage::user(buffer)],
260+
PdlBlock::Read(trace),
261+
))
242262
}
243263

244264
/// Run a PdlBlock::Call
@@ -275,7 +295,7 @@ impl<'a> Interpreter<'a> {
275295
eprintln!("If {:?}({:?})", block.condition, block.then);
276296
}
277297

278-
self.extend_scope_with_block_map(&block.defs);
298+
self.extend_scope_with_block_map(&block.defs).await?;
279299

280300
let cond = match &block.condition {
281301
StringOrBoolean::Boolean(b) => Value::Bool(*b),
@@ -285,7 +305,7 @@ impl<'a> Interpreter<'a> {
285305
Value::Bool(true) => self.run_quiet(&block.then, context).await,
286306
Value::Bool(false) => match &block.else_ {
287307
Some(else_block) => self.run_quiet(&else_block, context).await,
288-
None => Ok((vec![], PdlBlock::If(block.clone()))),
308+
None => Ok((Value::Null, vec![], PdlBlock::If(block.clone()))),
289309
},
290310
x => Err(Box::from(format!(
291311
"if block condition evaluated to non-boolean value: {:?}",
@@ -372,7 +392,7 @@ impl<'a> Interpreter<'a> {
372392
.unwrap();
373393
let messages = vec![ChatMessage::user(result_string.as_str().to_string())];
374394
let trace = PdlBlock::PythonCode(block.clone());
375-
Ok((messages, trace))
395+
Ok((Value::String(messages[0].content.clone()), messages, trace))
376396
}
377397
Err(_) => Err(Box::from(
378398
"Python code block failed to assign a 'result' variable",
@@ -401,8 +421,8 @@ impl<'a> Interpreter<'a> {
401421

402422
let messages = match &block.input {
403423
Some(input) => {
404-
// TODO ignoring trace
405-
let (messages, _trace) = self.run_quiet(&*input, context).await?;
424+
// TODO ignoring result, trace
425+
let (_result, messages, _trace) = self.run_quiet(&*input, context).await?;
406426
messages
407427
}
408428
None => context,
@@ -486,16 +506,44 @@ impl<'a> Interpreter<'a> {
486506
}
487507
let mut message = res.message.clone();
488508
message.content = response_string;
489-
Ok((vec![message], PdlBlock::Model(trace)))
509+
Ok((
510+
Value::String(message.content.clone()),
511+
vec![message],
512+
PdlBlock::Model(trace),
513+
))
490514
} else {
491-
Ok((vec![], PdlBlock::Model(trace)))
515+
// nothing came out of the model
516+
Ok((Value::Null, vec![], PdlBlock::Model(trace)))
492517
}
493518
// dbg!(history);
494519
}
495520
_ => Err(Box::from(format!("Unsupported model {}", block.model))),
496521
}
497522
}
498523

524+
async fn run_object(&mut self, block: &ObjectBlock, context: Context) -> Interpretation {
525+
let mut messages = vec![];
526+
let mut result_map = Map::new();
527+
let mut trace_map = HashMap::new();
528+
let mut iter = block.object.iter();
529+
while let Some((k, v)) = iter.next() {
530+
let (this_result, this_messages, this_trace) =
531+
self.run_quiet(v, context.clone()).await?;
532+
messages.extend(this_messages);
533+
result_map.insert(k.clone(), this_result);
534+
trace_map.insert(k.clone(), this_trace);
535+
}
536+
537+
if self.debug {
538+
eprintln!("Object {:?}", result_map);
539+
}
540+
Ok((
541+
Value::Object(result_map),
542+
messages,
543+
PdlBlock::Object(ObjectBlock { object: trace_map }),
544+
))
545+
}
546+
499547
/// Run a PdlBlock::Repeat
500548
async fn run_repeat(&mut self, block: &RepeatBlock, context: Context) -> Interpretation {
501549
// { i:[1,2,3], j: [4,5,6]} -> ([i,j], [[1,2,3],[4,5,6]])
@@ -515,6 +563,7 @@ impl<'a> Interpreter<'a> {
515563
eprintln!("Repeat {:?}", map);
516564
}
517565

566+
let mut results = vec![];
518567
let mut messages = vec![];
519568
let mut trace = vec![];
520569
if let Some(n) = map.iter().map(|(_, v)| v.len()).min() {
@@ -524,14 +573,19 @@ impl<'a> Interpreter<'a> {
524573
.map(|(k, v)| (k.clone(), v[iter].clone()))
525574
.collect();
526575
self.extend_scope_with_map(scope);
527-
let (ms, t) = self.run_quiet(&block.repeat, context.clone()).await?;
576+
let (result, ms, t) = self.run_quiet(&block.repeat, context.clone()).await?;
577+
results.push(result);
528578
messages.extend(ms);
529579
trace.push(t);
530580
self.scope.pop();
531581
}
532582
}
533583

534-
Ok((messages, PdlBlock::Repeat(block.clone())))
584+
Ok((
585+
Value::Array(results),
586+
messages,
587+
PdlBlock::Repeat(block.clone()),
588+
))
535589
}
536590

537591
fn to_ollama_role(&self, role: &Role) -> MessageRole {
@@ -545,8 +599,8 @@ impl<'a> Interpreter<'a> {
545599

546600
fn parse_result(&self, parser: &PdlParser, result: &String) -> Result<Value, PdlError> {
547601
match parser {
548-
PdlParser::Json => Ok(from_str(result)?),
549-
PdlParser::Yaml => Ok(from_yaml_str(result)?),
602+
PdlParser::Json => from_str(result).map_err(|e| Box::from(e)),
603+
PdlParser::Yaml => from_yaml_str(result).map_err(|e| Box::from(e)),
550604
}
551605
}
552606

@@ -561,24 +615,31 @@ impl<'a> Interpreter<'a> {
561615
self.extend_scope_with_map(scope);
562616
}
563617

564-
fn extend_scope_with_block_map(&mut self, map: &Option<HashMap<String, PdlBlock>>) {
618+
async fn extend_scope_with_block_map(
619+
&mut self,
620+
map: &Option<HashMap<String, PdlBlock>>,
621+
) -> Result<(), PdlError> {
565622
let cur_scope = self.scope.last().unwrap_or(&HashMap::new()).clone();
566623
let new_scope = match map {
567624
Some(defs) => {
568625
// this is all non-optimal
569626
let mut scope: Scope = HashMap::from(cur_scope);
570-
scope.extend(defs.iter().map(|(var, def)| {
571-
(
627+
let mut iter = defs.iter();
628+
while let Some((var, def)) = iter.next() {
629+
let (result, _, _) = self.run_quiet(def, vec![]).await?;
630+
scope.insert(
572631
var.clone(),
573-
from_str(to_string(def).unwrap().as_str()).unwrap(),
574-
)
575-
}));
632+
result,
633+
//from_str(to_string(&block).unwrap().as_str()).unwrap(),
634+
);
635+
}
576636
scope
577637
}
578638
None => cur_scope,
579639
};
580640

581641
self.extend_scope_with_map(new_scope);
642+
Ok(())
582643
}
583644

584645
/// Run a PdlBlock::Text
@@ -594,15 +655,20 @@ impl<'a> Interpreter<'a> {
594655
}
595656

596657
let mut input_messages = context.clone();
658+
let mut output_results = vec![];
597659
let mut output_messages = vec![];
598660
let mut output_blocks = vec![];
599661

600-
self.extend_scope_with_block_map(&block.defs);
662+
self.extend_scope_with_block_map(&block.defs).await?;
663+
eprintln!("Scope {:?}", self.scope.last());
664+
601665
let mut iter = block.text.iter();
602666
while let Some(block) = iter.next() {
603667
// run each element of the Text block
604-
let (this_messages, trace) = self.run(&block, input_messages.clone()).await?;
668+
let (this_result, this_messages, trace) =
669+
self.run(&block, input_messages.clone()).await?;
605670
input_messages.extend(this_messages.clone());
671+
output_results.push(this_result);
606672
output_messages.extend(this_messages);
607673
output_blocks.push(trace);
608674
}
@@ -611,28 +677,24 @@ impl<'a> Interpreter<'a> {
611677
let mut trace = block.clone();
612678
trace.text = output_blocks;
613679

614-
let result_string = output_messages
615-
.iter()
616-
.map(|m| m.content.clone())
680+
let result_string = output_results
681+
.into_iter()
682+
.map(|m| match m {
683+
Value::String(s) => s,
684+
x => x.to_string(),
685+
})
617686
.collect::<Vec<_>>()
618687
.join("\n");
619688

620-
if let Some(def) = &block.def {
621-
let result = if let Some(parser) = &block.parser {
622-
self.parse_result(parser, &result_string)?
623-
} else {
624-
Value::from(result_string.clone()) // TODO
625-
};
626-
627-
if let Some(scope) = self.scope.last_mut() {
628-
if self.debug {
629-
eprintln!("Def {} -> {}", def, result);
630-
}
631-
scope.insert(def.clone(), result);
632-
}
633-
}
689+
// FIXME, use output_results
690+
let result = self.def(
691+
&block.def,
692+
&Value::String(result_string.clone()),
693+
&block.parser,
694+
)?;
634695

635696
Ok((
697+
result,
636698
match &block.role {
637699
Some(role) => vec![ChatMessage::new(self.to_ollama_role(role), result_string)],
638700
None => output_messages,

0 commit comments

Comments
 (0)