增强: 任务查询支持按状态过滤(list_tasks status)
- AI 工具 list_tasks: schema 加 status 参数 + handler 内存过滤 (todo/in_progress/in_review/testing/blocked/done/cancelled) - df-mcp list_tasks: handler 加 status 过滤(MCP 对外一致) (spec 声明待补:中文 Edit 编码匹配限制,后续补) 自验: workspace EXIT 0 + df-mcp cargo check EXIT 0
This commit is contained in:
@@ -346,12 +346,16 @@ fn bind_directory(ctx: &Ctx, args: Value) -> BoxFuture<'static, CallToolResult>
|
|||||||
fn list_tasks(ctx: &Ctx, args: Value) -> BoxFuture<'static, CallToolResult> {
|
fn list_tasks(ctx: &Ctx, args: Value) -> BoxFuture<'static, CallToolResult> {
|
||||||
let db = ctx.db.clone();
|
let db = ctx.db.clone();
|
||||||
let project_id_filter = args.get("project_id").and_then(|v| v.as_str()).map(|s| s.to_owned());
|
let project_id_filter = args.get("project_id").and_then(|v| v.as_str()).map(|s| s.to_owned());
|
||||||
|
let status_filter = args.get("status").and_then(|v| v.as_str()).map(|s| s.to_owned());
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let repo = TaskRepo::new(&db);
|
let repo = TaskRepo::new(&db);
|
||||||
match repo.list_active().await {
|
match repo.list_active().await {
|
||||||
Ok(mut list) => {
|
Ok(mut list) => {
|
||||||
if let Some(pid) = project_id_filter {
|
if let Some(pid) = &project_id_filter {
|
||||||
list.retain(|t| t.project_id == pid);
|
list.retain(|t| t.project_id == *pid);
|
||||||
|
}
|
||||||
|
if let Some(st) = &status_filter {
|
||||||
|
list.retain(|t| t.status == *st);
|
||||||
}
|
}
|
||||||
json_ok(json!({ "tasks": list, "count": list.len() }))
|
json_ok(json!({ "tasks": list, "count": list.len() }))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -605,17 +605,21 @@ fn register_project_tools(registry: &mut AiToolRegistry, db: &Arc<Database>) {
|
|||||||
/// 组内顺序保留原相对顺序(list/create/update/advance/delete/get_count)。
|
/// 组内顺序保留原相对顺序(list/create/update/advance/delete/get_count)。
|
||||||
fn register_task_tools(registry: &mut AiToolRegistry, db: &Arc<Database>) {
|
fn register_task_tools(registry: &mut AiToolRegistry, db: &Arc<Database>) {
|
||||||
registry.register(
|
registry.register(
|
||||||
"list_tasks", "列出任务,可按 project_id 筛选,支持 offset/limit 分页。返回 items、total、has_more。默认 limit=50",
|
"list_tasks", "列出任务,可按 project_id/status 筛选(status: todo/in_progress/in_review/testing/blocked/done/cancelled),支持 offset/limit 分页。返回 items、total、has_more。默认 limit=50",
|
||||||
df_ai::ai_tools::object_schema(vec![("project_id", "string", false), ("offset", "integer", false), ("limit", "integer", false)]), RiskLevel::Low,
|
df_ai::ai_tools::object_schema(vec![("project_id", "string", false), ("status", "string", false), ("offset", "integer", false), ("limit", "integer", false)]), RiskLevel::Low,
|
||||||
{ let db = db.clone(); Box::new(move |args: serde_json::Value| {
|
{ let db = db.clone(); Box::new(move |args: serde_json::Value| {
|
||||||
let db = db.clone();
|
let db = db.clone();
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let repo = df_storage::crud::TaskRepo::new(&db);
|
let repo = df_storage::crud::TaskRepo::new(&db);
|
||||||
let tasks = if let Some(pid) = args.get("project_id").and_then(|v| v.as_str()) {
|
let mut tasks = if let Some(pid) = args.get("project_id").and_then(|v| v.as_str()) {
|
||||||
repo.query("project_id", pid).await?
|
repo.query("project_id", pid).await?
|
||||||
} else {
|
} else {
|
||||||
repo.list_all().await?
|
repo.list_all().await?
|
||||||
};
|
};
|
||||||
|
// 按状态过滤(可选):todo/in_progress/in_review/testing/blocked/done/cancelled
|
||||||
|
if let Some(status) = args.get("status").and_then(|v| v.as_str()) {
|
||||||
|
tasks.retain(|t| t.status == status);
|
||||||
|
}
|
||||||
let total = tasks.len();
|
let total = tasks.len();
|
||||||
let offset = args["offset"].as_u64().unwrap_or(0) as usize;
|
let offset = args["offset"].as_u64().unwrap_or(0) as usize;
|
||||||
let limit = args["limit"].as_u64().unwrap_or(MAX_LIST_RESULTS as u64).min(MAX_LIST_RESULTS as u64) as usize;
|
let limit = args["limit"].as_u64().unwrap_or(MAX_LIST_RESULTS as u64).min(MAX_LIST_RESULTS as u64) as usize;
|
||||||
|
|||||||
Reference in New Issue
Block a user