Multi-stage evidence-grounded inference architecture replacing the monolithic 9B model extraction pipeline. CPU-first specialist services handle routine extraction while the 9B vLLM model is preserved for semantic adjudication of ambiguous cases. Key components: - Capability-aware inference gateway (OpenAI-compatible + Ollama) - Endpoint registry with DB migrations and REST API - Sentence-aware document segmenter (property tests) - Deterministic financial parsing with offset integrity - Symbol resolution with ambiguity detection - Specialist service (GLiNER2, dynamic batching, K8s deployment) - Company-specific sentiment (FinBERT, calibration) - Retrieval-based novelty and duplicate detection - Confidence calibration pipeline - Deterministic routing engine (property tests) - 9B adjudication layer with VRAM gating - Stock-specific impact model (features, labels, baseline, trained) - Pipeline orchestrator (state machine, queues, leases, feature flags) - Bounded parallelism (async workers, semaphore, load shedding) - Observability (tracing, metrics, alerts) - Compatibility adapter (v3→v2 golden mapping tests) - Shadow/canary promotion framework - Active learning and fine-tuning pipeline Test results: 1,161 tests pass, ruff lint clean. All 282 spec tasks completed.
146 lines
5.0 KiB
Python
146 lines
5.0 KiB
Python
"""Tests for benchmark configuration definitions.
|
|
|
|
Validates: Requirements 16.2, 16.3, 16.5
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
from services.intelligence_pipeline_v3.benchmark.configurations import (
|
|
BASELINE_CURRENT,
|
|
BASELINE_STRICT_SCHEMA,
|
|
BASELINE_TEMP_ZERO,
|
|
BenchmarkConfig,
|
|
StructuredOutputMode,
|
|
list_configurations,
|
|
)
|
|
|
|
|
|
class TestBenchmarkConfig:
|
|
"""Tests for BenchmarkConfig model validation."""
|
|
|
|
def test_valid_config_creation(self) -> None:
|
|
config = BenchmarkConfig(
|
|
config_name="test",
|
|
description="A test config",
|
|
model_name="test-model",
|
|
temperature=0.5,
|
|
max_output_tokens=1024,
|
|
structured_output_mode=StructuredOutputMode.NONE,
|
|
)
|
|
assert config.config_name == "test"
|
|
assert config.temperature == 0.5
|
|
assert config.seed is None
|
|
assert config.additional_params == {}
|
|
|
|
def test_temperature_bounds(self) -> None:
|
|
with pytest.raises(Exception):
|
|
BenchmarkConfig(
|
|
config_name="bad",
|
|
description="bad temp",
|
|
model_name="m",
|
|
temperature=-0.1,
|
|
max_output_tokens=100,
|
|
structured_output_mode=StructuredOutputMode.NONE,
|
|
)
|
|
|
|
with pytest.raises(Exception):
|
|
BenchmarkConfig(
|
|
config_name="bad",
|
|
description="bad temp",
|
|
model_name="m",
|
|
temperature=2.1,
|
|
max_output_tokens=100,
|
|
structured_output_mode=StructuredOutputMode.NONE,
|
|
)
|
|
|
|
def test_max_output_tokens_must_be_positive(self) -> None:
|
|
with pytest.raises(Exception):
|
|
BenchmarkConfig(
|
|
config_name="bad",
|
|
description="bad tokens",
|
|
model_name="m",
|
|
temperature=0.0,
|
|
max_output_tokens=0,
|
|
structured_output_mode=StructuredOutputMode.NONE,
|
|
)
|
|
|
|
def test_config_is_frozen(self) -> None:
|
|
config = BenchmarkConfig(
|
|
config_name="frozen",
|
|
description="immutable",
|
|
model_name="m",
|
|
temperature=0.0,
|
|
max_output_tokens=512,
|
|
structured_output_mode=StructuredOutputMode.NONE,
|
|
)
|
|
with pytest.raises(Exception):
|
|
config.temperature = 1.0 # type: ignore[misc]
|
|
|
|
|
|
class TestStandardConfigurations:
|
|
"""Tests for the predefined standard configurations."""
|
|
|
|
def test_baseline_current_uses_temperature_07(self) -> None:
|
|
assert BASELINE_CURRENT.temperature == 0.7
|
|
|
|
def test_baseline_current_uses_json_object(self) -> None:
|
|
assert BASELINE_CURRENT.structured_output_mode == StructuredOutputMode.JSON_OBJECT
|
|
|
|
def test_baseline_current_no_seed(self) -> None:
|
|
assert BASELINE_CURRENT.seed is None
|
|
|
|
def test_baseline_temp_zero_is_deterministic(self) -> None:
|
|
assert BASELINE_TEMP_ZERO.temperature == 0.0
|
|
assert BASELINE_TEMP_ZERO.seed == 0
|
|
|
|
def test_baseline_temp_zero_same_model(self) -> None:
|
|
assert BASELINE_TEMP_ZERO.model_name == BASELINE_CURRENT.model_name
|
|
|
|
def test_baseline_temp_zero_still_json_object(self) -> None:
|
|
assert BASELINE_TEMP_ZERO.structured_output_mode == StructuredOutputMode.JSON_OBJECT
|
|
|
|
def test_baseline_strict_schema_uses_json_schema(self) -> None:
|
|
assert BASELINE_STRICT_SCHEMA.structured_output_mode == StructuredOutputMode.JSON_SCHEMA
|
|
|
|
def test_baseline_strict_schema_temp_zero(self) -> None:
|
|
assert BASELINE_STRICT_SCHEMA.temperature == 0.0
|
|
|
|
def test_baseline_strict_schema_same_model(self) -> None:
|
|
assert BASELINE_STRICT_SCHEMA.model_name == BASELINE_CURRENT.model_name
|
|
|
|
def test_all_configs_have_unique_names(self) -> None:
|
|
configs = list_configurations()
|
|
names = [c.config_name for c in configs]
|
|
assert len(names) == len(set(names))
|
|
|
|
def test_list_configurations_returns_all_three(self) -> None:
|
|
configs = list_configurations()
|
|
assert len(configs) == 3
|
|
names = {c.config_name for c in configs}
|
|
assert "baseline_current" in names
|
|
assert "baseline_temp_zero" in names
|
|
assert "baseline_strict_schema" in names
|
|
|
|
def test_all_configs_use_same_max_output_tokens(self) -> None:
|
|
configs = list_configurations()
|
|
tokens = {c.max_output_tokens for c in configs}
|
|
assert len(tokens) == 1 # All should agree
|
|
|
|
def test_all_configs_use_same_model(self) -> None:
|
|
configs = list_configurations()
|
|
models = {c.model_name for c in configs}
|
|
assert len(models) == 1
|
|
|
|
|
|
class TestStructuredOutputMode:
|
|
"""Tests for the StructuredOutputMode enum."""
|
|
|
|
def test_values(self) -> None:
|
|
assert StructuredOutputMode.NONE.value == "none"
|
|
assert StructuredOutputMode.JSON_OBJECT.value == "json_object"
|
|
assert StructuredOutputMode.JSON_SCHEMA.value == "json_schema"
|
|
|
|
def test_enum_members(self) -> None:
|
|
assert len(StructuredOutputMode) == 3
|