use serde_json::Value;
use trusty_common::mcp::{Response, error_codes};
use super::SmDispatcher;
use super::methods::{self, CODE_NOT_FOUND, CODE_UNAVAILABLE, MethodError};
use trusty_common::mcp::Request;
pub async fn dispatch(d: &SmDispatcher, req: Request) -> Response {
if req.id.is_none() {
return Response::suppressed();
}
let id = req.id.clone();
let params = req.params.clone().unwrap_or(Value::Null);
let result: Result<Value, MethodError> = match req.method.as_str() {
"sm.chat" => methods::sm_chat(d, ¶ms).await,
"sm.delegate" => methods::sm_delegate(d, ¶ms).await,
"sm.health" => methods::sm_health(d, ¶ms).await,
"sm.goals.list" => methods::sm_goals_list(d, ¶ms).await,
"sm.goals.create" => methods::sm_goals_create(d, ¶ms).await,
"sm.goals.update" => methods::sm_goals_update(d, ¶ms).await,
"sm.sessions.launch" => methods::sm_sessions_launch(d, ¶ms).await,
"sm.sessions.list" => methods::sm_sessions_list(d, ¶ms).await,
"sm.sessions.get" => methods::sm_sessions_get(d, ¶ms).await,
"sm.sessions.send" => methods::sm_sessions_send(d, ¶ms).await,
"sm.sessions.stop" => methods::sm_sessions_stop(d, ¶ms).await,
"sm.sessions.resume" => methods::sm_sessions_resume(d, ¶ms).await,
"sm.sessions.kill" => methods::sm_sessions_kill(d, ¶ms).await,
"sm.context.get" => methods::sm_context_get(d, ¶ms).await,
other => {
return Response::err(
id,
error_codes::METHOD_NOT_FOUND,
format!("unknown SM method: {other}"),
);
}
};
match result {
Ok(value) => Response::ok(id, value),
Err(e) => Response::err(id, error_code_for(&e), e.to_string()),
}
}
fn error_code_for(e: &MethodError) -> i32 {
match e {
MethodError::InvalidParams(_) => error_codes::INVALID_PARAMS,
MethodError::NotFound(_) => CODE_NOT_FOUND,
MethodError::Unavailable(_) => CODE_UNAVAILABLE,
MethodError::Internal(_) => error_codes::INTERNAL_ERROR,
}
}