feat: Intelligence Pipeline v3 — full implementation
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.
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
"""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
|
||||
Reference in New Issue
Block a user