Skip to main content

fastskill_core/http/handlers/
resolve.rs

1//! Resolve endpoint handler
2
3use crate::core::context_resolver::ResolveContextRequest;
4use crate::http::errors::{HttpError, HttpResult};
5use crate::http::handlers::AppState;
6use crate::http::models::ApiResponse;
7use axum::{extract::State, Json};
8use std::collections::HashMap;
9
10/// POST /api/resolve - Resolve skills with canonical paths and optional content
11pub async fn resolve_context(
12    State(state): State<AppState>,
13    Json(request): Json<ResolveContextRequest>,
14) -> HttpResult<axum::Json<ApiResponse<crate::core::context_resolver::ResolveContextResponse>>> {
15    if request.prompt.trim().is_empty() {
16        let mut errs = HashMap::new();
17        errs.insert(
18            "prompt".to_string(),
19            vec!["RESOLVE_EMPTY_PROMPT: prompt cannot be empty".to_string()],
20        );
21        return Err(HttpError::ValidationError(errs));
22    }
23
24    if request.limit == 0 {
25        let mut errs = HashMap::new();
26        errs.insert(
27            "limit".to_string(),
28            vec!["RESOLVE_LIMIT_ZERO: limit must be greater than 0".to_string()],
29        );
30        return Err(HttpError::ValidationError(errs));
31    }
32
33    let resolver = state.service.context_resolver();
34    let response = resolver
35        .resolve_context(request)
36        .await
37        .map_err(|e| HttpError::ServiceError(e.to_string()))?;
38
39    Ok(axum::Json(ApiResponse::success(response)))
40}