Skip to content

Commit 74c4a43

Browse files
committed
read block support
Signed-off-by: Nick Mitchell <[email protected]>
1 parent a1123b0 commit 74c4a43

File tree

3 files changed

+66
-3
lines changed

3 files changed

+66
-3
lines changed

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,29 @@ fn lang_python() -> String {
232232
"python".to_string()
233233
}
234234

235+
// Read from a file or standard input.
236+
//
237+
// Example. Read from the standard input with a prompt starting with `> `.
238+
// ```PDL
239+
// read:
240+
// message: "> "
241+
// ```
242+
//
243+
// Example. Read the file `./data.yaml` in the same directory of the PDL file containing the block and parse it into YAML.
244+
// ```PDL
245+
// read: ./data.yaml
246+
// parser: yaml
247+
// ```
248+
#[derive(Serialize, Deserialize, Debug, Clone)]
249+
pub struct PdlReadBlock {
250+
// Name of the file to read. If `None`, read the standard input.
251+
pub read: Value,
252+
// Name of the file to read. If `None`, read the standard input.
253+
pub message: Option<String>,
254+
// Indicate if one or multiple lines should be read.
255+
pub multiline: Option<bool>,
256+
}
257+
235258
#[derive(Serialize, Deserialize, Debug, Clone)]
236259
#[serde(untagged)]
237260
pub enum PdlBlock {
@@ -252,6 +275,7 @@ pub enum PdlBlock {
252275
Model(PdlModelBlock),
253276
Function(PdlFunctionBlock),
254277
PythonCode(PdlPythonCodeBlock),
278+
Read(PdlReadBlock),
255279
}
256280

257281
impl From<&str> for PdlBlock {

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

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use ::std::collections::HashMap;
33
use std::sync::{Arc, Mutex};
44
// use ::std::env::current_dir;
55
use ::std::error::Error;
6-
use ::std::fs::File;
6+
use ::std::fs::{read_to_string as read_file_to_string, File};
77
// use ::std::path::PathBuf;
88

99
use async_recursion::async_recursion;
@@ -25,8 +25,8 @@ 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-
PdlBlock, PdlCallBlock, PdlModelBlock, PdlParser, PdlPythonCodeBlock, PdlRepeatBlock,
29-
PdlTextBlock, PdlUsage, Role,
28+
PdlBlock, PdlCallBlock, PdlModelBlock, PdlParser, PdlPythonCodeBlock, PdlReadBlock,
29+
PdlRepeatBlock, PdlTextBlock, PdlUsage, Role,
3030
};
3131

3232
type Context = Vec<ChatMessage>;
@@ -84,6 +84,7 @@ impl<'a> Interpreter<'a> {
8484
PdlBlock::Call(block) => self.run_call(block, context).await,
8585
PdlBlock::PythonCode(block) => self.run_python_code(block, context).await,
8686
PdlBlock::Model(block) => self.run_model(block, context).await,
87+
PdlBlock::Read(block) => self.run_read(block, context).await,
8788
PdlBlock::Repeat(block) => self.run_repeat(block, context).await,
8889
PdlBlock::Text(block) => self.run_text(block, context).await,
8990
_ => Err(Box::from(format!("Unsupported block {:?}", program))),
@@ -148,6 +149,30 @@ impl<'a> Interpreter<'a> {
148149
Ok((messages, trace))
149150
}
150151

152+
// Run a PdlBlock::Read
153+
async fn run_read(&self, block: &PdlReadBlock, _context: Context) -> Interpretation {
154+
let trace = block.clone();
155+
156+
if let Some(message) = &block.message {
157+
println!("{}", message);
158+
}
159+
160+
let buffer = match &block.read {
161+
Value::String(file_path) => Ok(read_file_to_string(file_path)?),
162+
Value::Null => {
163+
let mut buffer = String::new();
164+
::std::io::stdin().read_line(&mut buffer)?;
165+
Ok(buffer)
166+
}
167+
x => Err(Box::<dyn Error + Send + Sync>::from(format!(
168+
"Unsupported value for read field: {:?}",
169+
x
170+
))),
171+
}?;
172+
173+
Ok((vec![ChatMessage::user(buffer)], PdlBlock::Read(trace)))
174+
}
175+
151176
// Run a PdlBlock::Call
152177
async fn run_call(&mut self, block: &PdlCallBlock, context: Context) -> Interpretation {
153178
if self.debug {

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,4 +206,18 @@ mod tests {
206206
assert_eq!(messages[0].content, "{'foo': 3}");
207207
Ok(())
208208
}
209+
210+
#[test]
211+
fn text_read_file() -> Result<(), Box<dyn Error>> {
212+
let program = json!({
213+
"message": "Read a file",
214+
"read":"./tests/data/foo.txt"
215+
});
216+
217+
let (messages, _) = run_json(program, false)?;
218+
assert_eq!(messages.len(), 1);
219+
assert_eq!(messages[0].role, MessageRole::User);
220+
assert_eq!(messages[0].content, "this should be foo\n");
221+
Ok(())
222+
}
209223
}

0 commit comments

Comments
 (0)