| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- from dataclasses import dataclass
- from app.schemas.conclusion import ConclusionSummary, RankedFinding
- from app.schemas.evidence import EvidenceSummary
- from app.schemas.experiment import ExperimentSummary, ScoreCard
- from app.schemas.observation import ObservationSummary
- from app.schemas.orchestration import OrchestratorPlan
- @dataclass(slots=True)
- class StubRunnerResult:
- probe_evidence: list[EvidenceSummary]
- experiments: list[ExperimentSummary]
- conclusion: ConclusionSummary
- status: str
- class StubRunnerService:
- def run_initial_plan(
- self,
- *,
- session_id: str,
- observation: ObservationSummary,
- plan: OrchestratorPlan,
- ) -> StubRunnerResult:
- periodic_hint = 0.79 if "periodic" in observation.tags else 0.68
- tonal_hint = 0.74 if observation.duration_ms >= 4500 else 0.61
- classifier_top_score = 0.64 if "periodic" in observation.tags else 0.55
- probe_evidence = [
- EvidenceSummary(
- id=f"{session_id}-e1",
- producer_module_id="energy_probe",
- category="feature",
- values={
- "rms": 0.41,
- "peak_count": 7,
- "duration_ms": observation.duration_ms,
- },
- confidence=0.86,
- ),
- EvidenceSummary(
- id=f"{session_id}-e2",
- producer_module_id="periodicity_probe",
- category="pattern",
- values={
- "repeat_interval_ms": 620,
- "stability": periodic_hint,
- },
- confidence=0.82,
- ),
- EvidenceSummary(
- id=f"{session_id}-e3",
- producer_module_id="baseline_sound_classifier",
- category="classification",
- values={
- "top_k": [
- {
- "label": "periodic_alert_tone",
- "score": classifier_top_score,
- },
- {
- "label": "mechanical_click_sequence",
- "score": 0.27,
- },
- ]
- },
- confidence=classifier_top_score,
- ),
- ]
- experiments: list[ExperimentSummary] = []
- parent_id: str | None = None
- for index, planned_experiment in enumerate(plan.experiments, start=1):
- experiment_id = f"{session_id}-x{index}"
- title = planned_experiment.goal
- score_total = 0.72 + (index * 0.06)
- notes = [
- f"Executed planned chain '{planned_experiment.preferred_chain_id or 'ad-hoc'}'."
- ]
- if planned_experiment.preferred_chain_id == "periodic_validation_chain":
- components = {
- "repeat_consistency": 0.89,
- "pattern_clarity": periodic_hint,
- "resource_cost": 0.18,
- }
- penalties = {"mixed_source_risk": 0.05}
- notes.append("Autocorrelation and cepstrum align on repeat interval.")
- failure_reasons: list[str] = []
- elif planned_experiment.preferred_chain_id == "harmonic_validation_chain":
- components = {
- "tonal_stability": tonal_hint,
- "harmonic_ratio": 0.71,
- "resource_cost": 0.22,
- }
- penalties = {"short_clip_penalty": 0.04}
- notes.append("Harmonic structure is present but not fully dominant.")
- failure_reasons = []
- else:
- components = {
- "mixed_source_probability": 0.43,
- "post_separation_gain": 0.18,
- "resource_cost": 0.31,
- }
- penalties = {"separation_uncertainty": 0.08}
- notes.append(
- "Source separation did not improve confidence enough to overtake the periodic hypothesis."
- )
- failure_reasons = []
- experiments.append(
- ExperimentSummary(
- id=experiment_id,
- parent_id=parent_id,
- hypothesis_id=planned_experiment.hypothesis_id,
- title=title,
- status="done",
- pipeline_summary=[
- node.module_id for node in planned_experiment.pipeline
- ],
- score=ScoreCard(
- total=round(score_total, 2),
- components=components,
- penalties=penalties,
- notes=notes,
- ),
- failure_reasons=failure_reasons,
- )
- )
- parent_id = experiment_id
- conclusion = ConclusionSummary(
- summary=(
- "The sample most likely contains a periodic alert-like tone rather "
- "than an unstructured environmental event."
- ),
- findings=[
- RankedFinding(
- label="Periodic alert tone",
- confidence=0.84 if "periodic" in observation.tags else 0.76,
- supporting_evidence=[
- "Repeat interval remains stable near 620 ms.",
- "Probe chain shows clear onset grouping.",
- "Validation chains favor periodic structure over diffuse events.",
- ],
- contradicting_evidence=[
- "Mixed-source contamination is not fully ruled out.",
- ],
- )
- ],
- uncertainty=[
- "The current stub runner does not yet incorporate source separation output.",
- "A longer clip may improve confidence around tonal stability.",
- ],
- suggested_next_actions=[
- "Run harmonic validation against a longer sample window.",
- "Add a mixed-source validation branch if future captures include overlap tags.",
- ],
- )
- return StubRunnerResult(
- probe_evidence=probe_evidence,
- experiments=experiments,
- conclusion=conclusion,
- status="reviewing",
- )
|