feat(gateway): PUT/DELETE /api/memories/{key} write endpoints
This commit is contained in:
parent
3f09793864
commit
b49f0ec8a5
@ -947,6 +947,49 @@ pub async fn get_memories(
|
||||
Ok(Json(json!({ "memories": memories })))
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct PutMemoryBody {
|
||||
content: String,
|
||||
importance: Option<f64>,
|
||||
}
|
||||
|
||||
pub async fn put_memory(
|
||||
State(state): State<Arc<GatewayState>>,
|
||||
Path(key): Path<String>,
|
||||
Json(body): Json<PutMemoryBody>,
|
||||
) -> Result<Json<Value>, ApiError> {
|
||||
let existing = state
|
||||
.storage
|
||||
.get_memory_by_key(&key)
|
||||
.await
|
||||
.map_err(ApiError::internal)?
|
||||
.ok_or_else(|| ApiError::not_found("memory not found"))?;
|
||||
let mut updated = existing;
|
||||
updated.content = body.content;
|
||||
if let Some(importance) = body.importance {
|
||||
updated.importance = importance.clamp(0.0, 1.0);
|
||||
}
|
||||
updated.updated_at = chrono::Utc::now().to_rfc3339();
|
||||
state
|
||||
.storage
|
||||
.upsert_memory(&updated)
|
||||
.await
|
||||
.map_err(ApiError::internal)?;
|
||||
Ok(Json(json!({ "updated": true, "key": key })))
|
||||
}
|
||||
|
||||
pub async fn delete_memory(
|
||||
State(state): State<Arc<GatewayState>>,
|
||||
Path(key): Path<String>,
|
||||
) -> Result<Json<Value>, ApiError> {
|
||||
state
|
||||
.storage
|
||||
.delete_memory(&key)
|
||||
.await
|
||||
.map_err(ApiError::internal)?;
|
||||
Ok(Json(json!({ "deleted": true })))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
@ -599,6 +599,10 @@ fn build_router(state: Arc<GatewayState>) -> Router {
|
||||
.route("/api/jobs", routing::get(http::get_jobs))
|
||||
.route("/api/jobs/{id}/runs", routing::get(http::get_job_runs))
|
||||
.route("/api/memories", routing::get(http::get_memories))
|
||||
.route(
|
||||
"/api/memories/{key}",
|
||||
routing::put(http::put_memory).delete(http::delete_memory),
|
||||
)
|
||||
.route(
|
||||
"/api/chat/{client_id}/uploads",
|
||||
routing::post(http::upload_file).layer(axum::extract::DefaultBodyLimit::disable()),
|
||||
|
||||
@ -42,6 +42,17 @@ impl super::Storage {
|
||||
parse_memory_rows(&rows)
|
||||
}
|
||||
|
||||
pub async fn get_memory_by_key(&self, key: &str) -> Result<Option<MemoryEntry>, StorageError> {
|
||||
let rows = sqlx::query(
|
||||
"SELECT id, key, content, category, importance, session_id, created_at, updated_at FROM memories WHERE key = ?",
|
||||
)
|
||||
.bind(key)
|
||||
.fetch_all(self.pool())
|
||||
.await?;
|
||||
let mut entries = parse_memory_rows(&rows)?;
|
||||
Ok(entries.pop())
|
||||
}
|
||||
|
||||
/// Store or update a memory entry (upsert by key).
|
||||
pub async fn upsert_memory(&self, entry: &MemoryEntry) -> Result<(), StorageError> {
|
||||
let category_str = entry.category.as_str();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user