diff --git a/crates/goose-server/src/commands/agent.rs b/crates/goose-server/src/commands/agent.rs
index 619451a7cdff..104e3b8128e6 100644
--- a/crates/goose-server/src/commands/agent.rs
+++ b/crates/goose-server/src/commands/agent.rs
@@ -29,7 +29,10 @@ pub async fn run() -> Result<()> {
.join("schedules.json");
let scheduler_instance = SchedulerFactory::create(schedule_file_path).await?;
- app_state.set_scheduler(scheduler_instance).await;
+ app_state.set_scheduler(scheduler_instance.clone()).await;
+
+ // NEW: Provide scheduler access to the agent
+ agent_ref.set_scheduler(scheduler_instance).await;
let cors = CorsLayer::new()
.allow_origin(Any)
diff --git a/crates/goose-server/src/routes/schedule.rs b/crates/goose-server/src/routes/schedule.rs
index cb1199ded702..9b4433c52ee4 100644
--- a/crates/goose-server/src/routes/schedule.rs
+++ b/crates/goose-server/src/routes/schedule.rs
@@ -93,6 +93,8 @@ fn parse_session_name_to_iso(session_name: &str) -> String {
request_body = CreateScheduleRequest,
responses(
(status = 200, description = "Scheduled job created successfully", body = ScheduledJob),
+ (status = 400, description = "Invalid cron expression or recipe file"),
+ (status = 409, description = "Job ID already exists"),
(status = 500, description = "Internal server error")
),
tag = "schedule"
@@ -128,7 +130,13 @@ async fn create_schedule(
.await
.map_err(|e| {
eprintln!("Error creating schedule: {:?}", e); // Log error
- StatusCode::INTERNAL_SERVER_ERROR
+ match e {
+ goose::scheduler::SchedulerError::JobNotFound(_) => StatusCode::NOT_FOUND,
+ goose::scheduler::SchedulerError::CronParseError(_) => StatusCode::BAD_REQUEST,
+ goose::scheduler::SchedulerError::RecipeLoadError(_) => StatusCode::BAD_REQUEST,
+ goose::scheduler::SchedulerError::JobIdExists(_) => StatusCode::CONFLICT,
+ _ => StatusCode::INTERNAL_SERVER_ERROR,
+ }
})?;
Ok(Json(job))
}
diff --git a/crates/goose/src/agents/agent.rs b/crates/goose/src/agents/agent.rs
index 9b7a8394e1ba..3f56dacc230b 100644
--- a/crates/goose/src/agents/agent.rs
+++ b/crates/goose/src/agents/agent.rs
@@ -17,6 +17,7 @@ use crate::permission::PermissionConfirmation;
use crate::providers::base::Provider;
use crate::providers::errors::ProviderError;
use crate::recipe::{Author, Recipe, Settings};
+use crate::scheduler_trait::SchedulerTrait;
use crate::tool_monitor::{ToolCall, ToolMonitor};
use regex::Regex;
use serde_json::Value;
@@ -27,7 +28,8 @@ use crate::agents::extension::{ExtensionConfig, ExtensionError, ExtensionResult,
use crate::agents::extension_manager::{get_parameter_names, ExtensionManager};
use crate::agents::platform_tools::{
PLATFORM_LIST_RESOURCES_TOOL_NAME, PLATFORM_MANAGE_EXTENSIONS_TOOL_NAME,
- PLATFORM_READ_RESOURCE_TOOL_NAME, PLATFORM_SEARCH_AVAILABLE_EXTENSIONS_TOOL_NAME,
+ PLATFORM_MANAGE_SCHEDULE_TOOL_NAME, PLATFORM_READ_RESOURCE_TOOL_NAME,
+ PLATFORM_SEARCH_AVAILABLE_EXTENSIONS_TOOL_NAME,
};
use crate::agents::prompt_manager::PromptManager;
use crate::agents::router_tool_selector::{
@@ -59,6 +61,7 @@ pub struct Agent {
pub(super) tool_result_rx: ToolResultReceiver,
pub(super) tool_monitor: Mutex