V3.3.1 修复:WBS 解析 'Extra data' 报错 + 开工接口空 body 容错
- parse_wbs 改用 raw_decode 提取第一个完整 JSON,忽略尾部杂质/多余 JSON(原按首{到尾}切片,模型输出带第二段JSON或解释文字时解析失败)
- 兼容 subtasks/task_list/items/task 等任务键名
- /autostart 接口 get_json 改 silent 容错(无 body 时不再 400)
This commit is contained in:
@@ -1076,7 +1076,7 @@ def project_autostart(pid):
|
||||
return jsonify({'ok': False, 'error': '请先在编辑项目中设置 AI 主管 Worker'}), 400
|
||||
if not db.q('SELECT 1 FROM project_team_workers WHERE project_id=?', (pid,)):
|
||||
return jsonify({'ok': False, 'error': '请先在编辑项目中勾选干活团队 Worker(≥1 个)'}), 400
|
||||
d = request.get_json(force=True) or {}
|
||||
d = request.get_json(silent=True) or {}
|
||||
ok = autostart.launch(pid, review_required=1 if d.get('auto_review') else 0)
|
||||
if not ok:
|
||||
return jsonify({'ok': False, 'error': 'AI 主管正在工作中,请稍候'}), 400
|
||||
|
||||
+27
-21
@@ -47,19 +47,39 @@ REVISE_PROMPT = (
|
||||
)
|
||||
|
||||
|
||||
def parse_wbs(text):
|
||||
"""从 LLM 输出中稳健提取 JSON 任务列表"""
|
||||
def _extract_json(text):
|
||||
"""用 raw_decode 稳健提取第一个完整 JSON 值(自动忽略尾部杂质/多余 JSON)"""
|
||||
t = text.strip()
|
||||
if t.startswith('```'):
|
||||
t = t.strip('`')
|
||||
if t.startswith('json'):
|
||||
t = t[4:]
|
||||
t = t.strip()
|
||||
start = min([i for i in (t.find('{'), t.find('[')) if i >= 0] or [0])
|
||||
end = max(t.rfind('}'), t.rfind(']')) + 1
|
||||
data = json.loads(t[start:end])
|
||||
tasks = data['tasks'] if isinstance(data, dict) else data
|
||||
assert isinstance(tasks, list) and tasks, '任务列表为空'
|
||||
candidates = [i for i in (t.find('{'), t.find('[')) if i >= 0]
|
||||
last_err = None
|
||||
for i in sorted(candidates):
|
||||
try:
|
||||
obj, _ = json.JSONDecoder().raw_decode(t[i:])
|
||||
return obj
|
||||
except Exception as e:
|
||||
last_err = e
|
||||
raise last_err or ValueError('未找到 JSON 内容')
|
||||
|
||||
|
||||
def parse_wbs(text):
|
||||
"""从 LLM 输出中稳健提取 JSON 任务列表(兼容任务键名/多余内容)"""
|
||||
try:
|
||||
data = _extract_json(text)
|
||||
except Exception:
|
||||
raise
|
||||
if isinstance(data, dict):
|
||||
for key in ('tasks', 'subtasks', 'task_list', 'items', 'task'):
|
||||
if key in data:
|
||||
data = data[key]
|
||||
break
|
||||
tasks = data if isinstance(data, list) else []
|
||||
if not tasks:
|
||||
raise ValueError('任务列表为空或格式不正确')
|
||||
return tasks
|
||||
|
||||
|
||||
@@ -100,20 +120,6 @@ def _chat_json(worker, messages, max_tokens=3000, temperature=0.3):
|
||||
raise last_err or ValueError('JSON 解析失败')
|
||||
|
||||
|
||||
def _extract_json(text):
|
||||
t = text.strip()
|
||||
if t.startswith('```'):
|
||||
t = t.strip('`')
|
||||
if t.startswith('json'):
|
||||
t = t[4:]
|
||||
t = t.strip()
|
||||
start = min([i for i in (t.find('{'), t.find('[')) if i >= 0] or [0])
|
||||
end = max(t.rfind('}'), t.rfind(']')) + 1
|
||||
if end <= start:
|
||||
raise ValueError('未找到 JSON 内容')
|
||||
return json.loads(t[start:end])
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 团队读取
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user