Skip to content

Commit ba711a6

Browse files
committed
includeblock support
Signed-off-by: Nick Mitchell <[email protected]>
1 parent 9578bfa commit ba711a6

File tree

4 files changed

+49
-10
lines changed

4 files changed

+49
-10
lines changed

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,13 +476,21 @@ pub struct ArrayBlock {
476476
pub array: Vec<PdlBlock>,
477477
}
478478

479+
/// Include a PDL file
480+
#[derive(Serialize, Deserialize, Debug, Clone)]
481+
pub struct IncludeBlock {
482+
/// Name of the file to include.
483+
pub include: String,
484+
}
485+
479486
#[derive(Serialize, Deserialize, Debug, Clone)]
480487
#[serde(untagged)]
481488
pub enum PdlBlock {
482489
Bool(bool),
483490
Number(Number),
484491
String(String),
485492
If(IfBlock),
493+
Include(IncludeBlock),
486494
Object(ObjectBlock),
487495
Call(CallBlock),
488496
Array(ArrayBlock),

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

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ use serde_json::{from_str, to_string, Value};
2525
use serde_norway::{from_reader, from_str as from_yaml_str};
2626

2727
use crate::pdl::ast::{
28-
ArrayBlock, CallBlock, Closure, FunctionBlock, IfBlock, ListOrString, MessageBlock, ModelBlock,
29-
ObjectBlock, PdlBlock, PdlParser, PdlResult, PdlUsage, PythonCodeBlock, ReadBlock, RepeatBlock,
30-
Role, Scope, SequencingBlock, StringOrBoolean,
28+
ArrayBlock, CallBlock, Closure, FunctionBlock, IfBlock, IncludeBlock, ListOrString,
29+
MessageBlock, ModelBlock, ObjectBlock, PdlBlock, PdlParser, PdlResult, PdlUsage,
30+
PythonCodeBlock, ReadBlock, RepeatBlock, Role, Scope, SequencingBlock, StringOrBoolean,
3131
};
3232

3333
type Context = Vec<ChatMessage>;
@@ -100,6 +100,7 @@ impl<'a> Interpreter<'a> {
100100
PdlBlock::String(s) => self.run_string(s, context).await,
101101
PdlBlock::Call(block) => self.run_call(block, context).await,
102102
PdlBlock::If(block) => self.run_if(block, context).await,
103+
PdlBlock::Include(block) => self.run_include(block, context).await,
103104
PdlBlock::Model(block) => self.run_model(block, context).await,
104105
PdlBlock::Object(block) => self.run_object(block, context).await,
105106
PdlBlock::PythonCode(block) => self.run_python_code(block, context).await,
@@ -356,6 +357,16 @@ impl<'a> Interpreter<'a> {
356357
res
357358
}
358359

360+
/// Run a PdlBlock::Include
361+
async fn run_include(&mut self, block: &IncludeBlock, context: Context) -> Interpretation {
362+
if self.debug {
363+
eprintln!("Include {:?}", block.include);
364+
}
365+
366+
self.run_quiet(&parse_file(&self.path_to(&block.include))?, context.clone())
367+
.await
368+
}
369+
359370
fn to_ollama_model_options(
360371
&self,
361372
maybe_parameters: &Option<HashMap<String, Value>>,
@@ -824,19 +835,25 @@ pub async fn run(program: &PdlBlock, cwd: Option<PathBuf>, debug: bool) -> Inter
824835

825836
pub fn run_sync(program: &PdlBlock, cwd: Option<PathBuf>, debug: bool) -> InterpretationSync {
826837
tauri::async_runtime::block_on(run(program, cwd, debug))
827-
.map_err(|err| Box::<dyn ::std::error::Error>::from(err.to_string()))
838+
.map_err(|err| Box::<dyn Error>::from(err.to_string()))
839+
}
840+
841+
fn parse_file(path: &PathBuf) -> Result<PdlBlock, PdlError> {
842+
from_reader(File::open(path)?)
843+
.map_err(|err| Box::<dyn Error + Send + Sync>::from(err.to_string()))
828844
}
829845

830846
pub async fn run_file(source_file_path: &str, debug: bool) -> Interpretation {
831-
let cwd = PathBuf::from(source_file_path)
832-
.parent()
833-
.and_then(|cwd| Some(cwd.to_path_buf()));
834-
run(&from_reader(File::open(source_file_path)?)?, cwd, debug).await
847+
let path = PathBuf::from(source_file_path);
848+
let cwd = path.parent().and_then(|cwd| Some(cwd.to_path_buf()));
849+
let program = parse_file(&path)?;
850+
851+
run(&program, cwd, debug).await
835852
}
836853

837854
pub fn run_file_sync(source_file_path: &str, debug: bool) -> InterpretationSync {
838855
tauri::async_runtime::block_on(run_file(source_file_path, debug))
839-
.map_err(|err| Box::<dyn ::std::error::Error>::from(err.to_string()))
856+
.map_err(|err| Box::<dyn Error>::from(err.to_string()))
840857
}
841858

842859
pub async fn run_string(source: &str, debug: bool) -> Interpretation {
@@ -849,7 +866,7 @@ pub async fn run_json(source: Value, debug: bool) -> Interpretation {
849866

850867
pub fn run_json_sync(source: Value, debug: bool) -> InterpretationSync {
851868
tauri::async_runtime::block_on(run_json(source, debug))
852-
.map_err(|err| Box::<dyn ::std::error::Error>::from(err.to_string()))
869+
.map_err(|err| Box::<dyn Error>::from(err.to_string()))
853870
}
854871

855872
pub fn pretty_print(messages: &Vec<ChatMessage>) -> String {

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,4 +456,17 @@ mod tests {
456456
assert_eq!(messages[0].content, "good on object");
457457
Ok(())
458458
}
459+
460+
#[test]
461+
fn text_include() -> Result<(), Box<dyn Error>> {
462+
let program = json!({
463+
"include": "./tests/cli/call-with-args.pdl"
464+
});
465+
466+
let (_, messages, _) = run_json(program, false)?;
467+
assert_eq!(messages.len(), 1);
468+
assert_eq!(messages[0].role, MessageRole::User);
469+
assert_eq!(messages[0].content, "hello world 4 bye");
470+
Ok(())
471+
}
459472
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
include: ./call-with-args.pdl

0 commit comments

Comments
 (0)