From 657a8e55796c9f0cc6f30937de545ed91f052063 Mon Sep 17 00:00:00 2001 From: soryu Date: Sun, 8 Feb 2026 12:32:53 +0000 Subject: Fixes for directive chain init --- makima/src/server/handlers/directives.rs | 61 +++++++++++++++++++++++++++++++- makima/src/server/mod.rs | 1 + makima/src/server/openapi.rs | 4 ++- 3 files changed, 64 insertions(+), 2 deletions(-) (limited to 'makima/src/server') diff --git a/makima/src/server/handlers/directives.rs b/makima/src/server/handlers/directives.rs index 65f32d5..3f62a33 100644 --- a/makima/src/server/handlers/directives.rs +++ b/makima/src/server/handlers/directives.rs @@ -13,7 +13,7 @@ use std::collections::HashMap; use crate::db::models::{ ChainStep, ChainStepWithContract, ChainWithSteps, CreateDirectiveRequest, Directive, DirectiveChain, DirectiveListResponse, DirectiveWithChains, EvaluationListResponse, - StepContractSummary, UpdateDirectiveRequest, + StepContractSummary, SubmitPlanRequest, UpdateDirectiveRequest, }; use crate::db::repository::{self, RepositoryError}; use crate::orchestration; @@ -724,3 +724,62 @@ pub async fn list_evaluations( } } } + +/// Submit a chain plan for a directive. +#[utoipa::path( + post, + path = "/api/v1/directives/{id}/submit-plan", + params( + ("id" = Uuid, Path, description = "Directive ID") + ), + request_body = SubmitPlanRequest, + responses( + (status = 200, description = "Plan submitted, directive active", body = Directive), + (status = 400, description = "Invalid request or status", body = ApiError), + (status = 401, description = "Unauthorized", body = ApiError), + (status = 404, description = "Directive not found", body = ApiError), + (status = 503, description = "Database not configured", body = ApiError), + (status = 500, description = "Internal server error", body = ApiError), + ), + security( + ("bearer_auth" = []), + ("api_key" = []) + ), + tag = "Directives" +)] +pub async fn submit_plan( + State(state): State, + Authenticated(auth): Authenticated, + Path(id): Path, + Json(req): Json, +) -> impl IntoResponse { + let Some(ref pool) = state.db_pool else { + return ( + StatusCode::SERVICE_UNAVAILABLE, + Json(ApiError::new("DB_UNAVAILABLE", "Database not configured")), + ) + .into_response(); + }; + + match orchestration::directive::submit_plan(pool, &state, auth.owner_id, id, &req.plan).await { + Ok(directive) => Json(directive).into_response(), + Err(e) if e.contains("not found") || e.contains("Not found") => ( + StatusCode::NOT_FOUND, + Json(ApiError::new("NOT_FOUND", e)), + ) + .into_response(), + Err(e) if e.contains("must be in 'planning'") || e.contains("no steps") => ( + StatusCode::BAD_REQUEST, + Json(ApiError::new("INVALID_REQUEST", e)), + ) + .into_response(), + Err(e) => { + tracing::error!("Failed to submit plan for directive {}: {}", id, e); + ( + StatusCode::INTERNAL_SERVER_ERROR, + Json(ApiError::new("SUBMIT_PLAN_FAILED", e)), + ) + .into_response() + } + } +} diff --git a/makima/src/server/mod.rs b/makima/src/server/mod.rs index c8242ae..0cad050 100644 --- a/makima/src/server/mod.rs +++ b/makima/src/server/mod.rs @@ -184,6 +184,7 @@ pub fn make_router(state: SharedState) -> Router { .route("/directives/{id}/start", post(directives::start_directive)) .route("/directives/{id}/chains", get(directives::list_chains)) .route("/directives/{id}/chains/{chain_id}", get(directives::get_chain)) + .route("/directives/{id}/submit-plan", post(directives::submit_plan)) .route("/directives/{id}/steps/{step_id}/evaluate", post(directives::evaluate_step)) .route("/directives/{id}/steps/{step_id}/evaluations", get(directives::list_evaluations)) // Contract supervisor resume endpoints diff --git a/makima/src/server/openapi.rs b/makima/src/server/openapi.rs index e680c07..888269f 100644 --- a/makima/src/server/openapi.rs +++ b/makima/src/server/openapi.rs @@ -17,7 +17,7 @@ use crate::db::models::{ MergeSkipRequest, MergeStartRequest, MergeStatusResponse, MeshChatConversation, MeshChatHistoryResponse, MeshChatMessageRecord, RepositoryHistoryEntry, RepositoryHistoryListResponse, RepositorySuggestionsQuery, SendMessageRequest, - StepContractSummary, Task, + StepContractSummary, SubmitPlanRequest, Task, TaskEventListResponse, TaskListResponse, TaskSummary, TaskWithSubtasks, TranscriptEntry, UpdateContractRequest, UpdateDirectiveRequest, UpdateFileRequest, UpdateTaskRequest, }; @@ -119,6 +119,7 @@ use crate::server::messages::{ApiError, AudioEncoding, StartMessage, StopMessage directives::get_chain, directives::evaluate_step, directives::list_evaluations, + directives::submit_plan, ), components( schemas( @@ -215,6 +216,7 @@ use crate::server::messages::{ApiError, AudioEncoding, StartMessage, StopMessage StepContractSummary, CreateDirectiveRequest, UpdateDirectiveRequest, + SubmitPlanRequest, DirectiveEvaluation, DirectiveEvent, EvaluationListResponse, -- cgit v1.2.3