Provider-agnostic system + user prompt builder for the confidence scoring pipeline's Pass 3 (AI re-rank). Output contract is JSON with "ranked" array; works with OpenAI, Claude, and local OpenAI-compatible servers (LM Studio, Ollama). Made-with: Cursor
93 lines
3.3 KiB
Python
93 lines
3.3 KiB
Python
"""Smoke tests for bank_rec_prompt module."""
|
|
|
|
from odoo.tests.common import TransactionCase, tagged
|
|
from odoo.addons.fusion_accounting_ai.services.prompts.bank_rec_prompt import (
|
|
SYSTEM_PROMPT,
|
|
build_prompt,
|
|
)
|
|
from odoo.addons.fusion_accounting_bank_rec.services.confidence_scoring import (
|
|
ScoredCandidate,
|
|
)
|
|
from . import _factories as f
|
|
|
|
|
|
@tagged('post_install', '-at_install')
|
|
class TestBankRecPrompt(TransactionCase):
|
|
|
|
def setUp(self):
|
|
super().setUp()
|
|
self.partner = self.env['res.partner'].create({'name': 'Prompt Test Partner'})
|
|
self.bank_line = f.make_bank_line(
|
|
self.env,
|
|
amount=1847.50,
|
|
partner=self.partner,
|
|
memo='RBC ETF DEP REF 4831',
|
|
)
|
|
self.scored = [
|
|
ScoredCandidate(
|
|
candidate_id=101,
|
|
confidence=0.92,
|
|
reasoning='Exact amount match',
|
|
score_amount_match=1.0,
|
|
score_partner_pattern=0.5,
|
|
score_precedent_similarity=0.85,
|
|
),
|
|
ScoredCandidate(
|
|
candidate_id=102,
|
|
confidence=0.71,
|
|
reasoning='Close amount',
|
|
score_amount_match=0.95,
|
|
score_partner_pattern=0.5,
|
|
score_precedent_similarity=0.6,
|
|
),
|
|
]
|
|
|
|
def test_system_prompt_requires_json_output(self):
|
|
self.assertIn('JSON', SYSTEM_PROMPT)
|
|
self.assertIn('"ranked"', SYSTEM_PROMPT)
|
|
|
|
def test_build_prompt_returns_tuple(self):
|
|
result = build_prompt(self.bank_line, self.scored)
|
|
self.assertEqual(len(result), 2)
|
|
system, user = result
|
|
self.assertIsInstance(system, str)
|
|
self.assertIsInstance(user, str)
|
|
|
|
def test_user_prompt_includes_bank_line_details(self):
|
|
_, user = build_prompt(self.bank_line, self.scored)
|
|
self.assertIn('1847.5', user)
|
|
self.assertIn('RBC ETF DEP REF 4831', user)
|
|
self.assertIn('Prompt Test Partner', user)
|
|
|
|
def test_user_prompt_includes_all_candidates(self):
|
|
_, user = build_prompt(self.bank_line, self.scored)
|
|
self.assertIn('candidate_id=101', user)
|
|
self.assertIn('candidate_id=102', user)
|
|
|
|
def test_user_prompt_omits_pattern_section_when_none(self):
|
|
_, user = build_prompt(self.bank_line, self.scored, pattern=None)
|
|
self.assertNotIn('PARTNER PATTERN', user)
|
|
|
|
def test_user_prompt_includes_pattern_section_when_provided(self):
|
|
pattern = f.make_pattern(self.env, partner=self.partner, reconcile_count=15)
|
|
_, user = build_prompt(self.bank_line, self.scored, pattern=pattern)
|
|
self.assertIn('PARTNER PATTERN', user)
|
|
self.assertIn('15', user)
|
|
|
|
def test_user_prompt_includes_precedents_when_provided(self):
|
|
from odoo.addons.fusion_accounting_bank_rec.services.precedent_lookup import (
|
|
PrecedentMatch,
|
|
)
|
|
precedents = [
|
|
PrecedentMatch(
|
|
precedent_id=1,
|
|
amount=1847.50,
|
|
memo_tokens='RBC,ETF',
|
|
matched_move_line_count=1,
|
|
similarity_score=0.95,
|
|
),
|
|
]
|
|
_, user = build_prompt(self.bank_line, self.scored, precedents=precedents)
|
|
self.assertIn('RECENT PRECEDENTS', user)
|
|
self.assertIn('0.95', user)
|