diff --git a/src/api/server.rs b/src/api/server.rs index 99e6f8a33..7e4f0285a 100644 --- a/src/api/server.rs +++ b/src/api/server.rs @@ -7,6 +7,7 @@ use super::{ }; use axum::Json; + use axum::Router; use axum::extract::{DefaultBodyLimit, Request, State}; use axum::http::{StatusCode, Uri, header}; @@ -158,6 +159,7 @@ pub async fn start_http_server( .route("/update/apply", post(settings::update_apply)) .route("/webchat/send", post(webchat::webchat_send)) .route("/webchat/history", get(webchat::webchat_history)) + .layer(DefaultBodyLimit::max(10 * 1024 * 1024)) .layer(middleware::from_fn_with_state( state.clone(), api_auth_middleware, diff --git a/src/tools/memory_save.rs b/src/tools/memory_save.rs index f84ed82f0..31a398fc6 100644 --- a/src/tools/memory_save.rs +++ b/src/tools/memory_save.rs @@ -9,6 +9,10 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use std::sync::Arc; +/// Maximum allowed memory content length (bytes). Prevents oversized memories +/// from bloating the database and embedding index. +const MAX_MEMORY_CONTENT_BYTES: usize = 50_000; + /// Tool for saving memories to the store. #[derive(Debug, Clone)] pub struct MemorySaveTool { @@ -160,6 +164,25 @@ impl Tool for MemorySaveTool { } async fn call(&self, args: Self::Args) -> std::result::Result { + if args.content.is_empty() { + return Err(MemorySaveError("content must not be empty".into())); + } + + if args.content.len() > MAX_MEMORY_CONTENT_BYTES { + return Err(MemorySaveError(format!( + "content exceeds maximum length of {MAX_MEMORY_CONTENT_BYTES} bytes (got {})", + args.content.len() + ))); + } + + if let Some(importance) = args.importance { + if !(0.0..=1.0).contains(&importance) { + return Err(MemorySaveError(format!( + "importance must be between 0.0 and 1.0 (got {importance})" + ))); + } + } + // Parse memory type let memory_type = match args.memory_type.as_str() { "fact" => MemoryType::Fact,