Skip to content

Commit 05f7b73

Browse files
authored
Add AUTO routing for priority=cost
1 parent 2aedaa5 commit 05f7b73

2 files changed

Lines changed: 53 additions & 4 deletions

File tree

lexoid/api.py

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
download_file,
3838
get_file_type,
3939
get_webpage_soup,
40+
has_image_in_pdf,
4041
is_supported_file_type,
4142
is_supported_url_file_type,
4243
recursive_read_html,
@@ -62,6 +63,23 @@ def wrapper(*args, **kwargs):
6263
if args[1] == ParserType.AUTO:
6364
router_priority = kwargs.get("router_priority", "speed")
6465
autoselect_llm = kwargs.get("autoselect_llm", False)
66+
if router_priority == "cost" and has_image_in_pdf(kwargs["path"]):
67+
# Handling this outside of router to allow for multiple func calls
68+
kwargs["parser_type"] = ParserType.STATIC_PARSE
69+
kwargs["framework"] = "paddleocr"
70+
result = func(**kwargs)
71+
character_threshold = kwargs.get("character_threshold", 100)
72+
len_result = len(result["raw"].strip())
73+
if len_result < character_threshold:
74+
logger.debug(
75+
f"Low character count detected ({len_result} < {character_threshold}), returning result"
76+
)
77+
return result
78+
logger.debug(
79+
f"Character count above threshold ({len_result} >= {character_threshold}), switching to LLM_PARSE"
80+
)
81+
kwargs["parser_type"] = ParserType.LLM_PARSE
82+
return func(**kwargs)
6583
routed_parser_type, model = router(
6684
kwargs["path"], router_priority, autoselect_llm=autoselect_llm
6785
)
@@ -173,15 +191,15 @@ def parse_chunk_list(
173191
"""
174192
combined_segments = []
175193
raw_texts = []
194+
parsers_used = []
176195
token_usage = {"input": 0, "output": 0, "llm_page_count": 0}
177196
for file_path in file_paths:
178197
result = parse_chunk(file_path, parser_type, **kwargs)
179198
combined_segments.extend(result["segments"])
180199
raw_texts.append(result["raw"])
181-
if (
182-
result.get("parser_used") == ParserType.LLM_PARSE
183-
and "token_usage" in result
184-
):
200+
parser_used = result.get("parser_used")
201+
parsers_used.append(parser_used.value if parser_used else "UNKNOWN")
202+
if parser_used == ParserType.LLM_PARSE and "token_usage" in result:
185203
token_usage["input"] += result["token_usage"]["input"]
186204
token_usage["output"] += result["token_usage"]["output"]
187205
token_usage["llm_page_count"] += len(result["segments"])
@@ -195,6 +213,7 @@ def parse_chunk_list(
195213
"parent_title": kwargs.get("parent_title", ""),
196214
"recursive_docs": [],
197215
"token_usage": token_usage,
216+
"parsers_used": parsers_used,
198217
}
199218

200219

@@ -328,6 +347,11 @@ def parse(
328347
),
329348
"total": sum(r["token_usage"]["total"] for r in chunk_results),
330349
},
350+
"parsers_used": [
351+
parser
352+
for r in chunk_results
353+
for parser in r.get("parsers_used", [])
354+
],
331355
}
332356

333357
if "api_cost_mapping" in kwargs and "token_usage" in result:

tests/test_parser.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,31 @@ async def test_parse_with_schema():
432432
assert all(key in result for key in sample_schema.keys())
433433

434434

435+
@pytest.mark.parametrize("character_threshold", [160, 100])
436+
@pytest.mark.asyncio
437+
async def test_cost_priority_routing(character_threshold):
438+
sample = "examples/inputs/NHL_agreement_2022_pg1.pdf"
439+
parser_type = "AUTO"
440+
router_priority = "cost"
441+
api_cost_path = os.path.join(os.path.dirname(__file__), "api_cost_mapping.json")
442+
config = {
443+
"parser_type": parser_type,
444+
"router_priority": router_priority,
445+
"page_nums": 1,
446+
"pages_per_split": 1,
447+
"character_threshold": character_threshold,
448+
"api_cost_mapping": api_cost_path,
449+
}
450+
result = parse(sample, **config)
451+
logger.debug(f"Token cost: {result['token_cost']}")
452+
if character_threshold > 150:
453+
assert "STATIC_PARSE" in result["parsers_used"]
454+
assert result["token_cost"]["total"] == 0
455+
else:
456+
assert "LLM_PARSE" in result["parsers_used"]
457+
assert result["token_cost"]["total"] > 0
458+
459+
435460
@pytest.mark.asyncio
436461
async def test_audio_parse():
437462
path = "examples/inputs/harvard.wav"

0 commit comments

Comments
 (0)