#[tokio::test]
async fn test_orchestration_goal_context_feed_forward() {
use crate::memory::embeddings::EmbeddingService;
use crate::state::SqliteStateStore;
use crate::types::FactPrivacy;
let db_file = tempfile::NamedTempFile::new().unwrap();
let db_path = db_file.path().to_str().unwrap().to_string();
let embedding_service = Arc::new(EmbeddingService::new().unwrap());
let state: Arc<dyn StateStore> = Arc::new(
SqliteStateStore::new(&db_path, 100, None, embedding_service)
.await
.unwrap(),
);
state
.upsert_fact(
"technical",
"build_full_stack_website_deploy_aws_target",
"AWS us-east-1 deployment target for full stack website",
"manual",
None,
FactPrivacy::Global,
)
.await
.unwrap();
state
.upsert_fact(
"project",
"full_stack_website_framework",
"Uses React and Node.js for full stack website deploy flow to AWS",
"manual",
None,
FactPrivacy::Global,
)
.await
.unwrap();
let mut goal = Goal::new_finite(
"Build a full-stack website and deploy to AWS",
"test-session",
);
let relevant_facts = state
.get_relevant_facts("Build a full-stack website and deploy to AWS", 10)
.await
.unwrap_or_default();
let relevant_procedures = state
.get_relevant_procedures("Build a full-stack website and deploy to AWS", 5)
.await
.unwrap_or_default();
if !relevant_facts.is_empty() || !relevant_procedures.is_empty() {
let ctx = serde_json::json!({
"relevant_facts": relevant_facts.iter().map(|f| {
serde_json::json!({"category": f.category, "key": f.key, "value": f.value})
}).collect::<Vec<_>>(),
"relevant_procedures": relevant_procedures.iter().map(|p| {
serde_json::json!({"name": p.name, "trigger": p.trigger_pattern, "steps": p.steps})
}).collect::<Vec<_>>(),
"task_results": [],
});
goal.context = Some(serde_json::to_string(&ctx).unwrap_or_default());
}
state.create_goal(&goal).await.unwrap();
let stored_goal = state.get_goal(&goal.id).await.unwrap().unwrap();
assert!(
stored_goal.context.is_some(),
"Goal should have context with relevant facts"
);
let ctx: serde_json::Value =
serde_json::from_str(stored_goal.context.as_deref().unwrap()).unwrap();
assert!(ctx.get("task_results").is_some());
assert!(ctx.get("relevant_facts").is_some());
let facts = ctx["relevant_facts"].as_array().unwrap();
assert!(
facts.len() >= 2,
"Should have at least 2 relevant facts, got {}",
facts.len()
);
assert!(facts[0].get("category").is_some());
assert!(facts[0].get("key").is_some());
assert!(facts[0].get("value").is_some());
std::mem::forget(db_file);
}
#[tokio::test]
async fn test_orchestration_context_accumulation_end_to_end() {
use crate::memory::embeddings::EmbeddingService;
use crate::state::SqliteStateStore;
use crate::tools::manage_goal_tasks::ManageGoalTasksTool;
use crate::traits::Tool;
let db_file = tempfile::NamedTempFile::new().unwrap();
let db_path = db_file.path().to_str().unwrap().to_string();
let embedding_service = Arc::new(EmbeddingService::new().unwrap());
let state: Arc<dyn StateStore> = Arc::new(
SqliteStateStore::new(&db_path, 100, None, embedding_service)
.await
.unwrap(),
);
let goal = Goal::new_finite("Build and deploy website", "test-session");
let goal_id = goal.id.clone();
state.create_goal(&goal).await.unwrap();
let tool = ManageGoalTasksTool::new(goal_id.clone(), state.clone());
tool.call(
&serde_json::json!({
"action": "create_task",
"description": "Set up database schema",
"task_order": 1
})
.to_string(),
)
.await
.unwrap();
tool.call(
&serde_json::json!({
"action": "create_task",
"description": "Build API endpoints",
"task_order": 2
})
.to_string(),
)
.await
.unwrap();
let tasks = state.get_tasks_for_goal(&goal_id).await.unwrap();
assert_eq!(tasks.len(), 2);
tool.call(
&serde_json::json!({
"action": "update_task",
"task_id": tasks[0].id,
"status": "completed",
"result": "Created users, posts, and comments tables in PostgreSQL"
})
.to_string(),
)
.await
.unwrap();
let goal = state.get_goal(&goal_id).await.unwrap().unwrap();
let ctx: serde_json::Value = serde_json::from_str(goal.context.as_deref().unwrap()).unwrap();
let results = ctx["task_results"].as_array().unwrap();
assert_eq!(results.len(), 1);
assert!(results[0]["result_summary"]
.as_str()
.unwrap()
.contains("PostgreSQL"));
tool.call(
&serde_json::json!({
"action": "update_task",
"task_id": tasks[1].id,
"status": "completed",
"result": "Built REST API with CRUD for users, posts, comments"
})
.to_string(),
)
.await
.unwrap();
let goal = state.get_goal(&goal_id).await.unwrap().unwrap();
let ctx: serde_json::Value = serde_json::from_str(goal.context.as_deref().unwrap()).unwrap();
let results = ctx["task_results"].as_array().unwrap();
assert_eq!(results.len(), 2, "Both task results should be accumulated");
std::mem::forget(db_file);
}