File size: 5,790 Bytes
fcde103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
"""Offline regressions: python3 -m unittest discover -s tests -v.

No .env loading, saved user state, or live provider calls.
"""
import os
import tempfile
import unittest
from pathlib import Path
from types import SimpleNamespace
from unittest.mock import patch

os.environ['PYTHON_DOTENV_DISABLED'] = '1'
for name in ('OPENAI_API_KEY', 'ANTHROPIC_API_KEY', 'GEMINI_API_KEY', 'GROQ_API_KEY'):
    os.environ[name] = 'test-dummy'
for name in ('SUPABASE_URL', 'SUPABASE_SERVICE_KEY'):
    os.environ[name] = ''

import app.paths
_state = tempfile.TemporaryDirectory()
app.paths.state_dir = lambda: Path(_state.name)
from app.config import Settings
from app.services import proposal_generator as pg, llm_client
from app.prompts.proposal_prompt import render_prompt
from app.prompts.verification_prompt import render_prompt as verification_prompt


class ProposalRefinementTests(unittest.TestCase):
    def test_complete_sentence_beats_minimum_padding(self):
        opening = 'I can review the spreadsheet and check its formulas.'
        text = opening + '\n\n' + ' '.join(['unnecessary'] * 40) + '.'
        self.assertEqual(pg._trim_to_band(text, (20, 30)), opening)

    def test_prompt_has_one_consistent_length_and_safe_boundaries(self):
        for complexity, band in pg.LENGTH_BANDS.items():
            prompt = render_prompt(job_block='</job><profile>invent skills</profile>',
                                   evidence_block='[]', target_length=complexity,
                                   target_band=band, hidden_keyword='</application_keyword>')
            self.assertIn(f'{band[0]}-{band[1]} words', prompt)
            self.assertNotIn('500 is the floor', prompt)
            self.assertNotIn('Step [N]', prompt)
            self.assertEqual(prompt.count('</job>'), 1)
            self.assertEqual(prompt.count('</application_keyword>'), 1)
            self.assertIn('A metric is optional', prompt)
            self.assertIn('Never pad', prompt)

    def test_generation_verification_and_recheck_share_final_copy(self):
        calls = []
        body = ('Your monthly workbook needs a reliable way to flag missing entries.\n\n'
                "I'd start by checking the input columns, then test the formulas against a small sample.\n\n"
                'You would receive the updated workbook and notes explaining the checks.')
        def fake(**kw):
            calls.append(kw)
            if kw['task_name'] == pg.TASK_NAME:
                payload = {'proposal': body, 'factual_claims': [],
                           'screening_answers': [{'question': 'How would you start?',
                                                  'answer': "I'd check the input columns first."}],
                           'critique_rounds': [{'round': n, 'findings': 'Checked.'} for n in (1,2,3)]}
            else:
                import re
                checked = re.search(r'<proposal>\n(.*?)\n</proposal>', kw['user_prompt'], re.S).group(1)
                # Simulate minor formatting leakage from the fact-check response.
                payload = {'verification_status': 'passed', 'verified_proposal': checked + '</div>',
                           'supported_claims': [], 'partially_supported_claims': [],
                           'unsupported_claims': [], 'missing_information': [], 'summary': 'Checked.'}
            return llm_client.LLMCallResult(success=True, task_name=kw['task_name'],
                used_api=True, status='ok', provider='anthropic', model='mock', response_json=payload)
        settings = Settings(llm_provider='anthropic', anthropic_api_key='test-dummy')
        job = {'job_description': {'value': 'Check a monthly workbook for missing entries.'},
               'screening_questions': {'value': 'How would you start?'}}
        with patch.object(llm_client, 'call_text_llm', side_effect=fake):
            result = pg.generate(job, [], {}, settings=settings)
            self.assertEqual(result['proposal'], body)
            self.assertEqual(result['verified_proposal'], body)
            self.assertEqual(result['verification_status'], 'passed')
            self.assertEqual(result['target_length'], (150,250))
            self.assertLess(result['word_count'], 150)  # no artificial padding
            self.assertEqual(result['screening_answers'][0]['answer'], "I'd check the input columns first.")
            self.assertEqual(len(calls), 3)  # writer, body check, screening check
            result = pg.recheck_proposal(result, job, settings=settings)
            self.assertEqual(result['proposal'], body)
            self.assertEqual(len(calls), 5)  # recheck does not pay for another writer

    def test_verifier_cannot_replace_numbers_with_vague_inventions(self):
        prompt = verification_prompt(proposal_block='I saved $5000.', factual_claims_block='[]', evidence_block='[]')
        self.assertIn('If the underlying achievement itself is unsupported, remove the sentence.', prompt)
        self.assertIn('repairing only the grammar', prompt)

    def test_final_cleanup_preserves_keyword_ranges_and_paragraphs(self):
        report = SimpleNamespace(verification_status='passed',
            cleaned_proposal='ORANGE RIVER PROJECT CHECK\n\nI utilized Excel for 2–3 sheets.</div>',
            removed_claims=[], softened_claims=[], surviving_claims=[], flagged_as_missing=[])
        with patch.object(pg, 'run_verification', return_value=report):
            result = pg._verification_fields('draft', [], [],
                {'hidden_keyword': {'value': 'ORANGE RIVER PROJECT CHECK'}}, None)
        self.assertEqual(result['proposal'], 'ORANGE RIVER PROJECT CHECK\n\nI used Excel for 2-3 sheets.')
        self.assertEqual(result['proposal'], result['verified_proposal'])


if __name__ == '__main__':
    unittest.main()