fix: restore final_output_tool when agent is recreated after LRU eviction (#10793)
This commit is contained in:
@@ -223,6 +223,11 @@ impl AgentManager {
|
||||
}
|
||||
}
|
||||
extension_results = agent.load_extensions_from_session(&session).await;
|
||||
if let Some(recipe) = &session.recipe {
|
||||
agent
|
||||
.apply_recipe_components(recipe.response.clone(), true)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
if agent.provider().await.is_err() {
|
||||
@@ -763,6 +768,100 @@ mod tests {
|
||||
assert_eq!(agent.goose_mode().await, mode);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_final_output_tool_restored_after_lru_eviction() {
|
||||
use crate::agents::final_output_tool::FINAL_OUTPUT_TOOL_NAME;
|
||||
use crate::recipe::{Recipe, Response};
|
||||
use serde_json::json;
|
||||
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let session_manager = Arc::new(SessionManager::new(temp_dir.path().to_path_buf()));
|
||||
let agent_config = AgentConfig::new(
|
||||
Arc::clone(&session_manager),
|
||||
PermissionManager::instance(),
|
||||
None,
|
||||
GooseMode::default(),
|
||||
false,
|
||||
GoosePlatform::GooseDesktop,
|
||||
);
|
||||
let manager = AgentManager::new(agent_config, Some(1)).await.unwrap();
|
||||
|
||||
let session = session_manager
|
||||
.create_session(
|
||||
temp_dir.path().to_path_buf(),
|
||||
"recipe-session".into(),
|
||||
crate::session::SessionType::User,
|
||||
GooseMode::default(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let recipe = Recipe {
|
||||
version: "1.0.0".into(),
|
||||
title: "Test".into(),
|
||||
description: "Test recipe".into(),
|
||||
response: Some(Response {
|
||||
json_schema: Some(json!({
|
||||
"type": "object",
|
||||
"properties": { "result": { "type": "string" } },
|
||||
"required": ["result"]
|
||||
})),
|
||||
}),
|
||||
instructions: None,
|
||||
prompt: None,
|
||||
extensions: None,
|
||||
settings: None,
|
||||
activities: None,
|
||||
author: None,
|
||||
parameters: None,
|
||||
sub_recipes: None,
|
||||
retry: None,
|
||||
};
|
||||
|
||||
session_manager
|
||||
.update(&session.id)
|
||||
.recipe(Some(recipe))
|
||||
.apply()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Fill the cache (capacity 1) then evict it
|
||||
let agent = manager
|
||||
.get_or_create_agent(session.id.clone())
|
||||
.await
|
||||
.unwrap();
|
||||
let tools = agent.list_tools(&session.id, None).await;
|
||||
assert!(
|
||||
tools
|
||||
.iter()
|
||||
.any(|t| t.name.as_ref() == FINAL_OUTPUT_TOOL_NAME),
|
||||
"final_output_tool must be present on first creation"
|
||||
);
|
||||
|
||||
// Evict by adding a second session
|
||||
manager
|
||||
.get_or_create_agent("evict-trigger".into())
|
||||
.await
|
||||
.unwrap();
|
||||
assert!(
|
||||
!manager.has_session(&session.id).await,
|
||||
"session should be evicted"
|
||||
);
|
||||
|
||||
// Recreate agent via slow path (create_agent_locked)
|
||||
let restored_agent = manager
|
||||
.get_or_create_agent(session.id.clone())
|
||||
.await
|
||||
.unwrap();
|
||||
let tools = restored_agent.list_tools(&session.id, None).await;
|
||||
assert!(
|
||||
tools
|
||||
.iter()
|
||||
.any(|t| t.name.as_ref() == FINAL_OUTPUT_TOOL_NAME),
|
||||
"final_output_tool must be restored after LRU eviction"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_session_mode_isolation() {
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
|
||||
Reference in New Issue
Block a user