Skip to content

Commit 46401a8

Browse files
committed
fix: rust ast support for gsm8k, including jsonl parser
The program may not run 100% yet, but it parses now. Signed-off-by: Nick Mitchell <[email protected]>
1 parent 7f2246b commit 46401a8

File tree

5 files changed

+116
-7
lines changed

5 files changed

+116
-7
lines changed

pdl-live-react/src-tauri/src/compile/beeai.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ fn call_tools(model: &String, parameters: &HashMap<String, Value>) -> PdlBlock {
270270
body: Repeat(RepeatBlock {
271271
for_: for_,
272272
repeat: Box::new(repeat),
273+
join: None,
273274
}),
274275
})
275276
}

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

Lines changed: 76 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,40 @@ pub enum Role {
1919
Tool,
2020
}
2121

22+
#[derive(Serialize, Deserialize, Debug, Clone)]
23+
#[serde(rename_all_fields(serialize = "lowercase"))]
24+
pub enum RegexMode {
25+
Search,
26+
Match,
27+
Fullmatch,
28+
Split,
29+
Findall,
30+
}
31+
32+
/// A regular expression parser
33+
#[derive(Serialize, Deserialize, Debug, Clone)]
34+
pub struct RegexParser {
35+
/// Regular expression to parse the value
36+
pub regex: String,
37+
38+
#[serde(skip_serializing_if = "Option::is_none")]
39+
pub mode: Option<RegexMode>,
40+
41+
/// Expected type of the parsed value
42+
#[serde(skip_serializing_if = "Option::is_none")]
43+
pub spec: Option<Value>,
44+
}
45+
2246
#[derive(Serialize, Deserialize, Debug, Clone)]
2347
pub enum PdlParser {
2448
#[serde(rename = "json")]
2549
Json,
26-
/*#[serde(rename = "jsonl")]
27-
Jsonl,*/
50+
#[serde(rename = "jsonl")]
51+
Jsonl,
2852
#[serde(rename = "yaml")]
2953
Yaml,
54+
#[serde(untagged)]
55+
Regex(RegexParser),
3056
}
3157

