修复: 同窗统一消费实体出场章
This commit is contained in:
parent
d015f1d321
commit
7f675922b2
@ -2398,6 +2398,13 @@ def _run(work_id, max_windows, max_calls, model, redo_window, semantic_on):
|
|||||||
did = name_map[nm][0]
|
did = name_map[nm][0]
|
||||||
to_update.setdefault(did, []).append(it["观察点"])
|
to_update.setdefault(did, []).append(it["观察点"])
|
||||||
pres_add.setdefault(did, set()).update(_int_chaps(it.get("出场章")))
|
pres_add.setdefault(did, set()).update(_int_chaps(it.get("出场章")))
|
||||||
|
# 在任何实体更新写入前汇总纯出场,确保同卡全部章节由一次 merge 或机械收尾消费。
|
||||||
|
for it in obs.get("纯出场", []):
|
||||||
|
nm = (it.get("名称") or "").strip()
|
||||||
|
if nm in name_map:
|
||||||
|
pres_add.setdefault(name_map[nm][0], set()).update(
|
||||||
|
_int_chaps(it.get("出场章"))
|
||||||
|
)
|
||||||
# ④ 卡更新(分批≤6)
|
# ④ 卡更新(分批≤6)
|
||||||
items = sorted(to_update.items())
|
items = sorted(to_update.items())
|
||||||
for i in range(0, len(items), UPDATE_BATCH):
|
for i in range(0, len(items), UPDATE_BATCH):
|
||||||
@ -2501,13 +2508,7 @@ def _run(work_id, max_windows, max_calls, model, redo_window, semantic_on):
|
|||||||
relation_touched.add(
|
relation_touched.add(
|
||||||
_insert_relation_card(conn, work_id, win_no, rp)
|
_insert_relation_card(conn, work_id, win_no, rp)
|
||||||
)
|
)
|
||||||
# ⑥ 机械收尾:出场章统一并入(纯出场 + 被更新卡,抽检#2)+ 窗置 done
|
# ⑥ 机械收尾:仅处理未被更新模型消费的出场章,然后窗置 done。
|
||||||
for it in obs.get("纯出场", []):
|
|
||||||
nm = (it.get("名称") or "").strip()
|
|
||||||
if nm in name_map:
|
|
||||||
pres_add.setdefault(name_map[nm][0], set()).update(
|
|
||||||
_int_chaps(it.get("出场章"))
|
|
||||||
)
|
|
||||||
presence_touched = set()
|
presence_touched = set()
|
||||||
for did, chs in pres_add.items():
|
for did, chs in pres_add.items():
|
||||||
if not chs:
|
if not chs:
|
||||||
|
|||||||
@ -2438,10 +2438,12 @@ def test_run_pure_presence_rejects_external_state_and_revision_conflicts():
|
|||||||
|
|
||||||
|
|
||||||
def test_run_presence_paths_accept_numeric_strings():
|
def test_run_presence_paths_accept_numeric_strings():
|
||||||
"""run 的已知更新归并卡与纯出场都把数字字符串章号落成整数。"""
|
"""同卡横跨新信息与纯出场时,有无模型更新都只走一次实体写入并落全章节。"""
|
||||||
|
|
||||||
|
def run_case(updates):
|
||||||
state = {
|
state = {
|
||||||
"window_status": "pending",
|
"window_status": "pending",
|
||||||
|
"revisions": {701: 0},
|
||||||
"payload": {
|
"payload": {
|
||||||
"type": "character",
|
"type": "character",
|
||||||
"名称": "安若雪",
|
"名称": "安若雪",
|
||||||
@ -2461,7 +2463,7 @@ def test_run_presence_paths_accept_numeric_strings():
|
|||||||
],
|
],
|
||||||
"纯出场": [{"名称": "安若雪", "出场章": ["71"]}],
|
"纯出场": [{"名称": "安若雪", "出场章": ["71"]}],
|
||||||
}, {})
|
}, {})
|
||||||
return ({"更新": []}, {})
|
return ({"更新": deepcopy(updates)}, {})
|
||||||
|
|
||||||
with patch.object(pu.psycopg, "connect", side_effect=lambda *_: _RunConn(state)), \
|
with patch.object(pu.psycopg, "connect", side_effect=lambda *_: _RunConn(state)), \
|
||||||
patch.object(pu, "load_entity_contracts", return_value=_fake_contracts()), \
|
patch.object(pu, "load_entity_contracts", return_value=_fake_contracts()), \
|
||||||
@ -2475,16 +2477,32 @@ def test_run_presence_paths_accept_numeric_strings():
|
|||||||
"load_known",
|
"load_known",
|
||||||
return_value=({"安若雪": (701, "character", "旧摘要")}, {}, {}, {701: 0}),
|
return_value=({"安若雪": (701, "character", "旧摘要")}, {}, {}, {701: 0}),
|
||||||
), \
|
), \
|
||||||
patch.object(pu, "m3_json", side_effect=fake_m3_json):
|
patch.object(pu, "m3_json", side_effect=fake_m3_json), \
|
||||||
pu._run(
|
patch.object(pu, "undo_window"), \
|
||||||
work_id=8,
|
patch.object(pu, "merge_card", wraps=pu.merge_card) as merge_mock, \
|
||||||
max_windows=0,
|
patch.object(
|
||||||
max_calls=0,
|
pu, "_write_locked_upgrade_draft", wraps=pu._write_locked_upgrade_draft
|
||||||
model="MiniMax-M3",
|
) as write_mock:
|
||||||
redo_window=0,
|
pu._run(8, 0, 0, "MiniMax-M3", 0, False)
|
||||||
semantic_on=False,
|
return state, merge_mock.call_count, write_mock.call_count
|
||||||
)
|
|
||||||
check("run-presence-归并与纯出场数字字符串均落库", state["payload"]["出场章"] == [70, 71])
|
updated, merge_calls, write_calls = run_case([
|
||||||
|
{"draft_id": 701, "变更字段": {"一句话摘要": "新摘要"}, "别名新增": []},
|
||||||
|
])
|
||||||
|
check("run-presence-有更新时只写一次",
|
||||||
|
merge_calls == 1 and write_calls == 1 and updated["revisions"][701] == 1,
|
||||||
|
detail=f"merge={merge_calls}, write={write_calls}, state={updated}")
|
||||||
|
check("run-presence-有更新时一次消费两数组章节",
|
||||||
|
updated["window_status"] == "done" and updated["payload"]["出场章"] == [70, 71],
|
||||||
|
detail=str(updated))
|
||||||
|
|
||||||
|
unchanged, merge_calls, write_calls = run_case([])
|
||||||
|
check("run-presence-无更新时由机械收尾写一次",
|
||||||
|
merge_calls == 0 and write_calls == 1 and unchanged["revisions"][701] == 1,
|
||||||
|
detail=f"merge={merge_calls}, write={write_calls}, state={unchanged}")
|
||||||
|
check("run-presence-无更新时两数组章节仍落库",
|
||||||
|
unchanged["window_status"] == "done" and unchanged["payload"]["出场章"] == [70, 71],
|
||||||
|
detail=str(unchanged))
|
||||||
|
|
||||||
|
|
||||||
def test_load_known_projection():
|
def test_load_known_projection():
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user