examples: primary qwen3-8b extractor
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
8fc0fd7646
commit
d1a5da1008
2 changed files with 211 additions and 0 deletions
81
tests/test_examples_llm_extract.py
Normal file
81
tests/test_examples_llm_extract.py
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
"""Tests for LLM extraction — respx mocks the llama-cpp /completion endpoint."""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from datetime import date
|
||||
from decimal import Decimal
|
||||
|
||||
import httpx
|
||||
import pytest
|
||||
import respx
|
||||
|
||||
from fire_planner.examples.llm_extract import extract_with_qwen
|
||||
from fire_planner.examples.models import RawPost
|
||||
|
||||
LLAMA_URL = "http://llama-cpp.llama-cpp.svc.cluster.local:8000/v1/chat/completions"
|
||||
|
||||
|
||||
def _post() -> RawPost:
|
||||
return RawPost(
|
||||
reddit_id="a1",
|
||||
source_sub="ExpatFIRE",
|
||||
url="u",
|
||||
title="FIRE'd at 38 — Manila",
|
||||
body="Net worth $1.2M, living in Manila with family of 3, retired last year.",
|
||||
created_at=date(2026, 1, 1),
|
||||
)
|
||||
|
||||
|
||||
@respx.mock
|
||||
@pytest.mark.asyncio
|
||||
async def test_extract_with_qwen_parses_json_response() -> None:
|
||||
payload = {
|
||||
"country": "Philippines",
|
||||
"city": "Manila",
|
||||
"portfolio_native": 1200000,
|
||||
"annual_exp_native": 18000,
|
||||
"raw_currency": "USD",
|
||||
"age": 38,
|
||||
"family_size": 3,
|
||||
"fi_status": "FIRE",
|
||||
"is_retired": True,
|
||||
"confidence": 0.85,
|
||||
}
|
||||
respx.post(LLAMA_URL).respond(
|
||||
200,
|
||||
json={"choices": [{"message": {"content": json.dumps(payload)}}]},
|
||||
)
|
||||
|
||||
async with httpx.AsyncClient() as client:
|
||||
out = await extract_with_qwen(_post(), llama_url=LLAMA_URL, client=client)
|
||||
|
||||
assert out is not None
|
||||
assert out.country == "Philippines"
|
||||
assert out.portfolio_native == Decimal("1200000")
|
||||
assert out.confidence == Decimal("0.85")
|
||||
assert out.llm_model == "qwen3-8b"
|
||||
|
||||
|
||||
@respx.mock
|
||||
@pytest.mark.asyncio
|
||||
async def test_extract_with_qwen_returns_none_on_unparseable_json() -> None:
|
||||
respx.post(LLAMA_URL).respond(
|
||||
200,
|
||||
json={"choices": [{"message": {"content": "definitely not json"}}]},
|
||||
)
|
||||
|
||||
async with httpx.AsyncClient() as client:
|
||||
out = await extract_with_qwen(_post(), llama_url=LLAMA_URL, client=client)
|
||||
|
||||
assert out is None
|
||||
|
||||
|
||||
@respx.mock
|
||||
@pytest.mark.asyncio
|
||||
async def test_extract_with_qwen_returns_none_on_http_error() -> None:
|
||||
respx.post(LLAMA_URL).respond(500)
|
||||
|
||||
async with httpx.AsyncClient() as client:
|
||||
out = await extract_with_qwen(_post(), llama_url=LLAMA_URL, client=client)
|
||||
|
||||
assert out is None
|
||||
Loading…
Add table
Add a link
Reference in a new issue