mirror of
https://github.com/ThearchyHelios/AgentLab.git
synced 2026-11-15 04:51:57 +00:00
7df224106d
- engine/inquiry.py:开放条件(停在审批且问的是待处理的那张卡;或已封存、核对一致的探索运行,追加在封存之后;
正式运行封存后、设置关闭、还在执行一律 409);同一运行同时只答一条(进程内登记);回答交给 run_verify_agent
(不传 emit,数据版本取运行记录,上限和模型按核查设置),任务里给被问的那句、照 judge.prepare 取的证据摘录
(遮罩照旧、原报告编号标明)、选中的原文和问题,数据源取这次运行用过的查询工具;回答由 compose_doc 组装成文档
落工件,数字可以引用自己的查询格子或报告已有的指标、运行输入,裸数字被标出;引用到遮罩列的格子渲染成「已遮罩」,
回答正文和查询清单里出现的遮罩列的值换成「已遮罩」;写入走 append_events,运行在回答期间变了就不写、照实说明,
触顶和失败照样记一条
- api/inquiry.py:POST 提问、GET 列表(按报告、句子筛选)、GET 质询工件(只认质询引用过的,遮罩照证据面板);
输入不合法回 {detail, field}
- api/runs.py:质询正在回答时,审批回复(批准 / 驳回)和继续运行回 409 inquiry_busy,拦在记签批人之前
62 lines
2.7 KiB
Python
62 lines
2.7 KiB
Python
"""审批质询:审批人针对待审报告里的一句话提问,只读 agent 现查现答(规则和做法见 engine/inquiry.py)。
|
||
|
||
- POST /api/runs/{run_id}/inquiries:{report, unit, quote?, question, approval_id?} → {inquiry, recorded, note}
|
||
- GET /api/runs/{run_id}/inquiries?report=&unit=:{items: [Inquiry]},封存前后的都算,按先后
|
||
- GET /api/runs/{run_id}/inquiries/artifacts/{artifact_id}:质询引用过的工件,查询快照的遮罩列照证据面板遮好
|
||
|
||
不受理:409 {detail, code}(inquiry_not_open / inquiry_busy / inquiry_disabled);输入不合法 422 {detail, field},
|
||
field 指明是哪一项(前后端约定的形状,不是 FastAPI 自己那种校验错误数组,所以请求体自己解析)。
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
from typing import Any
|
||
|
||
from fastapi import APIRouter, Header, HTTPException, Request
|
||
from fastapi.responses import JSONResponse
|
||
|
||
from app.api.coded import CodedHTTPException
|
||
from app.api.runs import actor_of
|
||
from app.engine import inquiry
|
||
from app.engine.inquiry import InquiryRefused
|
||
|
||
router = APIRouter(prefix="/api/runs", tags=["inquiry"])
|
||
|
||
|
||
def _refused(e: InquiryRefused) -> Any:
|
||
"""不受理 → HTTP 响应。422 照约定只回 {detail, field};其余带机读码的回 {detail, code}。"""
|
||
if e.status == 422:
|
||
return JSONResponse(status_code=422, content={"detail": e.message, "field": e.field})
|
||
if e.code:
|
||
raise CodedHTTPException(e.status, e.message, e.code)
|
||
raise HTTPException(e.status, e.message)
|
||
|
||
|
||
@router.post("/{run_id}/inquiries", response_model=None)
|
||
async def ask_inquiry(run_id: str, request: Request, x_actor: str | None = Header(default=None)) -> Any:
|
||
"""问一个问题。回答要等 agent 查完库(最长约为设置里的时长上限再加半分钟收尾),接口一直等到回答完才返回。"""
|
||
try:
|
||
body = await request.json()
|
||
except (ValueError, UnicodeDecodeError):
|
||
body = None
|
||
try:
|
||
return await inquiry.ask(run_id, inquiry.parse_ask(body), actor=actor_of(x_actor))
|
||
except InquiryRefused as e:
|
||
return _refused(e)
|
||
|
||
|
||
@router.get("/{run_id}/inquiries", response_model=None)
|
||
async def list_inquiries(run_id: str, report: str | None = None, unit: str | None = None) -> Any:
|
||
try:
|
||
return {"items": await inquiry.list_inquiries(run_id, report=report or None, unit=unit or None)}
|
||
except InquiryRefused as e:
|
||
return _refused(e)
|
||
|
||
|
||
@router.get("/{run_id}/inquiries/artifacts/{artifact_id}", response_model=None)
|
||
async def inquiry_artifact(run_id: str, artifact_id: str) -> Any:
|
||
try:
|
||
return await inquiry.inquiry_artifact(run_id, artifact_id)
|
||
except InquiryRefused as e:
|
||
return _refused(e)
|
||
|