use super::{get_bool, get_string, make_tool_with_prompts};
use crate::config::{AutoAdvanceConfig, DependenciesConfig, Prompts, StatesConfig};
use crate::db::Database;
use crate::error::ToolError;
use anyhow::Result;
use rmcp::model::Tool;
use serde_json::{json, Value};
pub fn get_tools(prompts: &Prompts, _states_config: &StatesConfig) -> Vec<Tool> {
vec![
make_tool_with_prompts(
"claim",
"Commit to working on a task (like adding to a changelist). Fails if: already claimed, deps unsatisfied, or worker lacks required tags. Sets status to timed (working) status.",
json!({
"worker_id": {
"type": "string",
"description": "Worker ID claiming the task"
},
"task": {
"type": "string",
"description": "Task ID to claim"
},
"force": {
"type": "boolean",
"description": "Force claim even if owned by another agent (default: false)"
}
}),
vec!["worker_id", "task"],
prompts,
),
]
}
pub fn claim(
db: &Database,
states_config: &StatesConfig,
deps_config: &DependenciesConfig,
auto_advance: &AutoAdvanceConfig,
args: Value,
) -> Result<Value> {
let worker_id = get_string(&args, "worker_id")
.ok_or_else(|| ToolError::missing_field("worker_id"))?;
let task_id = get_string(&args, "task")
.ok_or_else(|| ToolError::missing_field("task"))?;
let force = get_bool(&args, "force").unwrap_or(false);
let claim_status = states_config
.definitions
.iter()
.find(|(_, def)| def.timed)
.map(|(name, _)| name.clone())
.unwrap_or_else(|| "in_progress".to_string());
let (task, _unblocked, _auto_advanced) = db.update_task_unified(
&task_id,
&worker_id,
None, None, None, Some(claim_status), None, None, None, None, None, None, None, force,
states_config,
deps_config,
auto_advance,
)?;
Ok(json!({
"success": true,
"task": {
"id": &task.id,
"title": task.title,
"status": task.status,
"worker_id": task.worker_id,
"claimed_at": task.claimed_at
}
}))
}