68 lines
3.5 KiB
Python
68 lines
3.5 KiB
Python
import copy
|
|
import json
|
|
|
|
from tools.rag.build_chunks import TOKEN_COUNTER
|
|
from tools.rag.llm_context import compact_rag_payload
|
|
|
|
|
|
def response(text='Unikátny dôkaz o práci osoby. '):
|
|
return {'status': 'ok', 'query': 'Práca?', 'engine': 'test', 'strategies': ['test'],
|
|
'complete': None, 'truncated': False, 'truncation_reasons': [], 'index_version': {'version': 'test'},
|
|
'instructions': ['Cituj iba dodané zdroje.'], 'answer_format': {},
|
|
'sources': [{'source_id': 'S1', 'document_path': 'pages/eva/README.md', 'title': 'Eva',
|
|
'source_url': 'https://example.test/eva', 'text': text,
|
|
'query_evidence': {'huge_diagnostic': text * 10},
|
|
'retrieval': {'rank': 1}}], 'context': text}
|
|
|
|
|
|
def test_compact_payload_contains_evidence_once_and_preserves_sources():
|
|
original = response()
|
|
before = copy.deepcopy(original)
|
|
compact = compact_rag_payload(original)
|
|
assert original == before
|
|
assert json.dumps(compact, ensure_ascii=False).count(original['sources'][0]['text']) == 1
|
|
assert 'text' not in compact['sources'][0] and 'query_evidence' not in compact['sources'][0]
|
|
assert compact['sources'][0]['source_url'] == 'https://example.test/eva'
|
|
assert compact['index_version'] == original['index_version']
|
|
assert compact_rag_payload(compact) == compact
|
|
|
|
|
|
def test_entire_tool_json_is_bounded_and_marks_omitted_evidence():
|
|
original = response('Veľmi dlhý dôkaz 🧑🏽💻. ' * 2000)
|
|
original['sources'].append({**original['sources'][0], 'source_id': 'S2', 'text': 'Ďalší dôkaz'})
|
|
compact = compact_rag_payload(original, max_tokens=700)
|
|
used = TOKEN_COUNTER.count(json.dumps(compact, ensure_ascii=False, separators=(',', ':')))
|
|
assert used <= 700 and compact['context_budget']['used_tokens'] == used
|
|
assert compact['complete'] is False and compact['truncated'] is True
|
|
assert 'llm_context_budget' in compact['truncation_reasons']
|
|
assert 'KONIEC ZDROJA S1' in compact['context']
|
|
assert compact['source_count'] == 1 and '[OBSAH ZDROJA OREZANÝ]' in compact['context']
|
|
assert json.loads(compact['context'].splitlines()[1])['truncated'] is True
|
|
|
|
|
|
def test_diagnostics_are_explicit_and_never_forwarded_by_projection():
|
|
verbose = compact_rag_payload(response(), include_diagnostics=True)
|
|
assert verbose['diagnostics']['sources'][0]['query_evidence']
|
|
projected = compact_rag_payload(verbose)
|
|
assert 'diagnostics' not in projected
|
|
assert 'huge_diagnostic' not in json.dumps(projected)
|
|
|
|
|
|
def test_http_serialization_stays_within_budget_and_diagnostics_are_opt_in(monkeypatch):
|
|
from fastapi.testclient import TestClient
|
|
import app.main as main
|
|
import app.routes as routes
|
|
original = response('Dlhý dôkaz 🐈 ' * 1800)
|
|
monkeypatch.setattr(main, 'embed_query', lambda _: None)
|
|
monkeypatch.setattr(routes, 'build_rag_context', lambda *a, **kw: original)
|
|
monkeypatch.setenv('RAG_LLM_MAX_TOKENS', '700')
|
|
with TestClient(main.app) as client:
|
|
headers = {'X-API-Key': 'a' * 64}
|
|
compact = client.post('/rag', json={'query': 'Práca?'}, headers=headers)
|
|
assert compact.status_code == 200
|
|
assert TOKEN_COUNTER.count(compact.text) <= 700
|
|
assert 'diagnostics' not in compact.json()
|
|
assert 'text' not in compact.json()['sources'][0]
|
|
verbose = client.post('/rag', json={'query': 'Práca?', 'include_diagnostics': True}, headers=headers)
|
|
assert verbose.status_code == 200 and verbose.json()['diagnostics'] == original
|