use greentic_types::Node;
const BUILTIN_KINDS: &[&str] = &[
"session.wait",
"flow.call",
"provider.invoke",
"dw.agent",
"dw.agent_graph",
"sorla.call",
"operala.call",
"agentic.call",
];
pub fn is_builtin_component_id(id: &str) -> bool {
id.starts_with("emit.")
|| BUILTIN_KINDS.iter().any(|kind| {
id == *kind
|| id
.strip_prefix(kind)
.is_some_and(|rest| rest.starts_with('.'))
})
}
pub fn node_effective_id(node: &Node) -> &str {
let id = node.component.id.as_str();
if id.is_empty() || id == "component.exec" {
node.component.operation.as_deref().unwrap_or(id)
} else {
id
}
}
pub fn node_is_builtin(node: &Node) -> bool {
is_builtin_component_id(node_effective_id(node))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn builtin_ids_cover_runner_node_kinds() {
for id in [
"session.wait",
"flow.call",
"provider.invoke",
"emit.response",
] {
assert!(is_builtin_component_id(id), "{id} should be builtin");
}
for id in [
"dw.agent",
"dw.agent.smoke-agent",
"dw.agent_graph",
"dw.agent_graph.triage",
"sorla.call",
"operala.call",
"agentic.call",
] {
assert!(is_builtin_component_id(id), "{id} should be builtin");
}
for id in [
"qa.process",
"templating.handlebars",
"dw.agentish",
"agentic",
] {
assert!(!is_builtin_component_id(id), "{id} must NOT be builtin");
}
}
}