diff options
| author | soryu <soryu@soryu.co> | 2026-02-04 01:59:40 +0000 |
|---|---|---|
| committer | soryu <soryu@soryu.co> | 2026-02-04 01:59:40 +0000 |
| commit | 612cecc5bd5dbfc73d4a3a9d38626378eaf39041 (patch) | |
| tree | e23a4772b5299082a99c5ec449cbe222dc038e98 /makima/src | |
| parent | 40f4c4ebbb41a46d83fa67fa43e6ec683ab7fdb2 (diff) | |
| download | soryu-612cecc5bd5dbfc73d4a3a9d38626378eaf39041.tar.gz soryu-612cecc5bd5dbfc73d4a3a9d38626378eaf39041.zip | |
Remove chain supervisor capability
Chains no longer spawn a supervisor task. Checkpoint contracts will be
automatically run as part of the DAG execution when dependencies complete.
- Remove supervisor task creation from start_chain handler
- Remove chain supervisor CLI commands
- Remove supervisor_task_id from StartChainResponse
- Remove withSupervisor option from frontend
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'makima/src')
| -rw-r--r-- | makima/src/bin/makima.rs | 89 | ||||
| -rw-r--r-- | makima/src/daemon/cli/mod.rs | 14 | ||||
| -rw-r--r-- | makima/src/daemon/cli/supervisor.rs | 63 | ||||
| -rw-r--r-- | makima/src/db/models.rs | 8 | ||||
| -rw-r--r-- | makima/src/db/repository.rs | 16 | ||||
| -rw-r--r-- | makima/src/server/handlers/chains.rs | 136 |
6 files changed, 6 insertions, 320 deletions
diff --git a/makima/src/bin/makima.rs b/makima/src/bin/makima.rs index fa5378f..2037b47 100644 --- a/makima/src/bin/makima.rs +++ b/makima/src/bin/makima.rs @@ -612,95 +612,6 @@ async fn run_supervisor( .await?; println!("{}", serde_json::to_string(&result.0)?); } - // Chain supervisor commands - SupervisorCommand::ChainStatus(args) => { - let client = ApiClient::new(args.common.api_url, args.common.api_key)?; - eprintln!("Getting chain status for {}...", args.common.chain_id); - let result = client.get_chain(args.common.chain_id).await?; - if args.verbose { - // Get contracts as well - let contracts = client.get_chain_contracts(args.common.chain_id).await?; - println!("{}", serde_json::to_string(&serde_json::json!({ - "chain": result.0, - "contracts": contracts.0 - }))?); - } else { - println!("{}", serde_json::to_string(&result.0)?); - } - } - SupervisorCommand::ChainContracts(args) => { - let client = ApiClient::new(args.common.api_url, args.common.api_key)?; - eprintln!("Listing contracts in chain {}...", args.common.chain_id); - let result = client.get_chain_contracts(args.common.chain_id).await?; - if let Some(status) = &args.status { - // Filter by status client-side - let empty_vec = vec![]; - let contracts: Vec<_> = result.0.as_array() - .unwrap_or(&empty_vec) - .iter() - .filter(|c| c.get("status").and_then(|s| s.as_str()) == Some(status.as_str())) - .collect(); - println!("{}", serde_json::to_string(&contracts)?); - } else { - println!("{}", serde_json::to_string(&result.0)?); - } - } - SupervisorCommand::ChainProgress(args) => { - let client = ApiClient::new(args.common.api_url, args.common.api_key)?; - eprintln!("Triggering chain progression for {}...", args.common.chain_id); - // Use the start endpoint to progress (it handles already-active chains) - let result = client.start_chain(args.common.chain_id).await; - match result { - Ok(r) => println!("{}", serde_json::to_string(&r.0)?), - Err(e) => { - // Check if already active - in that case, just get status - if e.to_string().contains("ALREADY_ACTIVE") { - eprintln!("Chain is already active, checking current status..."); - let status = client.get_chain(args.common.chain_id).await?; - println!("{}", serde_json::to_string(&status.0)?); - } else { - return Err(e.into()); - } - } - } - } - SupervisorCommand::ChainGraph(args) => { - let client = ApiClient::new(args.common.api_url, args.common.api_key)?; - let result = client.get_chain_graph(args.common.chain_id).await?; - if args.format == "json" { - println!("{}", serde_json::to_string(&result.0)?); - } else { - // ASCII visualization (similar to chain graph command) - if let Some(nodes) = result.0.get("nodes").and_then(|n| n.as_array()) { - // Group by depth - let mut by_depth: std::collections::BTreeMap<i64, Vec<(&str, &str)>> = - std::collections::BTreeMap::new(); - for node in nodes { - let name = node.get("name").and_then(|n| n.as_str()).unwrap_or("?"); - let status = node.get("status").and_then(|s| s.as_str()).unwrap_or("pending"); - let depth = node.get("depth").and_then(|d| d.as_i64()).unwrap_or(0); - by_depth.entry(depth).or_default().push((name, status)); - } - let chain_name = result.0.get("name").and_then(|v| v.as_str()).unwrap_or("Chain"); - println!("Chain: {}", chain_name); - println!(); - for (depth, contracts) in by_depth { - let prefix = " ".repeat(depth as usize); - for (name, status) in contracts { - let icon = match status { - "completed" => "\u{2713}", - "active" => "\u{21bb}", - "failed" => "\u{2717}", - _ => "\u{25cb}", - }; - println!("{}[{}] {} ({})", prefix, icon, name, status); - } - } - } else { - println!("{}", serde_json::to_string(&result.0)?); - } - } - } } Ok(()) diff --git a/makima/src/daemon/cli/mod.rs b/makima/src/daemon/cli/mod.rs index 25163c2..035a784 100644 --- a/makima/src/daemon/cli/mod.rs +++ b/makima/src/daemon/cli/mod.rs @@ -170,20 +170,6 @@ pub enum SupervisorCommand { /// Mark a deliverable as complete MarkDeliverable(supervisor::MarkDeliverableArgs), - - // Chain supervisor commands (for chain-level orchestration) - - /// Get chain status with progress info - ChainStatus(supervisor::ChainStatusArgs), - - /// List contracts in the chain - ChainContracts(supervisor::ChainContractsArgs), - - /// Manually trigger chain progression - ChainProgress(supervisor::ChainProgressArgs), - - /// Get chain DAG visualization - ChainGraph(supervisor::ChainGraphArgs), } /// Contract subcommands for task-contract interaction. diff --git a/makima/src/daemon/cli/supervisor.rs b/makima/src/daemon/cli/supervisor.rs index 0b52c9c..82d3900 100644 --- a/makima/src/daemon/cli/supervisor.rs +++ b/makima/src/daemon/cli/supervisor.rs @@ -446,66 +446,3 @@ pub struct ResumeContractArgs { pub contract_id: Uuid, } -// ============================================================================ -// Chain Supervisor Command Args -// ============================================================================ - -/// Common arguments for chain supervisor commands. -#[derive(Args, Debug, Clone)] -pub struct ChainSupervisorArgs { - /// API URL - #[arg(long, env = "MAKIMA_API_URL", default_value = "https://api.makima.jp")] - pub api_url: String, - - /// API key for authentication - #[arg(long, env = "MAKIMA_API_KEY")] - pub api_key: String, - - /// Current task ID (the chain supervisor's own task ID) - #[arg(long, env = "MAKIMA_TASK_ID")] - pub self_task_id: Option<Uuid>, - - /// Chain ID - #[arg(long, env = "MAKIMA_CHAIN_ID")] - pub chain_id: Uuid, -} - -/// Arguments for chain-status command (get chain status with progress info). -#[derive(Args, Debug)] -pub struct ChainStatusArgs { - #[command(flatten)] - pub common: ChainSupervisorArgs, - - /// Include contract details - #[arg(long)] - pub verbose: bool, -} - -/// Arguments for chain-contracts command (list contracts in the chain). -#[derive(Args, Debug)] -pub struct ChainContractsArgs { - #[command(flatten)] - pub common: ChainSupervisorArgs, - - /// Filter by status (active, completed, failed) - #[arg(long)] - pub status: Option<String>, -} - -/// Arguments for chain-progress command (manually trigger chain progression). -#[derive(Args, Debug)] -pub struct ChainProgressArgs { - #[command(flatten)] - pub common: ChainSupervisorArgs, -} - -/// Arguments for chain-graph command (get chain DAG visualization). -#[derive(Args, Debug)] -pub struct ChainGraphArgs { - #[command(flatten)] - pub common: ChainSupervisorArgs, - - /// Output format (ascii, json) - #[arg(long, default_value = "ascii")] - pub format: String, -} diff --git a/makima/src/db/models.rs b/makima/src/db/models.rs index 0b8ef43..4e569ec 100644 --- a/makima/src/db/models.rs +++ b/makima/src/db/models.rs @@ -3064,14 +3064,11 @@ pub struct UpdateContractDefinitionRequest { pub editor_y: Option<f64>, } -/// Request to start a chain +/// Request to start a chain (kept for backwards compatibility) #[derive(Debug, Clone, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] pub struct StartChainRequest { - /// Whether to create a supervisor task that monitors chain progress - #[serde(default)] - pub with_supervisor: bool, - /// Repository URL for the supervisor task to work with + /// Repository URL (reserved for future use) pub repository_url: Option<String>, } @@ -3080,7 +3077,6 @@ pub struct StartChainRequest { #[serde(rename_all = "camelCase")] pub struct StartChainResponse { pub chain_id: Uuid, - pub supervisor_task_id: Option<Uuid>, /// Root contracts created (those with no dependencies) pub contracts_created: Vec<Uuid>, pub status: String, diff --git a/makima/src/db/repository.rs b/makima/src/db/repository.rs index fb430ab..ec233ba 100644 --- a/makima/src/db/repository.rs +++ b/makima/src/db/repository.rs @@ -5687,22 +5687,6 @@ pub async fn get_chain_definition_graph( })) } -/// Set the supervisor task ID for a chain. -pub async fn set_chain_supervisor_task( - pool: &PgPool, - chain_id: Uuid, - supervisor_task_id: Option<Uuid>, -) -> Result<(), sqlx::Error> { - sqlx::query( - "UPDATE chains SET supervisor_task_id = $2, updated_at = NOW() WHERE id = $1", - ) - .bind(chain_id) - .bind(supervisor_task_id) - .execute(pool) - .await?; - Ok(()) -} - /// Update chain status. pub async fn update_chain_status( pool: &PgPool, diff --git a/makima/src/server/handlers/chains.rs b/makima/src/server/handlers/chains.rs index ae19ca0..6cef72c 100644 --- a/makima/src/server/handlers/chains.rs +++ b/makima/src/server/handlers/chains.rs @@ -15,8 +15,8 @@ use uuid::Uuid; use crate::db::models::{ AddContractDefinitionRequest, ChainContractDefinition, ChainContractDetail, ChainDefinitionGraphResponse, ChainEditorData, ChainEvent, ChainGraphResponse, ChainSummary, - ChainWithContracts, CreateChainRequest, CreateTaskRequest, StartChainRequest, - StartChainResponse, UpdateChainRequest, UpdateContractDefinitionRequest, + ChainWithContracts, CreateChainRequest, StartChainRequest, StartChainResponse, + UpdateChainRequest, UpdateContractDefinitionRequest, }; use crate::db::repository::{self, RepositoryError}; use crate::server::auth::Authenticated; @@ -1067,7 +1067,7 @@ pub async fn start_chain( State(state): State<SharedState>, Authenticated(auth): Authenticated, Path(chain_id): Path<Uuid>, - body: Option<Json<StartChainRequest>>, + _body: Option<Json<StartChainRequest>>, ) -> impl IntoResponse { let Some(ref pool) = state.db_pool else { return ( @@ -1077,11 +1077,6 @@ pub async fn start_chain( .into_response(); }; - let req = body.map(|b| b.0).unwrap_or(StartChainRequest { - with_supervisor: false, - repository_url: None, - }); - // Verify ownership and get chain let chain = match repository::get_chain_for_owner(pool, chain_id, auth.owner_id).await { Ok(Some(c)) => c, @@ -1152,114 +1147,6 @@ pub async fn start_chain( } } - // Create supervisor task if requested - let mut supervisor_task_id: Option<Uuid> = None; - if req.with_supervisor { - let supervisor_name = format!("Chain Supervisor: {}", chain.name); - let supervisor_plan = format!( - r#"You are the supervisor for chain "{}". - -## Environment Variables -- MAKIMA_CHAIN_ID={} -- MAKIMA_API_URL (configured) -- MAKIMA_API_KEY (configured) - -## Your Responsibilities -1. Monitor chain progress by periodically checking chain status -2. Validate that contracts are completing successfully -3. Identify and report any issues or blockers -4. Track the overall chain progress through the DAG - -## Available Commands -Use these makima CLI commands to monitor the chain: - -```bash -# Check chain status -makima chain status {} - -# List contracts in the chain -makima chain contracts {} - -# View the chain DAG with current status -makima chain graph {} --with-status -``` - -## Monitoring Loop -1. Check chain status every few minutes -2. If a contract fails, investigate the issue -3. Report progress to the user when milestones are reached -4. Mark the chain as complete when all contracts finish - -## Current Chain Info -- Chain ID: {} -- Chain Name: {} -- Total definitions: {} - -Begin monitoring the chain. Check the initial status and report what you find."#, - chain.name, - chain_id, - chain_id, - chain_id, - chain_id, - chain_id, - chain.name, - definitions.len() - ); - - let supervisor_req = CreateTaskRequest { - name: supervisor_name, - description: Some(format!("Supervisor task for chain: {}", chain.name)), - plan: supervisor_plan, - repository_url: req.repository_url.clone(), - base_branch: None, - target_branch: None, - parent_task_id: None, - contract_id: None, // Chain supervisor is not tied to a specific contract - target_repo_path: None, - completion_action: None, - continue_from_task_id: None, - copy_files: None, - is_supervisor: true, - checkpoint_sha: None, - priority: 0, - merge_mode: None, - branched_from_task_id: None, - conversation_history: None, - supervisor_worktree_task_id: None, - }; - - match repository::create_task_for_owner(pool, auth.owner_id, supervisor_req).await { - Ok(supervisor_task) => { - tracing::info!( - chain_id = %chain_id, - supervisor_task_id = %supervisor_task.id, - "Created supervisor task for chain" - ); - - // Update chain with supervisor_task_id - if let Err(e) = - repository::set_chain_supervisor_task(pool, chain_id, Some(supervisor_task.id)) - .await - { - tracing::warn!( - chain_id = %chain_id, - error = %e, - "Failed to link supervisor task to chain" - ); - } - - supervisor_task_id = Some(supervisor_task.id); - } - Err(e) => { - tracing::warn!( - chain_id = %chain_id, - error = %e, - "Failed to create supervisor task for chain" - ); - } - } - } - // Progress the chain - this creates root contracts (definitions with no dependencies) let progression = match repository::progress_chain(pool, chain_id, auth.owner_id).await { Ok(p) => p, @@ -1268,7 +1155,6 @@ Begin monitoring the chain. Check the initial status and report what you find."# // Chain is active but no contracts created - return partial success return Json(StartChainResponse { chain_id, - supervisor_task_id, contracts_created: vec![], status: "active".to_string(), }) @@ -1278,7 +1164,6 @@ Begin monitoring the chain. Check the initial status and report what you find."# Json(StartChainResponse { chain_id, - supervisor_task_id, contracts_created: progression.contracts_created, status: if progression.chain_completed { "completed".to_string() @@ -1357,20 +1242,7 @@ pub async fn stop_chain( .into_response(); } - // TODO: Kill the supervisor task if running - // Clear supervisor task ID and set status to archived - match repository::set_chain_supervisor_task(pool, chain_id, None).await { - Ok(_) => {} - Err(e) => { - tracing::error!("Failed to clear chain supervisor: {}", e); - return ( - StatusCode::INTERNAL_SERVER_ERROR, - Json(ApiError::new("DB_ERROR", e.to_string())), - ) - .into_response(); - } - } - + // Archive the chain match repository::update_chain_status(pool, chain_id, "archived").await { Ok(_) => Json(serde_json::json!({"stopped": true, "status": "archived"})).into_response(), Err(e) => { |
