muse-agent-example/tests/集成/test_参考分析权威.py
zizi cf0f4fb985 W20–W24:保存知识方法、迁移框架、审校修订与案例行为的集成成果
接续 88dd570,保存 W20–W24 已实现的共享接口、业务入口、迁移、工作台、测试与文档。
W20/W22/W23 保持 in_progress,W21/W24 保持 verified;此提交不宣称方法或规则正式启用、多轮返修、真实角色评测完成。

W25 新增实验、标定、逐调用交付与角色执行及其迁移/测试/索引留在实施工作树,原有私人和旧实现保留项不纳入。

验证:离线 571、前端 33 通过;PG 469 项通过、2 项浏览器未启用,2 项误带入的 W25 用例已移出本提交;最终任务与交付边界 37 项通过。make 检查、最终类型、84 项资源及 diff 检查通过。未重跑浏览器或 Pi 宿主,不以合成调用认证外部模型效果。
独立整体审查四维通过;证据保存在 R2-20260909/提交W20-W24。
2026-09-13 16:24:42 +08:00

147 lines
7.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""完整分析落B03;S02运行证据不被业务回查或历史承接改写。"""
from dataclasses import replace
import pytest
from muse.任务运行.接口 import 任务状态, 步骤结果
from muse.共享.错误 import Muse错误
from muse.接入.cli.研究命令 import 运行研究命令
from muse.编排.研究拆书 import 查询拆书状态
from muse.资料研究.接口 import 版本身份, 窗口, 窗计划哈希, 资料服务
from muse.配置 import 服务配置
pytestmark = pytest.mark.数据库
def _来源(工具):
return 工具.导入来源("B03版本样例", "第1回 机舱\n林深照看机舱。\n")
def _完成(工具, 来源, 名称):
任务 = 工具.发起(来源["source_id"])
快照 = 工具.装配.任务运行.读取任务(任务["task_id"])
for _ in 快照.冻结输入["输入"]["窗计划"]:
工具.剧本.append(
工具.分析输出([{"name": 名称, "type": "人物", "evidence": ["林深照看机舱。"]}])
)
终态 = 工具.跑任务(任务["task_id"])
assert 终态.状态 == 任务状态.已完成
return 任务, 终态
def test_相同输入的不同运行分别持久化完整分析__214010(研究环境):
工具 = 研究环境
来源 = _来源(工具)
一, 原一 = _完成(工具, 来源, "第一种归纳")
二, 原二 = _完成(工具, 来源, "第二种归纳")
assert 一["版本ID"] == 二["版本ID"] and 一["task_id"] != 二["task_id"]
with 工具.库.连接(只读=True) as 连:
列表 = 工具.服务.列出分析(连, "post-author", 来源["source_id"])
assert len(列表) == 2 and {r["analysis_id"] for r in 列表} == {一["task_id"], 二["task_id"]}
assert len({r["content_hash"] for r in 列表}) == 2
assert {r["payload"]["窗口结果"]["w001"]["entities"][0]["name"] for r in 列表} == {
"第一种归纳",
"第二种归纳",
}
with pytest.raises(Muse错误):
工具.服务.读取分析(连, "foreign-author", 一["task_id"])
with 工具.库.连接() as 连, 连.transaction():
回查 = 工具.服务.承接历史分析(连, 工具.装配.任务运行, "post-author", 一["task_id"])
assert 回查["origin"] == "model"
状态 = 查询拆书状态(工具.装配, "post-author", 来源["source_id"])
assert len(状态["分析"]) == 2
assert {r["analysis_state"] for r in 状态["台账"]} == {"recorded"}
assert 工具.装配.任务运行.读取任务(一["task_id"]) == 原一
assert 工具.装配.任务运行.读取任务(二["task_id"]) == 原二
def _旧版本登记(上下文, *, 坏摘要):
# 复现升级前的最终处理器;前置窗口仍由真实S02流程和合成模型提供方执行。
任务 = 上下文.任务
输入 = 任务.冻结输入["输入"]["拆书"]
步骤 = {s["step_id"]: s for s in 任务.步骤}
结果 = 步骤["逐窗提取"]["checkpoint"]["窗口结果"]
合并 = 步骤["实体归并"]["checkpoint"]["归并"]
窗列表 = [窗口(**r) for r in 任务.冻结输入["输入"]["窗计划"]]
版本 = {
"版本ID": 版本身份(输入["source_id"], 输入["revision"], 窗列表),
"source_id": 输入["source_id"],
"revision": 输入["revision"],
"content_hash": 输入["content_hash"],
"窗计划哈希": 窗计划哈希(窗列表),
"完成窗": sorted(结果),
"实体组数": len(合并["合并组"]) + int(坏摘要),
"歧义数": len(合并["歧义"]),
"样本依据": 任务.冻结输入["输入"].get("样本依据"),
}
return 步骤结果({"版本ID": 版本["版本ID"], "歧义数": 版本["歧义数"]}, {"版本": 版本})
@pytest.mark.parametrize("坏摘要", [False, True])
def test_已完成旧检查点显式承接不造任务且坏摘要拒绝__214011(
研究环境, monkeypatch, tmp_path, 坏摘要
):
工具 = 研究环境
来源 = _来源(工具)
登记 = 工具.装配.流程登记
原获取 = 登记.获取
def 旧获取(身份, 版本):
处理器 = 原获取(身份, 版本)
if 身份 == "rs.version":
return replace(处理器, 执行=lambda ctx: _旧版本登记(ctx, 坏摘要=坏摘要))
return 处理器
with monkeypatch.context() as m:
m.setattr(登记, "获取", 旧获取)
任务, 原任务 = _完成(工具, 来源, "旧分析")
with 工具.库.连接(只读=True) as 连:
assert 工具.服务.列出分析(连, "post-author", 来源["source_id"]) == []
查询 = 查询拆书状态(工具.装配, "post-author", 来源["source_id"])
assert 查询["台账"][0]["analysis_state"] == "history_not_imported" and 查询["分析"] == []
前任务数 = len(工具.装配.任务运行.列出任务("post-author"))
工具.装配.配置 = replace(
工具.装配.配置, HTTP=服务配置(str(tmp_path / "token-reference"), "post-author")
)
if 坏摘要:
with pytest.raises(Muse错误, match="旧登记摘要与完整结果不符"):
运行研究命令(工具.装配, "承接", 任务["task_id"])
with 工具.库.连接(只读=True) as 连:
assert 工具.服务.列出分析(连, "post-author", 来源["source_id"]) == []
else:
分析 = 运行研究命令(工具.装配, "承接", 任务["task_id"])
assert 分析["origin"] == "checkpoint_history"
assert 分析["payload"]["窗口结果"]["w001"]["entities"][0]["name"] == "旧分析"
assert 运行研究命令(工具.装配, "承接", 任务["task_id"]) == 分析
assert 运行研究命令(工具.装配, "分析", 任务["task_id"]) == 分析
assert 运行研究命令(工具.装配, "检查", 任务["task_id"])["分析"] == 分析
assert 工具.装配.任务运行.读取任务(任务["task_id"]) == 原任务
assert len(工具.装配.任务运行.列出任务("post-author")) == 前任务数
assert 工具.剧本 == [], "承接不重发模型调用,也不需要额外模型剧本"
def test_历史承接拒绝未完成任务和非持有者写入__214012(研究环境):
工具 = 研究环境
来源 = _来源(工具)
任务 = 工具.发起(来源["source_id"])
with 工具.库.连接() as 连:
with pytest.raises(Muse错误, match="已完成"):
with 连.transaction():
资料服务().承接历史分析(连, 工具.装配.任务运行, "post-author", 任务["task_id"])
领取 = 工具.装配.任务运行.领取步骤("worker", 工具.环境["处理器能力"])
assert 领取 is not None
with 工具.库.连接() as 连:
with pytest.raises(Muse错误, match="只有分析登记步骤"):
with 连.transaction():
资料服务().登记模型分析(连, 工具.装配.任务运行, 领取)
工具.装配.任务运行.控制任务(
任务["task_id"], "post-author", 任务状态.运行中, "取消", 命令ID="cancel-analysis"
)
with 工具.库.连接() as 连:
with pytest.raises(Muse错误, match="任务已停止"):
with 连.transaction():
资料服务().登记模型分析(连, 工具.装配.任务运行, 领取)
with 工具.库.连接(只读=True) as 连:
assert 工具.服务.列出分析(连, "post-author", 来源["source_id"]) == []