| 1540 | } |
| 1541 | |
| 1542 | fn merge_live_outcome_into_context( |
| 1543 | context: &mut graphbit_core::types::WorkflowContext, |
| 1544 | node_id: &str, |
| 1545 | node_name: &str, |
| 1546 | final_output: &str, |
| 1547 | executions_to_append: Vec<serde_json::Value>, |
| 1548 | tools_used_to_add: Vec<String>, |
| 1549 | final_finish_reason: &str, |
| 1550 | ) { |
| 1551 | context.node_outputs.insert( |
| 1552 | node_id.to_string(), |
| 1553 | serde_json::Value::String(final_output.to_string()), |
| 1554 | ); |
| 1555 | |
| 1556 | for key in [ |
| 1557 | format!("node_response_{node_id}"), |
| 1558 | format!("node_response_{node_name}"), |
| 1559 | ] { |
| 1560 | let mut node_meta = context |
| 1561 | .metadata |
| 1562 | .get(&key) |
| 1563 | .cloned() |
| 1564 | .unwrap_or_else(|| serde_json::json!({})); |
| 1565 | let Some(obj) = node_meta.as_object_mut() else { |
| 1566 | context.metadata.insert(key, node_meta); |
| 1567 | continue; |
| 1568 | }; |
| 1569 | |
| 1570 | obj.insert( |
| 1571 | "final_output".to_string(), |
| 1572 | serde_json::Value::String(final_output.to_string()), |
| 1573 | ); |
| 1574 | obj.insert( |
| 1575 | "exit_reason".to_string(), |
| 1576 | serde_json::Value::String(final_finish_reason.to_string()), |
| 1577 | ); |
| 1578 | obj.insert( |
| 1579 | "end_time".to_string(), |
| 1580 | serde_json::Value::String(chrono::Utc::now().to_rfc3339()), |
| 1581 | ); |
| 1582 | |
| 1583 | let mut existing_exec = obj |
| 1584 | .get("executions") |
| 1585 | .and_then(|v| v.as_array()) |
| 1586 | .cloned() |
| 1587 | .unwrap_or_default(); |
| 1588 | existing_exec.extend(executions_to_append.clone()); |
| 1589 | obj.insert( |
| 1590 | "executions".to_string(), |
| 1591 | serde_json::Value::Array(existing_exec.clone()), |
| 1592 | ); |
| 1593 | |
| 1594 | let mut tools_used = obj |
| 1595 | .get("tools_used") |
| 1596 | .and_then(|v| v.as_array()) |
| 1597 | .map(|arr| { |
| 1598 | arr.iter() |
| 1599 | .filter_map(|v| v.as_str().map(|s| s.to_string())) |