feat(bioflow): 就绪卡+版本化卡接线——工具结果经 payload.bioflow 下发前端渲染 (#009)

This commit is contained in:
2026-10-13 11:18:53 +08:00
parent 9797b1b414
commit 6b4b5e571f
3 changed files with 53 additions and 1 deletions
@@ -291,6 +291,28 @@ def _empty_audit() -> Dict[str, Any]:
return {"rounds": 0, "tool_calls": 0, "used_json_fallback": False, "tool_names": [], "errors": []}
def _map_readiness(data: Dict[str, Any]) -> Dict[str, Any]:
"""check_readiness 结果 → 就绪卡字段 {ready, quadrants:[{name,ok}]}。"""
inner = data.get("result", data) if isinstance(data, dict) else {}
quadrants = []
for key in ("environment", "reference", "space", "budget"):
q = inner.get(key) or {}
quadrants.append({"name": key, "ok": bool(q.get("ok"))})
return {"ready": bool(inner.get("ready")), "quadrants": quadrants}
def _map_versioning(data: Dict[str, Any]) -> Dict[str, Any]:
"""propose_change 结果 → 版本化卡字段 {plan_revision, run_id, affected_stages, based_on_revision}。"""
inner = data.get("result", data) if isinstance(data, dict) else {}
affected = inner.get("affected") or []
return {
"plan_revision": "",
"run_id": "",
"affected_stages": list(affected),
"based_on_revision": None,
}
def _make_payload(
question: str,
answer: str,
@@ -299,6 +321,8 @@ def _make_payload(
capabilities: Optional[List[str]] = None,
active_job_id: Optional[str] = None,
chain: Optional[str] = None,
readiness: Optional[Dict[str, Any]] = None,
versioning: Optional[Dict[str, Any]] = None,
) -> Dict[str, Any]:
payload: Dict[str, Any] = {
"success": True,
@@ -318,6 +342,10 @@ def _make_payload(
payload["bioflow"]["active_job_id"] = str(active_job_id)
if chain:
payload["bioflow"]["chain"] = str(chain)
if readiness:
payload["bioflow"]["readiness"] = readiness
if versioning:
payload["bioflow"]["versioning"] = versioning
return payload
@@ -647,6 +675,18 @@ def _try_bioflow_agent_impl(
if not answer:
return None
tool_results = (audit or {}).get("tool_results") or {}
readiness = None
versioning = None
for name, result_text in tool_results.items():
data = _try_parse_json(result_text)
if not isinstance(data, dict):
continue
if name == "check_readiness":
readiness = _map_readiness(data)
elif name == "propose_change":
versioning = _map_versioning(data)
return _make_payload(
question,
answer,
@@ -654,6 +694,8 @@ def _try_bioflow_agent_impl(
capabilities=[m.name for m in manifests],
active_job_id=(bioflow or {}).get("active_job_id"),
chain=(bioflow or {}).get("chain"),
readiness=readiness,
versioning=versioning,
)
@@ -66,6 +66,7 @@ class ToolRunner:
"tool_calls": 0,
"used_json_fallback": False,
"tool_names": [],
"tool_results": {},
"errors": [],
}
messages: List[Dict[str, Any]] = []
@@ -125,6 +126,7 @@ class ToolRunner:
"function": {"name": name or "unknown", "arguments": json.dumps(arguments, ensure_ascii=False)},
}
)
audit["tool_results"][name] = result_text
messages.append({"role": "tool", "tool_call_id": call_id, "content": result_text})
assistant_message["tool_calls"] = tool_call_blocks
messages.append(assistant_message)
+9 -1
View File
@@ -2549,10 +2549,18 @@ export const useChatStore = defineStore('chat', {
const p = ev.payload || {};
const answer = p.answer || '';
updateLocal(() => {
aMsg.blocks = [
const blocks = [
{ type: 'bioflow_path', status: 'done', candidates: [] },
{ type: 'text', html: answer },
];
const bfPayload = p.bioflow || {};
if (bfPayload.readiness) {
blocks.push({ type: 'bioflow_readiness', ...bfPayload.readiness, error: null });
}
if (bfPayload.versioning) {
blocks.push({ type: 'bioflow_versioning', ...bfPayload.versioning });
}
aMsg.blocks = blocks;
aMsg.raw = p.raw ?? p;
aMsg.status = 'done';
});