Audit batch 5: I-9, I-12, I-14, N-1..N-12, single-task wire single-transaction
This commit is contained in:
1 parent
cdac8039b3
commit
2adc605373
7 files changed
+1349
-440
No files matched your search
+88
-45
@@ -4200,7 +4200,10 @@ class CloudControlPlaneHandler(BaseHTTPRequestHandler):
|
||||
# cost_records 表只在 CostStore 首次初始化时建:新鲜
|
||||
# 库上直接查会报 no such table,报告端点不应因此 500。
|
||||
# 先建表(幂等),再读;建表失败时成本按空算、报告
|
||||
# 里 token/usd 为 0,不假装成本已计。
|
||||
# 里 token/usd 为 0,不假装成本已计。审计批 5(N-1):
|
||||
# 下面成本 SELECT 同样加 except 兜底(此前只有 finally、
|
||||
# 没有 except,建表失败会直接抛到 handler 层),失败时
|
||||
# 成本按空算并在报告里标 cost_unavailable。
|
||||
try:
|
||||
_cost_store = CostStore(self.server.db_path)
|
||||
try:
|
||||
@@ -4238,11 +4241,19 @@ class CloudControlPlaneHandler(BaseHTTPRequestHandler):
|
||||
" WHERE project_id = ?",
|
||||
(project_id,),
|
||||
).fetchall()
|
||||
cost_rows = conn.execute(
|
||||
"SELECT task_id, total_tokens, usd_micros"
|
||||
" FROM cost_records WHERE project_id = ?",
|
||||
(project_id,),
|
||||
).fetchall()
|
||||
cost_unavailable = False
|
||||
try:
|
||||
cost_rows = conn.execute(
|
||||
"SELECT task_id, total_tokens, usd_micros"
|
||||
" FROM cost_records WHERE project_id = ?",
|
||||
(project_id,),
|
||||
).fetchall()
|
||||
except Exception:
|
||||
# 审计批 5(N-1):成本查询失败(通常是建表失败后
|
||||
# 表仍不存在)时成本按空算,不抛到 handler 层;
|
||||
# 报告里的 cost_unavailable 标明成本不可用。
|
||||
cost_rows = []
|
||||
cost_unavailable = True
|
||||
finally:
|
||||
conn.close()
|
||||
tasks_by_id = {}
|
||||
@@ -4275,6 +4286,18 @@ class CloudControlPlaneHandler(BaseHTTPRequestHandler):
|
||||
tasks_by_id, costs_by_task, explicit_n=explicit_n)
|
||||
report["project_id"] = project_id
|
||||
report["truncated"] = truncated
|
||||
report["cost_unavailable"] = cost_unavailable
|
||||
# 审计批 5(N-5):截断取最早 10000 行(ORDER BY
|
||||
# created_at ASC),与协调员门查询取最新 5000 行方向
|
||||
# 相反——调用方须知样本是哪一段:同时返回样本时间窗
|
||||
# (保留样本的最早/最晚 created_at;无样本时为 None)。
|
||||
if audit_rows:
|
||||
report["sample_window"] = {
|
||||
"earliest_created_at": audit_rows[0]["created_at"],
|
||||
"latest_created_at": audit_rows[-1]["created_at"]}
|
||||
else:
|
||||
report["sample_window"] = {
|
||||
"earliest_created_at": None, "latest_created_at": None}
|
||||
# 显式失败清单:解析 worker_capability_gateway_explicit
|
||||
# 行(格式:task_id model=.. tier=.. mode=.. missing=..
|
||||
# unknown=.. blocked=..;fix4 之前的行无 blocked 项,
|
||||
@@ -4570,6 +4593,57 @@ class CloudControlPlaneHandler(BaseHTTPRequestHandler):
|
||||
for path, size in saved],
|
||||
})
|
||||
|
||||
@staticmethod
|
||||
def _resolve_create_agent_definition(body):
|
||||
"""建任务的 agent 定义解析(审计批 5,I-9③抽取,行为逐字不变)。
|
||||
|
||||
原 _create_task 内 agent/agent_name 解析段平移:返回
|
||||
(definition, error)——error 非空时调用方按原样发 400 且
|
||||
不建任务;definition 为 None 且 error 为空表示未给定义。
|
||||
副作用:无库写、无响应发送(400 由调用方发,与原地一致)。
|
||||
"""
|
||||
if body.get("agent") is not None \
|
||||
and body.get("agent_name") is not None:
|
||||
return None, "agent and agent_name cannot both be used"
|
||||
if body.get("agent") is not None \
|
||||
and body.get("agent_version") is not None:
|
||||
return None, ("agent_version is only for agent_name;"
|
||||
" an inline agent carries its own version")
|
||||
definition = None
|
||||
if body.get("agent") is not None:
|
||||
if not isinstance(body.get("agent"), dict):
|
||||
return None, "agent must be an object"
|
||||
try:
|
||||
definition = _parse_agent_definition(
|
||||
body.get("agent"),
|
||||
known_skills=_agent_known_skills())
|
||||
except ValueError as exc:
|
||||
return None, str(exc)
|
||||
if body.get("agent_name") is not None:
|
||||
try:
|
||||
definition = _resolve_agent(
|
||||
body.get("agent_name"),
|
||||
version=body.get("agent_version"),
|
||||
agents_dir=_agent_default_dir(),
|
||||
known_skills=_agent_known_skills())
|
||||
except ValueError as exc:
|
||||
return None, str(exc)
|
||||
return definition, None
|
||||
|
||||
@staticmethod
|
||||
def _validate_create_audit_loop(body):
|
||||
"""建任务的 audit_loop 开关校验(审计批 5,I-9③抽取,行为逐字不变)。
|
||||
|
||||
原 _create_task 内审计循环接线校验段平移:只认 True/1
|
||||
(其它真值一律错,不猜)。返回 (audit_loop_val, error)——
|
||||
error 非空时调用方按原样发 400 且不建任务。
|
||||
"""
|
||||
if body.get("audit_loop") is None:
|
||||
return 0, None
|
||||
if body.get("audit_loop") not in (True, 1):
|
||||
return None, "audit_loop must be true or 1"
|
||||
return 1, None
|
||||
|
||||
def _create_task(self, user_id):
|
||||
body, err = self._read_json()
|
||||
if err:
|
||||
@@ -4606,39 +4680,11 @@ class CloudControlPlaneHandler(BaseHTTPRequestHandler):
|
||||
# 优先于定义;解析出的字段落进已有列,定义身份与
|
||||
# 指令落进 agent_name/agent_version/agent_instructions
|
||||
# 列(v2),prompt 不再带头。
|
||||
definition = None
|
||||
if body.get("agent") is not None \
|
||||
and body.get("agent_name") is not None:
|
||||
self._send_json(400, {
|
||||
"error": "agent and agent_name cannot both be used"})
|
||||
definition, _agent_err = \
|
||||
self._resolve_create_agent_definition(body)
|
||||
if _agent_err:
|
||||
self._send_json(400, {"error": _agent_err})
|
||||
return
|
||||
if body.get("agent") is not None \
|
||||
and body.get("agent_version") is not None:
|
||||
self._send_json(400, {
|
||||
"error": "agent_version is only for agent_name;"
|
||||
" an inline agent carries its own version"})
|
||||
return
|
||||
if body.get("agent") is not None:
|
||||
if not isinstance(body.get("agent"), dict):
|
||||
self._send_json(400, {"error": "agent must be an object"})
|
||||
return
|
||||
try:
|
||||
definition = _parse_agent_definition(
|
||||
body.get("agent"),
|
||||
known_skills=_agent_known_skills())
|
||||
except ValueError as exc:
|
||||
self._send_json(400, {"error": str(exc)})
|
||||
return
|
||||
if body.get("agent_name") is not None:
|
||||
try:
|
||||
definition = _resolve_agent(
|
||||
body.get("agent_name"),
|
||||
version=body.get("agent_version"),
|
||||
agents_dir=_agent_default_dir(),
|
||||
known_skills=_agent_known_skills())
|
||||
except ValueError as exc:
|
||||
self._send_json(400, {"error": str(exc)})
|
||||
return
|
||||
depends_on = body.get("depends_on") or []
|
||||
if isinstance(depends_on, str):
|
||||
depends_on = [depends_on]
|
||||
@@ -4976,13 +5022,10 @@ class CloudControlPlaneHandler(BaseHTTPRequestHandler):
|
||||
# 就不写 audit_loop 列(默认 0),父任务的循环只记在
|
||||
# 父任务上,子任务包只是前言载体。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
|
||||
audit_loop_val, _al_err = self._validate_create_audit_loop(body)
|
||||
if _al_err:
|
||||
self._send_json(400, {"error": _al_err})
|
||||
return
|
||||
agent_name_val = definition.name if definition else None
|
||||
agent_version_val = definition.version if definition else None
|
||||
agent_instructions_val = (
|
||||
|
||||
Reference in new issue
Block a user