engram_core/
config_handler.rs1use std::sync::Arc;
2
3use serde::Deserialize;
4use serde_json::{Value, json};
5
6use crate::error::CoreError;
7use crate::server::ServerState;
8
9#[derive(Deserialize)]
10struct ConfigParams {
11 action: String,
12}
13
14pub async fn handle(state: &Arc<ServerState>, params: Value) -> Result<Value, CoreError> {
15 let parsed: ConfigParams = serde_json::from_value(params)
16 .map_err(|error| CoreError::DispatchError(error.to_string()))?;
17 match parsed.action.as_str() {
18 "get" => Ok(sanitized_config(&state.config)),
19 "set" => Err(CoreError::ConfigReadOnly),
20 other => Err(CoreError::DispatchError(format!(
21 "invalid config action: {other}"
22 ))),
23 }
24}
25
26fn sanitized_config(config: &crate::config::Config) -> Value {
27 json!({
28 "database": { "path": config.database.path },
29 "embedding": {
30 "provider": config.embedding.provider,
31 "model": config.embedding.model,
32 "dimension": config.embedding.dimension,
33 "has_api_key": config.embedding.api_key.as_deref().is_some_and(|k| !k.is_empty()),
34 },
35 "llm": {
36 "provider": config.llm.provider,
37 "model": config.llm.model,
38 "has_api_key": config.llm.api_key.as_deref().is_some_and(|k| !k.is_empty()),
39 },
40 "server": {
41 "socket_path": config.server.socket_path,
42 "reindex_interval_secs": config.server.reindex_interval_secs,
43 },
44 "hnsw": {
45 "max_connections": config.hnsw.max_connections,
46 "ef_construction": config.hnsw.ef_construction,
47 "ef_search": config.hnsw.ef_search,
48 "dimension": config.hnsw.dimension,
49 },
50 "consolidation": {
51 "stale_days": config.consolidation.stale_days,
52 "min_score": config.consolidation.min_score,
53 "fts_similarity_floor": config.consolidation.fts_similarity_floor,
54 },
55 })
56}