MCPcopy Index your code
hub / github.com/InfinitiBit/graphbit / execute_agent_node_static

Method execute_agent_node_static

core/src/workflow.rs:1435–2055  ·  view source on GitHub ↗

Execute an agent node (static version). When `guardrail_enforcer` is `Some`, encodes prompt before LLM and decodes response after. When `stream_mode.emits_tokens()` and the provider supports streaming, emits `Token` events per chunk via `event_tx` and accumulates into a full response. Falls back to `complete()` if the provider does not support streaming.

(
        current_node_id: &NodeId,
        agent_node_config: &AgentNodeConfig,
        node_config: &std::collections::HashMap<String, serde_json::Value>,
        context: Arc<Mutex<WorkflowContext>

Source from the content-addressed store, hash-verified

1433 /// events per chunk via `event_tx` and accumulates into a full response. Falls back to
1434 /// `complete()` if the provider does not support streaming.
1435 async fn execute_agent_node_static(
1436 current_node_id: &NodeId,
1437 agent_node_config: &AgentNodeConfig,
1438 node_config: &std::collections::HashMap<String, serde_json::Value>,
1439 context: Arc<Mutex<WorkflowContext>>,
1440 agents: Arc<RwLock<HashMap<crate::types::AgentId, Arc<dyn AgentTrait>>>>,
1441 guardrail_enforcer: Option<Arc<Enforcer>>,
1442 event_tx: Option<tokio::sync::mpsc::Sender<crate::stream::StreamEvent>>,
1443 stream_mode: crate::stream::StreamMode,
1444 ) -> GraphBitResult<serde_json::Value> {
1445 let agent_id = &agent_node_config.agent_id;
1446 let prompt_template = &agent_node_config.prompt_template;
1447 let conversational_context = agent_node_config.conversational_context.as_deref();
1448 // Use read lock for better performance
1449 let agents_guard = agents.read().await;
1450 let agent = agents_guard
1451 .get(agent_id)
1452 .ok_or_else(|| GraphBitError::agent_not_found(agent_id.to_string()))?
1453 .clone();
1454 drop(agents_guard); // Release the lock early
1455
1456 // Build implicit preamble from upstream (parent) node outputs, then resolve templates
1457 let (resolved_prompt, resolved_context, metadata_input_raw) = {
1458 let ctx = context.lock().await;
1459
1460 // Extract dependency map and name map from metadata
1461 let deps_map = ctx
1462 .metadata
1463 .get("node_dependencies")
1464 .cloned()
1465 .unwrap_or(serde_json::json!({}));
1466 let id_name_map = ctx
1467 .metadata
1468 .get("node_id_to_name")
1469 .cloned()
1470 .unwrap_or(serde_json::json!({}));
1471
1472 // Collect preamble sections from DIRECT parents of this node
1473 let mut sections: Vec<String> = Vec::new();
1474 // Also collect a JSON map of parent outputs for CrewAI-style context passing
1475 let mut parents_json: serde_json::Map<String, serde_json::Value> =
1476 serde_json::Map::new();
1477
1478 // Use id->name map for titles
1479 let id_name_obj = id_name_map.as_object();
1480
1481 // Resolve current node id string and direct parents from deps map
1482 let cur_id_str = current_node_id.to_string();
1483 let parent_ids: Vec<String> = deps_map
1484 .as_object()
1485 .and_then(|m| m.get(&cur_id_str))
1486 .and_then(|v| v.as_array())
1487 .map(|arr| {
1488 arr.iter()
1489 .filter_map(|v| v.as_str().map(str::to_string))
1490 .collect::<Vec<String>>()
1491 })
1492 .unwrap_or_default();

Callers

nothing calls this directly

Calls 15

cloneMethod · 0.80
to_stringMethod · 0.80
insertMethod · 0.80
encodeMethod · 0.80
with_prompt_cachingMethod · 0.80
emits_tokensMethod · 0.80
decodeMethod · 0.80
getMethod · 0.45
is_emptyMethod · 0.45
configMethod · 0.45
with_temperatureMethod · 0.45
with_max_tokensMethod · 0.45

Tested by

no test coverage detected