feat: yaml_patcher and ProfileApplyRequest support metric_weights and doc_weights
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -137,3 +137,104 @@ def test_apply_no_profiles_returns_empty(tmp_path):
|
||||
_resolve_absolute=True,
|
||||
)
|
||||
assert patched == []
|
||||
|
||||
|
||||
def test_apply_metric_weights_patches_yaml(tmp_path):
|
||||
"""Applying metric_weights writes them into the YAML."""
|
||||
import yaml as yaml_lib
|
||||
import pytest
|
||||
scenario_file = tmp_path / "w-scenario.yaml"
|
||||
scenario_file.write_text(
|
||||
"scenario_name: test\nmode: offline\njudge_model: m\nembedding_model: e\n"
|
||||
"dataset: d.csv\nmetrics:\n- faithfulness\noutput_dir: out\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
from webapp.services.yaml_patcher import apply_profiles_to_scenario
|
||||
patched = apply_profiles_to_scenario(
|
||||
scenario_path=str(scenario_file),
|
||||
judge_profile=None, answer_profile=None, dataset_profile=None,
|
||||
metric_weights={"faithfulness": 0.7, "context_recall": 0.3},
|
||||
_resolve_absolute=True,
|
||||
)
|
||||
assert "metric_weights" in patched
|
||||
data = yaml_lib.safe_load(scenario_file.read_text())
|
||||
assert abs(data["metric_weights"]["faithfulness"] - 0.7) < 1e-9
|
||||
|
||||
|
||||
def test_apply_doc_weights_patches_yaml(tmp_path):
|
||||
"""Applying doc_weights writes them into the YAML."""
|
||||
import yaml as yaml_lib
|
||||
scenario_file = tmp_path / "dw-scenario.yaml"
|
||||
scenario_file.write_text(
|
||||
"scenario_name: test\nmode: offline\njudge_model: m\nembedding_model: e\n"
|
||||
"dataset: d.csv\nmetrics:\n- faithfulness\noutput_dir: out\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
from webapp.services.yaml_patcher import apply_profiles_to_scenario
|
||||
patched = apply_profiles_to_scenario(
|
||||
scenario_path=str(scenario_file),
|
||||
judge_profile=None, answer_profile=None, dataset_profile=None,
|
||||
doc_weights={"doc.pdf": 2.0},
|
||||
_resolve_absolute=True,
|
||||
)
|
||||
assert "doc_weights" in patched
|
||||
data = yaml_lib.safe_load(scenario_file.read_text())
|
||||
assert abs(data["doc_weights"]["doc.pdf"] - 2.0) < 1e-9
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Connectivity test endpoint tests
|
||||
# ---------------------------------------------------------------------------
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
|
||||
def test_probe_connectivity_success(client):
|
||||
"""POST /api/llm-profiles/probe returns ok=True on successful completion."""
|
||||
mock_response = MagicMock()
|
||||
mock_response.choices = [MagicMock()]
|
||||
with patch("webapp.api.llm_profiles.OpenAI") as MockOpenAI:
|
||||
MockOpenAI.return_value.chat.completions.create.return_value = mock_response
|
||||
resp = client.post("/api/llm-profiles/probe", json={
|
||||
"model": "test-model",
|
||||
"base_url": "http://x/v1",
|
||||
"api_key": "sk-test",
|
||||
})
|
||||
assert resp.status_code == 200
|
||||
data = resp.json()
|
||||
assert data["ok"] is True
|
||||
assert data["latency_ms"] is not None
|
||||
|
||||
|
||||
def test_probe_connectivity_failure(client):
|
||||
"""POST /api/llm-profiles/probe returns ok=False when the LLM call raises."""
|
||||
with patch("webapp.api.llm_profiles.OpenAI") as MockOpenAI:
|
||||
MockOpenAI.return_value.chat.completions.create.side_effect = Exception("connection refused")
|
||||
resp = client.post("/api/llm-profiles/probe", json={
|
||||
"model": "test-model",
|
||||
"base_url": "http://x/v1",
|
||||
"api_key": "sk-test",
|
||||
})
|
||||
assert resp.status_code == 200
|
||||
data = resp.json()
|
||||
assert data["ok"] is False
|
||||
assert "connection refused" in data["message"]
|
||||
|
||||
|
||||
def test_test_saved_profile_success(client):
|
||||
"""POST /api/llm-profiles/{id}/test returns ok=True for a saved profile."""
|
||||
body = {"name": "T", "model": "m1", "base_url": "http://x/v1", "api_key": "k"}
|
||||
pid = client.post("/api/llm-profiles", json=body).json()["profile_id"]
|
||||
|
||||
mock_response = MagicMock()
|
||||
mock_response.choices = [MagicMock()]
|
||||
with patch("webapp.api.llm_profiles.OpenAI") as MockOpenAI:
|
||||
MockOpenAI.return_value.chat.completions.create.return_value = mock_response
|
||||
resp = client.post(f"/api/llm-profiles/{pid}/test")
|
||||
assert resp.status_code == 200
|
||||
assert resp.json()["ok"] is True
|
||||
|
||||
|
||||
def test_test_nonexistent_profile_returns_404(client):
|
||||
"""POST /api/llm-profiles/{id}/test returns 404 for unknown profile id."""
|
||||
resp = client.post("/api/llm-profiles/nonexistent/test")
|
||||
assert resp.status_code == 404
|
||||
|
||||
Reference in New Issue
Block a user