feat(ai): add PixelRAG VLM generate preflight

This commit is contained in:
ogt
2026-07-10 00:17:02 +08:00
parent d1ca067054
commit bed3a8a8ee
11 changed files with 384 additions and 14 deletions

View File

@@ -257,6 +257,83 @@ def test_pixelrag_vlm_replay_worker_auto_selects_installed_candidate(tmp_path, m
assert payload["summary"]["executed_ok_count"] == 1
def test_pixelrag_vlm_replay_worker_generate_probe_blocks_tile_generate(tmp_path, monkeypatch):
from services import pixelrag_vlm_replay_worker_service as service
_write_receipt(
tmp_path,
platform="shopee_tw",
manifest_id="shopee-ok",
title="Shopee 防曬乳",
url="https://shopee.tw/search?keyword=sunscreen",
)
monkeypatch.setattr(
service,
"build_pixelrag_vlm_route_readiness",
lambda **kwargs: {
"policy": "read_only_pixelrag_vlm_route_readiness_v1",
"status": "critical",
"summary": {
"configured_model": "minicpm-v:latest",
"candidate_model": "gemma3:4b",
"candidate_host": "http://34.21.145.224:11434",
"tag_model_route_ready": True,
"model_route_ready": False,
"generate_probe_performed": True,
"generate_probe_ok_count": 0,
"generate_route_ready": False,
"generate_ready_model": "",
"generate_ready_host": "",
"generate_ready_provider": "",
"model_call_performed": True,
},
"controlled_apply": {"model_call": True},
"next_machine_action": "repair_ollama_vlm_generate_runtime_or_proxy_timeout",
},
)
class FakeOllama:
def __init__(self, model):
self.model = model
def generate(self, *args, **kwargs):
raise AssertionError("tile VLM generate should not be called")
monkeypatch.setattr(service, "OllamaService", FakeOllama)
payload = service.run_pixelrag_ollama_vlm_replay_worker(
artifact_root=tmp_path,
output_root=tmp_path / "receipts",
platform="shopee_tw",
model="minicpm-v:latest",
execute=True,
write_receipt=True,
tile_limit=1,
auto_select_model=True,
probe_generate_before_execute=True,
)
assert payload["status"] == "critical"
assert payload["model"] == "gemma3:4b"
assert payload["summary"]["model_route_not_ready_count"] == 1
assert payload["summary"]["route_model_call_performed"] is True
assert payload["summary"]["tile_model_call_performed"] is False
assert payload["summary"]["model_call_performed"] is True
assert payload["controlled_apply"]["model_call"] is True
assert payload["next_machine_action"] == "repair_ollama_vlm_generate_runtime_or_proxy_timeout"
item = payload["worker_items"][0]
assert item["worker_status"] == "model_route_not_ready"
assert item["generate_probe_performed"] is True
assert item["generate_route_ready"] is False
assert item["model_call_performed"] is False
receipt_path = tmp_path / "receipts" / "shopee_tw" / "shopee-ok" / "vlm_replay_receipt.json"
assert receipt_path.exists()
receipt = json.loads(receipt_path.read_text(encoding="utf-8"))
assert receipt["worker_status"] == "model_route_not_ready"
assert receipt["artifact_write_performed"] is True
assert receipt["generate_route_ready"] is False
def test_pixelrag_vlm_replay_worker_cli_outputs_machine_readable_json(tmp_path):
_write_receipt(
tmp_path,

View File

@@ -67,6 +67,70 @@ def test_pixelrag_vlm_route_readiness_critical_when_no_candidate(monkeypatch):
assert payload["next_machine_action"] == "install_or_configure_pixelrag_vlm_model_on_approved_ollama_host"
def test_pixelrag_vlm_route_readiness_generate_probe_success(monkeypatch):
from services import pixelrag_vlm_route_readiness_service as service
monkeypatch.setattr(service, "_approved_hosts", lambda: ["http://secondary:11434"])
monkeypatch.setattr(
service.requests,
"get",
lambda url, timeout: FakeResponse(payload={"models": [{"name": "gemma3:4b"}]}),
)
monkeypatch.setattr(
service.requests,
"post",
lambda url, json, timeout: FakeResponse(payload={"response": "OK", "done": True}),
)
payload = service.build_pixelrag_vlm_route_readiness(
model="minicpm-v:latest",
probe_generate=True,
probe_timeout_seconds=1,
)
assert payload["status"] == "warning"
assert payload["summary"]["candidate_model"] == "gemma3:4b"
assert payload["summary"]["tag_model_route_ready"] is True
assert payload["summary"]["model_route_ready"] is True
assert payload["summary"]["generate_probe_performed"] is True
assert payload["summary"]["generate_probe_ok_count"] == 1
assert payload["summary"]["generate_route_ready"] is True
assert payload["summary"]["generate_ready_host"] == "http://secondary:11434"
assert payload["controlled_apply"]["model_call"] is True
def test_pixelrag_vlm_route_readiness_generate_probe_failure_blocks_route(monkeypatch):
from services import pixelrag_vlm_route_readiness_service as service
monkeypatch.setattr(service, "_approved_hosts", lambda: ["http://secondary:11434"])
monkeypatch.setattr(
service.requests,
"get",
lambda url, timeout: FakeResponse(payload={"models": [{"name": "gemma3:4b"}]}),
)
def fake_post(url, json, timeout):
raise TimeoutError("generate timeout")
monkeypatch.setattr(service.requests, "post", fake_post)
payload = service.build_pixelrag_vlm_route_readiness(
model="minicpm-v:latest",
probe_generate=True,
probe_timeout_seconds=1,
)
assert payload["status"] == "critical"
assert payload["success"] is False
assert payload["summary"]["candidate_model"] == "gemma3:4b"
assert payload["summary"]["tag_model_route_ready"] is True
assert payload["summary"]["model_route_ready"] is False
assert payload["summary"]["generate_probe_performed"] is True
assert payload["summary"]["generate_probe_ok_count"] == 0
assert payload["summary"]["generate_route_ready"] is False
assert payload["next_machine_action"] == "repair_ollama_vlm_generate_runtime_or_proxy_timeout"
def test_pixelrag_vlm_route_readiness_route_returns_readback(monkeypatch):
from flask import Flask
from routes import system_public_routes as routes
@@ -87,6 +151,7 @@ def test_pixelrag_vlm_route_readiness_route_returns_readback(monkeypatch):
app = Flask(__name__)
with app.test_request_context(
"/api/ai-automation/pixelrag-vlm-route-readiness?model=minicpm-v:latest"
"&probe_generate=true&probe_timeout=4"
):
response = routes.ai_automation_pixelrag_vlm_route_readiness_api.__wrapped__()
payload = response.get_json()