feat(goose-acp): enable parallel sessions with isolated agent state (#6392)
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This commit is contained in:
+69
-29
@@ -15,11 +15,15 @@ mod tests {
|
||||
use async_trait::async_trait;
|
||||
use chrono::{DateTime, Utc};
|
||||
use goose::agents::platform_tools::PLATFORM_MANAGE_SCHEDULE_TOOL_NAME;
|
||||
use goose::agents::AgentConfig;
|
||||
use goose::config::permission::PermissionManager;
|
||||
use goose::config::GooseMode;
|
||||
use goose::scheduler::{ScheduledJob, SchedulerError};
|
||||
use goose::scheduler_trait::SchedulerTrait;
|
||||
use goose::session::Session;
|
||||
use goose::session::{Session, SessionManager};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use tempfile::TempDir;
|
||||
|
||||
struct MockScheduler {
|
||||
jobs: tokio::sync::Mutex<Vec<ScheduledJob>>,
|
||||
@@ -114,12 +118,20 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_schedule_management_tool_list() {
|
||||
let agent = Agent::new();
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let data_dir = temp_dir.path().to_path_buf();
|
||||
let session_manager = Arc::new(SessionManager::new(data_dir.clone()));
|
||||
let permission_manager = Arc::new(PermissionManager::new(data_dir));
|
||||
let mock_scheduler = Arc::new(MockScheduler::new());
|
||||
agent.set_scheduler(mock_scheduler.clone()).await;
|
||||
let config = AgentConfig::new(
|
||||
session_manager,
|
||||
permission_manager,
|
||||
Some(mock_scheduler),
|
||||
GooseMode::Auto,
|
||||
);
|
||||
let agent = Agent::with_config(config);
|
||||
|
||||
// Test that the schedule management tool is available in the tools list
|
||||
let tools = agent.list_tools(None).await;
|
||||
let tools = agent.list_tools("test-session-id", None).await;
|
||||
let schedule_tool = tools
|
||||
.iter()
|
||||
.find(|tool| tool.name == PLATFORM_MANAGE_SCHEDULE_TOOL_NAME);
|
||||
@@ -137,7 +149,7 @@ mod tests {
|
||||
async fn test_no_schedule_management_tool_without_scheduler() {
|
||||
let agent = Agent::new();
|
||||
|
||||
let tools = agent.list_tools(None).await;
|
||||
let tools = agent.list_tools("test-session-id", None).await;
|
||||
let schedule_tool = tools
|
||||
.iter()
|
||||
.find(|tool| tool.name == PLATFORM_MANAGE_SCHEDULE_TOOL_NAME);
|
||||
@@ -146,11 +158,22 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_schedule_management_tool_in_platform_tools() {
|
||||
let agent = Agent::new();
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let data_dir = temp_dir.path().to_path_buf();
|
||||
let session_manager = Arc::new(SessionManager::new(data_dir.clone()));
|
||||
let permission_manager = Arc::new(PermissionManager::new(data_dir));
|
||||
let mock_scheduler = Arc::new(MockScheduler::new());
|
||||
agent.set_scheduler(mock_scheduler.clone()).await;
|
||||
let config = AgentConfig::new(
|
||||
session_manager,
|
||||
permission_manager,
|
||||
Some(mock_scheduler),
|
||||
GooseMode::Auto,
|
||||
);
|
||||
let agent = Agent::with_config(config);
|
||||
|
||||
let tools = agent.list_tools(Some("platform".to_string())).await;
|
||||
let tools = agent
|
||||
.list_tools("test-session-id", Some("platform".to_string()))
|
||||
.await;
|
||||
|
||||
// Check that the schedule management tool is included in platform tools
|
||||
let schedule_tool = tools
|
||||
@@ -188,11 +211,20 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_schedule_management_tool_schema_validation() {
|
||||
let agent = Agent::new();
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let data_dir = temp_dir.path().to_path_buf();
|
||||
let session_manager = Arc::new(SessionManager::new(data_dir.clone()));
|
||||
let permission_manager = Arc::new(PermissionManager::new(data_dir));
|
||||
let mock_scheduler = Arc::new(MockScheduler::new());
|
||||
agent.set_scheduler(mock_scheduler.clone()).await;
|
||||
let config = AgentConfig::new(
|
||||
session_manager,
|
||||
permission_manager,
|
||||
Some(mock_scheduler),
|
||||
GooseMode::Auto,
|
||||
);
|
||||
let agent = Agent::with_config(config);
|
||||
|
||||
let tools = agent.list_tools(None).await;
|
||||
let tools = agent.list_tools("test-session-id", None).await;
|
||||
let schedule_tool = tools
|
||||
.iter()
|
||||
.find(|tool| tool.name == PLATFORM_MANAGE_SCHEDULE_TOOL_NAME);
|
||||
@@ -307,7 +339,6 @@ mod tests {
|
||||
use goose::providers::base::{Provider, ProviderMetadata, ProviderUsage, Usage};
|
||||
use goose::providers::errors::ProviderError;
|
||||
use goose::session::session_manager::SessionType;
|
||||
use goose::session::SessionManager;
|
||||
use rmcp::model::{CallToolRequestParam, Tool};
|
||||
use rmcp::object;
|
||||
use std::path::PathBuf;
|
||||
@@ -379,12 +410,15 @@ mod tests {
|
||||
let provider = Arc::new(MockToolProvider::new());
|
||||
let user_message = Message::user().with_text("Hello");
|
||||
|
||||
let session = SessionManager::create_session(
|
||||
PathBuf::default(),
|
||||
"max-turn-test".to_string(),
|
||||
SessionType::Hidden,
|
||||
)
|
||||
.await?;
|
||||
let session = agent
|
||||
.config
|
||||
.session_manager
|
||||
.create_session(
|
||||
PathBuf::default(),
|
||||
"max-turn-test".to_string(),
|
||||
SessionType::Hidden,
|
||||
)
|
||||
.await?;
|
||||
|
||||
agent.update_provider(provider, &session.id).await?;
|
||||
|
||||
@@ -451,10 +485,14 @@ mod tests {
|
||||
#[cfg(test)]
|
||||
mod extension_manager_tests {
|
||||
use super::*;
|
||||
use goose::agents::extension::{ExtensionConfig, PlatformExtensionContext};
|
||||
use goose::agents::extension::ExtensionConfig;
|
||||
use goose::agents::extension_manager_extension::{
|
||||
MANAGE_EXTENSIONS_TOOL_NAME, SEARCH_AVAILABLE_EXTENSIONS_TOOL_NAME,
|
||||
};
|
||||
use goose::agents::AgentConfig;
|
||||
use goose::config::permission::PermissionManager;
|
||||
use goose::config::GooseMode;
|
||||
use goose::session::SessionManager;
|
||||
|
||||
async fn setup_agent_with_extension_manager() -> Agent {
|
||||
// Add the TODO extension to the config so it can be discovered by search_available_extensions
|
||||
@@ -472,15 +510,17 @@ mod tests {
|
||||
};
|
||||
set_extension(todo_extension_entry);
|
||||
|
||||
let agent = Agent::new();
|
||||
// Create agent with session_id from the start
|
||||
let temp_dir = tempfile::tempdir().unwrap();
|
||||
let session_manager = Arc::new(SessionManager::new(temp_dir.path().to_path_buf()));
|
||||
let config = AgentConfig::new(
|
||||
session_manager,
|
||||
PermissionManager::instance(),
|
||||
None,
|
||||
GooseMode::Auto,
|
||||
);
|
||||
|
||||
agent
|
||||
.extension_manager
|
||||
.set_context(PlatformExtensionContext {
|
||||
session_id: Some("test_session".to_string()),
|
||||
extension_manager: Some(Arc::downgrade(&agent.extension_manager)),
|
||||
})
|
||||
.await;
|
||||
let agent = Agent::with_config(config);
|
||||
|
||||
// Now add the extension manager platform extension
|
||||
let ext_config = ExtensionConfig::Platform {
|
||||
@@ -500,7 +540,7 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn test_extension_manager_tools_available() {
|
||||
let agent = setup_agent_with_extension_manager().await;
|
||||
let tools = agent.list_tools(None).await;
|
||||
let tools = agent.list_tools("test-session-id", None).await;
|
||||
|
||||
// Note: Tool names are prefixed with the normalized extension name "extensionmanager"
|
||||
// not the display name "Extension Manager"
|
||||
|
||||
Reference in New Issue
Block a user