Skip to content

Commit f0364e5

Browse files
committed
merge
2 parents d408f14 + f5343be commit f0364e5

File tree

1 file changed

+69
-3
lines changed

1 file changed

+69
-3
lines changed

nerve-core/src/agent/task/tasklet.rs

+69-3
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ use serde::Deserialize;
1111
use serde_trim::*;
1212

1313
use super::{variables::interpolate_variables, Task};
14-
use crate::agent::get_user_input;
1514
use crate::agent::task::robopages;
15+
use crate::agent::{get_user_input, namespaces};
1616
use crate::agent::{
1717
namespaces::{Action, Namespace},
1818
state::SharedState,
@@ -41,8 +41,12 @@ pub struct TaskletAction {
4141
args: Option<HashMap<String, String>>,
4242
example_payload: Option<String>,
4343
timeout: Option<String>,
44-
#[serde(deserialize_with = "string_trim")]
45-
tool: String,
44+
45+
tool: Option<String>,
46+
alias: Option<String>,
47+
48+
#[serde(skip_deserializing, skip_serializing)]
49+
aliased_to: Option<Box<dyn Action>>,
4650
}
4751

4852
#[async_trait]
@@ -56,10 +60,18 @@ impl Action for TaskletAction {
5660
}
5761

5862
fn example_payload(&self) -> Option<&str> {
63+
if let Some(aliased_to) = &self.aliased_to {
64+
return aliased_to.example_payload();
65+
}
66+
5967
self.example_payload.as_deref()
6068
}
6169

6270
fn example_attributes(&self) -> Option<HashMap<String, String>> {
71+
if let Some(aliased_to) = &self.aliased_to {
72+
return aliased_to.example_attributes();
73+
}
74+
6375
self.args.clone()
6476
}
6577

@@ -88,9 +100,16 @@ impl Action for TaskletAction {
88100
return Ok(Some(result));
89101
}
90102

103+
// run as alias of a builtin namespace.action, here we can unwrap as everything is validated earlier
104+
if let Some(aliased_to) = &self.aliased_to {
105+
return aliased_to.run(state, attributes, payload).await;
106+
}
107+
91108
// run as local tool
92109
let parts: Vec<String> = self
93110
.tool
111+
.as_ref()
112+
.ok_or_else(|| anyhow!("tool not set"))?
94113
.split_whitespace()
95114
.map(|x| x.trim())
96115
.filter(|x| !x.is_empty())
@@ -314,12 +333,14 @@ impl Tasklet {
314333
let yaml = std::fs::read_to_string(&canon)?;
315334
let mut tasklet: Self = serde_yaml::from_str(&yaml)?;
316335

336+
// used to set the working directory while running the task
317337
tasklet.folder = if let Some(folder) = tasklet_parent_folder.to_str() {
318338
folder.to_string()
319339
} else {
320340
return Err(anyhow!("can't get string of {:?}", tasklet_parent_folder));
321341
};
322342

343+
// set unique task name from the folder or yaml file itself
323344
tasklet.name = if canon.ends_with("task.yaml") || canon.ends_with("task.yml") {
324345
tasklet_parent_folder
325346
.file_name()
@@ -331,6 +352,51 @@ impl Tasklet {
331352
canon.file_stem().unwrap().to_str().unwrap().to_owned()
332353
};
333354

355+
// check any tool definied as alias of a builtin namespace and perform some validation
356+
if let Some(functions) = tasklet.functions.as_mut() {
357+
for group in functions {
358+
for action in &mut group.actions {
359+
if let Some(alias) = &action.alias {
360+
if action.tool.is_some() {
361+
return Err(anyhow!("can't define both tool and alias"));
362+
}
363+
364+
let (namespace_name, action_name) = alias
365+
.split_once('.')
366+
.ok_or_else(|| anyhow!("invalid alias format '{}', aliases must be provided as 'namespace.action'", alias))?;
367+
368+
if let Some(get_namespace_fn) =
369+
namespaces::NAMESPACES.get(namespace_name)
370+
{
371+
let le_namespace = get_namespace_fn();
372+
let le_action = le_namespace
373+
.actions
374+
.iter()
375+
.find(|a| a.name() == action_name);
376+
377+
if let Some(le_action) = le_action {
378+
log::info!(
379+
"aliased {}.{} to {}",
380+
group.name,
381+
action.name,
382+
le_action.name()
383+
);
384+
action.aliased_to = Some(le_action.clone());
385+
} else {
386+
return Err(anyhow!(
387+
"action '{}' not found in namespace '{}'",
388+
action_name,
389+
namespace_name
390+
));
391+
}
392+
} else {
393+
return Err(anyhow!("namespace '{}' not found", namespace_name));
394+
}
395+
}
396+
}
397+
}
398+
}
399+
334400
log::debug!("tasklet = {:?}", &tasklet);
335401

336402
Ok(tasklet)

0 commit comments

Comments
 (0)