3258
#[derive(Serialize, Deserialize, Debug, Clone)]
@@ -89,15 +115,26 @@ impl Timing {
89115
#[serde(default)]
90116
#[builder(setter(into, strip_option), default)]
91117
pub struct Metadata {
118+
/// Documentation associated to the block
92119
#[serde(skip_serializing_if = "Option::is_none")]
93120
pub description: Option<String>,
94121

122+
/// Set of definitions executed before the execution of the block
95123
#[serde(skip_serializing_if = "Option::is_none")]
96124
pub defs: Option<IndexMap<String, PdlBlock>>,
97125

126+
/// Name of the variable used to store the result of the execution of the block
98127
#[serde(skip_serializing_if = "Option::is_none")]
99128
pub def: Option<String>,
100129

130+
/// Indicate if the block contributes to the result and background context
131+
#[serde(skip_serializing_if = "Option::is_none")]
132+
pub contribute: Option<Vec<String>>, // TODO
133+
134+
/// Type specification of the result of the block
135+
#[serde(skip_serializing_if = "Option::is_none")]
136+
pub spec: Option<Value>,
137+
101138
#[serde(rename = "pdl__id", skip_serializing_if = "Option::is_none")]
102139
pub pdl_id: Option<String>,
103140

@@ -284,11 +321,9 @@ pub struct ModelBlock {
284321
pub input: Option<Box<PdlBlock>>,
285322
#[serde(skip_serializing_if = "Option::is_none")]
286323
pub platform: Option<String>,
287-
#[serde(skip_serializing_if = "Option::is_none")]
288-
#[serde(rename = "modelResponse")]
324+
#[serde(rename = "modelResponse", skip_serializing_if = "Option::is_none")]
289325
pub model_response: Option<String>,
290-
#[serde(rename = "pdl__usage")]
291-
#[serde(skip_serializing_if = "Option::is_none")]
326+
#[serde(rename = "pdl__usage", skip_serializing_if = "Option::is_none")]
292327
pub pdl_usage: Option<PdlUsage>,
293328

294329
/// The result of evaluating the `input` field (if given)
@@ -307,6 +342,37 @@ pub enum ListOrString {
307342
List(Vec<Value>),
308343
}
309344

345+
#[derive(Serialize, Deserialize, Debug, Clone)]
346+
pub enum IterationType {
347+
#[serde(rename = "lastOf")]
348+
LastOf,
349+
#[serde(rename = "array")]
350+
Array,
351+
#[serde(rename = "object")]
352+
Object,
353+
#[serde(rename = "text")]
354+
Text,
355+
}
356+
357+
#[derive(Serialize, Deserialize, Debug, Clone)]
358+
pub struct JoinAs {
359+
#[serde(rename = "as")]
360+
as_: IterationType,
361+
}
362+
#[derive(Serialize, Deserialize, Debug, Clone)]
363+
pub struct JoinAsWith {
364+
#[serde(rename = "as")]
365+
as_: IterationType,
366+
with: String,
367+
}
368+
369+
#[derive(Serialize, Deserialize, Debug, Clone)]
370+
#[serde(untagged)]
371+
pub enum JoinType {
372+
AsWith(JoinAsWith),
373+
As(JoinAs),
374+
}
375+
310376
/// Repeat the execution of a block.
311377
///
312378
/// For loop example:
@@ -326,6 +392,10 @@ pub struct RepeatBlock {
326392

327393
/// Body of the loop
328394
pub repeat: Box<PdlBlock>,
395+
396+
/// Define how to combine the result of each iteration
397+
#[serde(skip_serializing_if = "Option::is_none")]
398+
pub join: Option<JoinType>,
329399
}
330400

331401
/// Create a message

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1189,8 +1189,14 @@ impl<'a> Interpreter<'a> {
11891189

11901190
fn parse_result(&self, parser: &PdlParser, result: &String) -> Result<PdlResult, PdlError> {
11911191
match parser {
1192-
PdlParser::Json => from_str(result).map_err(|e| Box::from(e)),
1192+
PdlParser::Json => from_str(result).map_err(|e| Box::from(e)), // .map_err(|e| PdlError::from(e))
1193+
PdlParser::Jsonl => Ok(PdlResult::List(
1194+
serde_json::Deserializer::from_str(result)
1195+
.into_iter::<PdlResult>()
1196+
.collect::<Result<_, _>>()?,
1197+
)),
11931198
PdlParser::Yaml => from_yaml_str(result).map_err(|e| Box::from(e)),
1199+
PdlParser::Regex(_) => todo!(),
11941200
}
11951201
}
11961202

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,29 @@ mod tests {
205205
Ok(())
206206
}
207207

208+
#[test]
209+
fn text_parser_jsonl() -> Result<(), Box<dyn Error>> {
210+
let json = "{\"key\":\"value\"}
211+
{\"key2\":\"value2\"}";
212+
let program = json!({
213+
"text": [
214+
{ "def": "foo", "parser": "jsonl", "text": [json] },
215+
"${ foo[0].key }",
216+
"${ foo[1].key2 }"
217+
]
218+
});
219+
220+
let (_, messages, _) = run_json(program, streaming(), initial_scope())?;
221+
assert_eq!(messages.len(), 3);
222+
assert_eq!(messages[0].role, MessageRole::User);
223+
assert_eq!(messages[0].content, json);
224+
assert_eq!(messages[1].role, MessageRole::User);
225+
assert_eq!(messages[1].content, "value");
226+
assert_eq!(messages[2].role, MessageRole::User);
227+
assert_eq!(messages[2].content, "value2");
228+
Ok(())
229+
}
230+
208231
#[test]
209232
fn last_of_parser_json() -> Result<(), Box<dyn Error>> {
210233
let json = "{\"key\":\"value\"}";
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
text:
2+
- text:
3+
- |
4+
{"key": "value"}
5+
{"key2": "value2"}
6+
parser: jsonl
7+
def: foo
8+
- ${ foo[0].key }
9+
- ${ foo[1].key2 }

0 commit comments

Comments
 (0)