Files
beige/backend/app/api/v1/fission.py
yangqianqian cefdbaabdc feat(M7): 第11环裂变引擎端到端打通
- fission_service: 1源任务扇出N套子任务(回填source_fission_id,复用主管道),MAX_FANOUT=5红线
- fission_prompt: 三档参考度(high/mid/low)占位规则,真实措辞待北哥定义
- tasks.py: worker识别裂变子任务→注入对应档位规则进文案上下文(关键缺口修复)
- api/v1/fission: POST触发 + GET进度聚合, main.py注册路由
- 实测: fission_id=2扇出task70/71,worker注入日志level=high,进度端点聚合正确

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 15:05:27 +08:00

79 lines
2.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
app/api/v1/fission.py — 第11环裂变路由
POST /fission 触发裂变(1源任务→N套子任务)
GET /fission/{id} 查裂变进度(聚合N个子任务状态)
工作台内呈现,子任务走标准 SSE 流回进度。
"""
import logging
from typing import Annotated
from fastapi import APIRouter, Depends
from pydantic import BaseModel, Field
from sqlalchemy.orm import Session
from app.core.database import get_db
from app.core.response import ok, raise_not_found
from app.middleware.workspace_guard import CurrentUser, require_write_permission
from app.models.fission import FissionTask
from app.models.task import GenerationTask
logger = logging.getLogger(__name__)
router = APIRouter(tags=["fission"])
class FissionCreate(BaseModel):
source_task_id: int
reference_level: str = Field(default="mid") # low/mid/high
fanout_count: int = Field(default=3, ge=1, le=5)
@router.post("/fission")
def create_fission_endpoint(
body: FissionCreate,
current_user: Annotated[CurrentUser, Depends(require_write_permission)] = None,
db: Session = Depends(get_db),
):
"""触发裂变:从源任务扇出 N 套完整笔记包。返回 fission_id + 子 task_ids。"""
from app.services.fission_service import create_fission
fission_id, task_ids = create_fission(
db, current_user, body.source_task_id, body.reference_level, body.fanout_count,
)
return ok({"fission_id": fission_id, "task_ids": task_ids,
"reference_level": body.reference_level, "fanout_count": len(task_ids)})
@router.get("/fission/{fission_id}")
def get_fission_progress(
fission_id: int,
current_user: Annotated[CurrentUser, Depends(require_write_permission)] = None,
db: Session = Depends(get_db),
):
"""查裂变进度:聚合 N 个子任务状态x/N 完成)。"""
ft = db.query(FissionTask).filter(
FissionTask.id == fission_id,
FissionTask.workspace_id == current_user.workspace_id,
).first()
if not ft:
raise_not_found("裂变任务不存在")
subs = db.query(GenerationTask).filter(
GenerationTask.source_fission_id == fission_id,
GenerationTask.workspace_id == current_user.workspace_id,
).all()
done_states = {"pending_selection", "pending_review", "approved", "archived"}
done = sum(1 for s in subs if s.status in done_states)
failed = sum(1 for s in subs if s.status == "failed")
total = len(subs)
# 聚合状态:全失败=failed,全完成=done,否则generating
agg = "done" if done == total and total > 0 else ("failed" if failed == total and total > 0 else "generating")
if ft.status != agg:
ft.status = agg; db.commit()
return ok({
"fission_id": ft.id, "reference_level": ft.reference_level,
"fanout_count": ft.fanout_count, "status": agg,
"progress": {"done": done, "failed": failed, "total": total},
"task_ids": [s.id for s in subs],
})