auto-sync: 2026-05-21 00:14:10
This commit is contained in:
@@ -66,13 +66,32 @@ async def get_task(project_id: str, task_id: str,
|
||||
@router.post("/tasks")
|
||||
async def create_task(project_id: str, body: Dict[str, Any]):
|
||||
bb = _bb(project_id)
|
||||
# v2.8: title 为空时自动生成
|
||||
# ID: 后端生成 {project_id_prefix}-{date}-{seq}
|
||||
task_id = body.get("id")
|
||||
if not task_id:
|
||||
import re
|
||||
from datetime import datetime
|
||||
prefix = re.sub(r'[^a-z0-9]', '-', project_id.lower()).strip('-')[:20]
|
||||
date_str = datetime.now().strftime('%Y%m%d')
|
||||
# seq: 查当前项目最大 seq
|
||||
try:
|
||||
max_id_row = bb._conn.execute(
|
||||
"SELECT id FROM tasks WHERE id LIKE ? ORDER BY id DESC LIMIT 1",
|
||||
(f"{prefix}-{date_str}-%",)
|
||||
).fetchone()
|
||||
seq = int(max_id_row[0].split('-')[-1]) + 1 if max_id_row else 1
|
||||
except Exception:
|
||||
seq = 1
|
||||
task_id = f"{prefix}-{date_str}-{seq:04d}"
|
||||
|
||||
# Title: LLM 生成(如果前端没传)
|
||||
title = body.get("title", "")
|
||||
if not title or not title.strip():
|
||||
desc = body.get("description", "") or ""
|
||||
title = (desc[:30] + "…") if len(desc) > 30 else (desc or "新军令")
|
||||
title = await _generate_title(desc) or ((desc[:30] + "…") if len(desc) > 30 else (desc or "新军令"))
|
||||
|
||||
task = Task(
|
||||
id=body["id"], title=title,
|
||||
id=task_id, title=title,
|
||||
description=body.get("description"),
|
||||
task_type=body.get("task_type", "coding"),
|
||||
priority=body.get("priority", 5),
|
||||
@@ -88,6 +107,36 @@ async def create_task(project_id: str, body: Dict[str, Any]):
|
||||
return {"ok": True, "task_id": task.id, "title": task.title}
|
||||
|
||||
|
||||
async def _generate_title(description: str) -> str | None:
|
||||
"""调用 LLM 生成简短标题"""
|
||||
if not description or len(description) < 5:
|
||||
return None
|
||||
try:
|
||||
from openai import OpenAI
|
||||
import os
|
||||
client = OpenAI(
|
||||
base_url=os.environ.get("OPENAI_BASE_URL", "https://open.bigmodel.cn/api/paas/v4"),
|
||||
api_key=os.environ.get("OPENAI_API_KEY", ""),
|
||||
)
|
||||
resp = client.chat.completions.create(
|
||||
model=os.environ.get("MOZIPLUS_TITLE_MODEL", "glm-4-flash"),
|
||||
messages=[
|
||||
{"role": "system", "content": "你是一个任务标题生成器。根据用户的需求描述,生成一个简洁的中文标题(5-15字),只输出标题,不要任何其他内容。"},
|
||||
{"role": "user", "content": description[:500]},
|
||||
],
|
||||
max_tokens=50,
|
||||
temperature=0.3,
|
||||
timeout=10,
|
||||
)
|
||||
title = resp.choices[0].message.content.strip().strip('"').strip("'")
|
||||
if title and len(title) <= 30:
|
||||
return title
|
||||
except Exception as e:
|
||||
import logging
|
||||
logging.getLogger("moziplus-v2").warning(f"Title generation failed: {e}")
|
||||
return None
|
||||
|
||||
|
||||
@router.get("/tasks/{task_id}/progress")
|
||||
async def task_progress(project_id: str, task_id: str):
|
||||
"""Task Stage 进度(含子 Task 统计)"""
|
||||
|
||||
Reference in New Issue
Block a user