Constraint resolver: aggregate mass/footprint across a combo instead of pairwise-only checks, treat medium/atmosphere as agreement not supply/demand, reduce multi-provider checks by best/sum instead of AND-ing every provider, fail closed on unrecognized mutex values, add a propulsion-viability (thrust-to-weight) rule. Seed data updated to match (nuclear/solar-sail footprint floors, water-medium exclusions, explicit ground/gravity providers). Domain metric units were stored globally per metric name instead of per-domain, silently corrupting cost_efficiency for every domain but the first one seeded — fixed with a schema migration. Stub estimator's cost_efficiency/safety/availability/reliability were a backwards formula and flat constants; replaced with heuristics grounded in each entity's thrust_profile/energy_form/infrastructure. LLM estimate_physics() now receives each metric's unit and expected range instead of a bare name, fixing wildly miscalibrated estimates traced back to the prompt's own hardcoded example anchoring the model to the wrong order of magnitude. Sharpened the safety-estimation and plausibility-review prompts. Deduped provider parsing logic into llm/parsing.py. Web pipeline form can now pick an LLM provider per run instead of only via server env var. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
30 lines
1.0 KiB
Python
30 lines
1.0 KiB
Python
"""Mock LLM provider for testing."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from physcom.llm.base import LLMProvider
|
|
from physcom.models.domain import MetricBound
|
|
|
|
|
|
class MockLLMProvider(LLMProvider):
|
|
"""Returns deterministic stub responses for testing."""
|
|
|
|
def __init__(self, default_estimates: dict[str, float] | None = None) -> None:
|
|
self._defaults = default_estimates or {}
|
|
|
|
def estimate_physics(
|
|
self, combination_description: str, metrics: list[MetricBound]
|
|
) -> dict[str, float]:
|
|
result = {}
|
|
for mb in metrics:
|
|
result[mb.metric_name] = self._defaults.get(mb.metric_name, 0.5)
|
|
return result
|
|
|
|
def review_plausibility(
|
|
self, combination_description: str, scores: dict[str, float]
|
|
) -> tuple[str, bool]:
|
|
avg = sum(scores.values()) / max(len(scores), 1)
|
|
if avg > 0.5:
|
|
return ("This concept appears plausible and worth further investigation.", True)
|
|
return ("This concept has significant feasibility challenges.", False)
|