fix: wire audit loop into worker completion path (pushback delivery, escalate, packet preamble)
Audit-loop wiring, worker completion path only: after the final write-back (and only when the final is completed/failed, not quota, not cancelled, not goal-converted, and the task carries audit_loop), collect this attempt's deterministic gate results (execution, goal_verify only when host reported goal_met, capability / required_tools / gateway as passed-or-inapplicable markers, since a pre-dispatch gate rejection early-returns before any runner round and requeueing it would deterministically re-fail the same gate) and call audit_loop_evaluate. Pushback stores the packet JSON in tasks.audit_loop_packet and CAS-requeues the task; the next claim prepends the packet preamble to prompt (and goal) with a data-only separator, DB prompt untouched. Pass clears the packet. Escalate sets failed (VALID_STATUSES has no needs_review, never invented) with an escalation error and clears the packet; subjective needs_review leaves the outcome untouched and only audits. New tasks.audit_loop / audit_loop_packet columns follow the attempts DDL pattern in worker ensure, server migrate, PG schema, PG backfill, migrations backfill, and POST /tasks accepts audit_loop (True/1 only, coordinator tasks rejected like v9). Coordinator parent tasks return via _run_coordinator before the attempt loop and coordinator children never inherit audit_loop, so coordinator wiring is left as legacy, unchanged.
This commit is contained in:
1 parent
37b1aadc02
commit
f2005689fd
6 files changed
+764
-8
No files matched your search
+28
-3
@@ -1254,6 +1254,10 @@ def migrate_tasks_table(conn):
|
||||
"agent_tools": "TEXT",
|
||||
# agent 定义 v9:工具审批声明 JSON 对象(NULL = 未声明)。
|
||||
"agent_tool_approvals": "TEXT",
|
||||
# 审计循环接线:audit_loop=1 才启用自动循环(默认 0);
|
||||
# audit_loop_packet 存上一轮推回包 JSON(NULL = 无包)。
|
||||
"audit_loop": "INTEGER DEFAULT 0",
|
||||
"audit_loop_packet": "TEXT",
|
||||
}
|
||||
for name, coltype in new_cols.items():
|
||||
if name not in cols:
|
||||
@@ -1882,6 +1886,10 @@ def _task_to_dict(row, attachments=None, total_tokens=None):
|
||||
# v9:agent_tool_approvals 存 JSON 对象;脏数据/老行
|
||||
# 缺列时按 None 计(= 未声明)。
|
||||
"agent_tool_approvals": _agent_tool_approvals_from_row(row),
|
||||
# 审计循环接线:开关回读(老行缺列按 0 计);推回包
|
||||
# JSON 是 worker 内部状态,不进任务详情回读(控制台
|
||||
# 不应渲染机器包,运营方看推回审计行即可)。
|
||||
"audit_loop": _row_get(row, "audit_loop") or 0,
|
||||
"paused_by_user": _row_get(row, "paused_by_user") or 0,
|
||||
"interrupted_reason": _row_get(row, "interrupted_reason"),
|
||||
"auto_resume_count": _row_get(row, "auto_resume_count") or 0,
|
||||
@@ -4906,6 +4914,23 @@ class CloudControlPlaneHandler(BaseHTTPRequestHandler):
|
||||
"error": "agent tools cannot be used with"
|
||||
" goal/coordinator tasks"})
|
||||
return
|
||||
# 审计循环接线:audit_loop 只认 True/1(其它真值一律
|
||||
# 400,不猜);协调员父任务不跑模型回合、接线覆盖不到
|
||||
# 它,带 audit_loop 建协调员任务属于静默丢弃,同款
|
||||
# v9 拒绝逻辑,400 且不建任务。goal 任务允许(goal
|
||||
# 校验门是接线要消费的确定性门之一)。
|
||||
audit_loop_val = 0
|
||||
if body.get("audit_loop") is not None:
|
||||
if body.get("audit_loop") not in (True, 1):
|
||||
self._send_json(400, {
|
||||
"error": "audit_loop must be true or 1"})
|
||||
return
|
||||
audit_loop_val = 1
|
||||
if coord_parts:
|
||||
self._send_json(400, {
|
||||
"error": "audit_loop cannot be used with"
|
||||
" coordinator tasks"})
|
||||
return
|
||||
agent_name_val = definition.name if definition else None
|
||||
agent_version_val = definition.version if definition else None
|
||||
agent_instructions_val = (
|
||||
@@ -4941,9 +4966,9 @@ class CloudControlPlaneHandler(BaseHTTPRequestHandler):
|
||||
" parent_task_id, coordinator_part,"
|
||||
" child_model, child_effort,"
|
||||
" agent_name, agent_version, agent_instructions,"
|
||||
" agent_tools, agent_tool_approvals)"
|
||||
" agent_tools, agent_tool_approvals, audit_loop)"
|
||||
" VALUES(?, ?, ?, 'queued', ?, ?, ?, ?, ?, ?, NULL, ?,"
|
||||
" ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
" ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
(task_id, project_id, prompt, idempotency_key,
|
||||
json.dumps(depends_on), priority, user_id, now, now,
|
||||
executor, goal, verify_command, goal_max_rounds,
|
||||
@@ -4953,7 +4978,7 @@ class CloudControlPlaneHandler(BaseHTTPRequestHandler):
|
||||
None, None, child_model, child_effort,
|
||||
agent_name_val, agent_version_val,
|
||||
agent_instructions_val, agent_tools_val,
|
||||
agent_tool_approvals_val),
|
||||
agent_tool_approvals_val, audit_loop_val),
|
||||
)
|
||||
# 长任务不限时:API 字段 no_time_limit=1 时写标记,
|
||||
# worker 认领后按不限时跑(单轮 host 600 秒仍在);
|
||||
|
||||
Reference in new issue
Block a user