Skip to content

Commit ab0600d

Browse files
committed
fix: begin phasing in Metadata (common defs, etc. attrs) into rust AST
Rather than duplicating this "metadata" logic -- the stuff common to all non-literal blocks. This just starts the migration. The main trick is to use the serde `flatten` capability, so that we can maintain a separate Metadata struct in Rust, but have it flattened into the enclosing object for serde. Signed-off-by: Nick Mitchell <[email protected]>
1 parent a8029eb commit ab0600d

File tree

4 files changed

+64
-35
lines changed

4 files changed

+64
-35
lines changed

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

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ use serde_json::{from_reader, json, to_string, Map, Value};
1212
use tempfile::Builder;
1313

1414
use crate::pdl::ast::{
15-
ArrayBlock, CallBlock, FunctionBlock, ListOrString, MessageBlock, ModelBlock, ObjectBlock,
16-
PdlBaseType, PdlBlock, PdlOptionalType, PdlParser, PdlType, PythonCodeBlock, RepeatBlock, Role,
17-
TextBlock,
15+
ArrayBlock, CallBlock, FunctionBlock, ListOrString, MessageBlock, Metadata, ModelBlock,
16+
ObjectBlock, PdlBaseType, PdlBlock, PdlOptionalType, PdlParser, PdlType, PythonCodeBlock,
17+
RepeatBlock, Role, TextBlock,
1818
};
1919
use crate::pdl::pip::pip_install_if_needed;
2020
use crate::pdl::requirements::BEEAI_FRAMEWORK;
@@ -192,7 +192,7 @@ fn with_tools(
192192
fn call_tools(model: &String, parameters: &HashMap<String, Value>) -> PdlBlock {
193193
let repeat = PdlBlock::Text(TextBlock {
194194
def: None,
195-
defs: None,
195+
metadata: None,
196196
role: None,
197197
parser: None,
198198
description: Some("Calling tool ${ tool.function.name }".to_string()),
@@ -206,11 +206,13 @@ fn call_tools(model: &String, parameters: &HashMap<String, Value>) -> PdlBlock {
206206
name: Some("${ tool.function.name }".to_string()),
207207
tool_call_id: Some("${ tool.id }".to_string()),
208208
content: Box::new(PdlBlock::Call(CallBlock {
209-
defs: json_loads(
210-
&"args",
211-
&"pdl__args",
212-
&"${ tool.function.arguments }",
213-
),
209+
metadata: Some(Metadata {
210+
defs: json_loads(
211+
&"args",
212+
&"pdl__args",
213+
&"${ tool.function.arguments }",
214+
),
215+
}),
214216
call: "${ pdl__tools[tool.function.name] }".to_string(), // look up tool in tool_declarations def (see below)
215217
args: Some("${ args }".into()), // invoke with arguments as specified by the model
216218
})),
@@ -464,7 +466,7 @@ asyncio.run(invoke())
464466
role: Some(Role::System),
465467
text: vec![PdlBlock::String(instructions)],
466468
def: None,
467-
defs: None,
469+
metadata: None,
468470
parser: None,
469471
description: Some("Model instructions".into()),
470472
}));
@@ -504,7 +506,7 @@ asyncio.run(invoke())
504506
function: HashMap::new(),
505507
return_: Box::new(PdlBlock::Text(TextBlock {
506508
def: None,
507-
defs: None,
509+
metadata: None,
508510
role: None,
509511
parser: None,
510512
description: Some(format!("Model call {}", &model)),
@@ -514,7 +516,7 @@ asyncio.run(invoke())
514516
);
515517
PdlBlock::Text(TextBlock {
516518
def: None,
517-
defs: Some(defs),
519+
metadata: Some(Metadata { defs: Some(defs) }),
518520
role: None,
519521
parser: None,
520522
description: Some("Model call wrapper".to_string()),
@@ -533,7 +535,7 @@ asyncio.run(invoke())
533535

534536
let pdl: PdlBlock = PdlBlock::Text(TextBlock {
535537
def: None,
536-
defs: if tool_declarations.len() == 0 {
538+
metadata: if tool_declarations.len() == 0 {
537539
None
538540
} else {
539541
let mut m = indexmap::IndexMap::new();
@@ -543,7 +545,7 @@ asyncio.run(invoke())
543545
object: tool_declarations,
544546
}),
545547
);
546-
Some(m)
548+
Some(Metadata { defs: Some(m) })
547549
},
548550
description: Some(bee.workflow.workflow.name),
549551
role: None,

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

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ pub enum PdlType {
5151
Object(HashMap<String, PdlType>),
5252
}
5353

54+
/// Common metadata of blocks
55+
#[derive(Serialize, Deserialize, Debug, Clone)]
56+
pub struct Metadata {
57+
#[serde(skip_serializing_if = "Option::is_none")]
58+
pub defs: Option<IndexMap<String, PdlBlock>>,
59+
}
60+
5461
/// Call a function
5562
#[derive(Serialize, Deserialize, Debug, Clone)]
5663
#[serde(tag = "kind", rename = "call")]
@@ -62,16 +69,17 @@ pub struct CallBlock {
6269
#[serde(skip_serializing_if = "Option::is_none")]
6370
pub args: Option<Value>,
6471

72+
#[serde(flatten)]
6573
#[serde(skip_serializing_if = "Option::is_none")]
66-
pub defs: Option<IndexMap<String, PdlBlock>>,
74+
pub metadata: Option<Metadata>,
6775
}
6876

6977
impl CallBlock {
7078
pub fn new(call: String) -> Self {
7179
CallBlock {
7280
call: call,
7381
args: None,
74-
defs: None,
82+
metadata: None,
7583
}
7684
}
7785
}
@@ -81,7 +89,7 @@ pub trait SequencingBlock {
8189
fn description(&self) -> &Option<String>;
8290
fn role(&self) -> &Option<Role>;
8391
fn def(&self) -> &Option<String>;
84-
fn defs(&self) -> &Option<IndexMap<String, PdlBlock>>;
92+
fn metadata(&self) -> &Option<Metadata>;
8593
fn items(&self) -> &Vec<PdlBlock>;
8694
fn with_items(&self, items: Vec<PdlBlock>) -> Self;
8795
fn parser(&self) -> &Option<PdlParser>;
@@ -104,8 +112,9 @@ pub struct LastOfBlock {
104112
#[serde(skip_serializing_if = "Option::is_none")]
105113
pub role: Option<Role>,
106114

115+
#[serde(flatten)]
107116
#[serde(skip_serializing_if = "Option::is_none")]
108-
pub defs: Option<IndexMap<String, PdlBlock>>,
117+
pub metadata: Option<Metadata>,
109118

110119
#[serde(skip_serializing_if = "Option::is_none")]
111120
pub parser: Option<PdlParser>,
@@ -126,8 +135,8 @@ impl SequencingBlock for LastOfBlock {
126135
fn def(&self) -> &Option<String> {
127136
return &self.def;
128137
}
129-
fn defs(&self) -> &Option<IndexMap<String, PdlBlock>> {
130-
&self.defs
138+
fn metadata(&self) -> &Option<Metadata> {
139+
&self.metadata
131140
}
132141
fn items(&self) -> &Vec<PdlBlock> {
133142
&self.last_of
@@ -171,8 +180,9 @@ pub struct TextBlock {
171180
#[serde(skip_serializing_if = "Option::is_none")]
172181
pub role: Option<Role>,
173182

183+
#[serde(flatten)]
174184
#[serde(skip_serializing_if = "Option::is_none")]
175-
pub defs: Option<IndexMap<String, PdlBlock>>,
185+
pub metadata: Option<Metadata>,
176186

177187
#[serde(skip_serializing_if = "Option::is_none")]
178188
pub parser: Option<PdlParser>,
@@ -193,8 +203,8 @@ impl SequencingBlock for TextBlock {
193203
fn def(&self) -> &Option<String> {
194204
return &self.def;
195205
}
196-
fn defs(&self) -> &Option<IndexMap<String, PdlBlock>> {
197-
&self.defs
206+
fn metadata(&self) -> &Option<Metadata> {
207+
&self.metadata
198208
}
199209
fn items(&self) -> &Vec<PdlBlock> {
200210
&self.text
@@ -228,7 +238,7 @@ impl TextBlock {
228238
pub fn new(text: Vec<PdlBlock>) -> Self {
229239
TextBlock {
230240
def: None,
231-
defs: None,
241+
metadata: None,
232242
description: None,
233243
role: None,
234244
parser: None,
@@ -525,8 +535,9 @@ pub struct IfBlock {
525535
#[serde(skip_serializing_if = "Option::is_none")]
526536
pub else_: Option<Box<PdlBlock>>,
527537

538+
#[serde(flatten)]
528539
#[serde(skip_serializing_if = "Option::is_none")]
529-
pub defs: Option<IndexMap<String, PdlBlock>>,
540+
pub metadata: Option<Metadata>,
530541
}
531542

532543
/// Return the array of values computed by each block of the list of blocks

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

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::pdl::ast::PdlBlock;
1+
use crate::pdl::ast::{Metadata, PdlBlock};
22

33
/// Extract models referenced by the programs
44
pub fn extract_models(program: &PdlBlock) -> Vec<String> {
@@ -35,7 +35,10 @@ fn extract_values_iter(program: &PdlBlock, field: &str, values: &mut Vec<String>
3535
b.text
3636
.iter()
3737
.for_each(|p| extract_values_iter(p, field, values));
38-
if let Some(defs) = &b.defs {
38+
if let Some(Metadata {
39+
defs: Some(defs), ..
40+
}) = &b.metadata
41+
{
3942
defs.values()
4043
.for_each(|p| extract_values_iter(p, field, values));
4144
}
@@ -44,7 +47,10 @@ fn extract_values_iter(program: &PdlBlock, field: &str, values: &mut Vec<String>
4447
b.last_of
4548
.iter()
4649
.for_each(|p| extract_values_iter(p, field, values));
47-
if let Some(defs) = &b.defs {
50+
if let Some(Metadata {
51+
defs: Some(defs), ..
52+
}) = &b.metadata
53+
{
4854
defs.values()
4955
.for_each(|p| extract_values_iter(p, field, values));
5056
}
@@ -54,11 +60,19 @@ fn extract_values_iter(program: &PdlBlock, field: &str, values: &mut Vec<String>
5460
if let Some(else_) = &b.else_ {
5561
extract_values_iter(else_, field, values);
5662
}
57-
if let Some(defs) = &b.defs {
63+
if let Some(Metadata {
64+
defs: Some(defs), ..
65+
}) = &b.metadata
66+
{
5867
defs.values()
5968
.for_each(|p| extract_values_iter(p, field, values));
6069
}
6170
}
71+
PdlBlock::Empty(b) => {
72+
b.defs
73+
.values()
74+
.for_each(|p| extract_values_iter(p, field, values));
75+
}
6276
PdlBlock::Object(b) => b
6377
.object
6478
.values()

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// use ::std::cell::LazyCell;
21
use ::std::collections::HashMap;
32
use ::std::error::Error;
43
use ::std::path::PathBuf;
@@ -91,7 +90,6 @@ impl State {
9190

9291
struct Interpreter<'a> {
9392
// batch: u32,
94-
// role: Role,
9593
// id_stack: Vec<String>,
9694
options: RunOptions<'a>,
9795
jinja_env: Environment<'a>,
@@ -110,7 +108,6 @@ impl<'a> Interpreter<'a> {
110108

111109
Self {
112110
// batch: 0,
113-
// role: Role::User,
114111
// id_stack: vec![],
115112
jinja_env: jinja_env,
116113
options: options,
@@ -415,8 +412,9 @@ impl<'a> Interpreter<'a> {
415412
eprintln!("Empty");
416413
}
417414

418-
let trace = block.clone();
419415
self.process_defs(&Some(block.defs.clone()), state).await?;
416+
417+
let trace = block.clone();
420418
Ok((
421419
PdlResult::Dict(state.scope.clone()),
422420
vec![],
@@ -430,7 +428,9 @@ impl<'a> Interpreter<'a> {
430428
eprintln!("If {:?}({:?})", block.condition, block.then);
431429
}
432430

433-
self.process_defs(&block.defs, state).await?;
431+
if let Some(meta) = &block.metadata {
432+
self.process_defs(&meta.defs, state).await?;
433+
}
434434

435435
let cond = match &block.condition {
436436
StringOrBoolean::Boolean(b) => PdlResult::Bool(*b),
@@ -893,7 +893,9 @@ impl<'a> Interpreter<'a> {
893893
let mut output_messages = vec![];
894894
let mut output_blocks = vec![];
895895

896-
self.process_defs(block.defs(), state).await?;
896+
if let Some(meta) = block.metadata() {
897+
self.process_defs(&meta.defs, state).await?;
898+
}
897899

898900
// here is where we iterate over the sequence items
899901
let mut iter = block.items().iter();

0 commit comments

Comments
 (0)