"""Explicit complete-chain requests must remain required in delivery scope.""" from copy import deepcopy import pytest from backend.prospecting import delivery from backend.prospecting.discussion_scope import conditions, requirements URL = 'https://www.xiaohongshu.com/explore/' + 'a' * 24 def task(goal, **inputs): return {'id':'relation-wording-fixture','status':'completed','current_step':'results', 'inputs':{'goal':goal,'intent':'inspect','subject_urls':[URL],'target_candidates':None, 'max_comments_per_note':5,'_goal_version':1,**inputs}, 'artifacts':{'messages':[{'role':'user','text':goal}],'sources':[],'decisions':[], 'operation_evidence':[],'browser_history':{'is_successful':True}, 'browser_verdict':'success','analysis_goal_version':1}} @pytest.mark.parametrize('goal', [ '这次只验证一个讨论组的完整回复链。', '请保存完整回复链。', '检查完整的回复链路。', '逐条核对发言人、直接父评论或父回复、根讨论。', '逐条核对发言人、直接的父回复、根评论。', '确认直接父评论。', '请验证父回复。', '请核对父评论与根讨论。', '父评论及根讨论都要核对。', ]) def test_complete_chain_and_direct_parent_variants_are_explicit_requirements(goal): row = task(goal) before = deepcopy(row) assert 'relations' in requirements(row) checks = conditions(row) assert any(c['key']=='discussion_relations' and c['required'] and not c['met'] for c in checks) assert not delivery.project(row)['fulfillment']['complete'] assert row == before and row['inputs']['max_comments_per_note']==5 @pytest.mark.parametrize('goal', [ '只保存正文,不用核对完整回复链。', '只保存正文,不需要验证直接父回复。', '只保存正文,完整回复链不用核对。', '只保存正文,不必再核对父评论与根讨论。', '只保存正文。比如:验证完整回复链。', '只保存正文。评论里写“逐条核对直接父回复和根讨论”,这是引用。', '只保存正文。\n> 检查完整回复链。', '只保存正文。\n```\n确认直接父评论\n```', '只保存父评论,评论与回复合计最多5条。', ]) def test_negation_quotation_examples_and_comment_only_requests_do_not_add_relations(goal): assert 'relations' not in requirements(task(goal)) @pytest.mark.parametrize('cancellation', ['不用再核对完整回复链。','完整回复链不用核对。','不需要验证直接父回复。']) def test_later_explicit_cancellation_removes_chain_requirement(cancellation): row = task('核对完整回复链。') row['artifacts']['messages'].append({'role':'user','text':cancellation}) assert 'relations' not in requirements(row) row['artifacts']['messages'].append({'role':'user','text':'还是请核对完整回复链。'}) assert 'relations' in requirements(row) @pytest.mark.parametrize('inputs', [ {'intent':'discover','target_candidates':1}, {'intent':'export'}, {'intent':'inspect','subject_urls':[],'max_notes':None}, ]) def test_chain_wording_does_not_expand_other_task_contracts(inputs): assert conditions(task('核对完整回复链,核对直接父回复和根讨论。',**inputs))==[] def test_assistant_or_model_notes_cannot_add_chain_requirement(): row = task('只保存正文。',user_notes='核对完整回复链。') row['artifacts']['messages'].append({'role':'assistant','text':'逐条核对直接父回复和根讨论。'}) assert not conditions(row)