Spaces:
Running
Running
| # Models Map β `replicalab/models.py` | |
| > All Pydantic data contracts. Frozen with `extra="forbid"` unless noted. | |
| > | |
| > **Tasks implemented:** MOD 01, 02, 03, 04, 09, 11, 12 | |
| ## Enums | |
| ### `ScientistActionType(str, Enum)` | |
| | Value | Meaning | | |
| |-------|---------| | |
| | `propose_protocol` | First protocol submission | | |
| | `revise_protocol` | Modify existing protocol | | |
| | `request_info` | Ask lab manager a question | | |
| | `accept` | Agree to current protocol | | |
| ### `LabManagerActionType(str, Enum)` | |
| | Value | Meaning | | |
| |-------|---------| | |
| | `report_feasibility` | Report on feasibility without suggestions | | |
| | `suggest_alternative` | Propose revised protocol | | |
| | `reject` | Reject protocol outright | | |
| | `accept` | Approve protocol | | |
| ## Action Models | |
| ### `ScientistAction(BaseModel)` β `extra="forbid"` | |
| MOD 01 + MOD 09. Strict contract for scientist output. | |
| | Field | Type | Constraint | Notes | | |
| |-------|------|-----------|-------| | |
| | `action_type` | `ScientistActionType` | required | | | |
| | `sample_size` | `int` | `ge=0` | Must be `>=1` for propose/revise | | |
| | `controls` | `list[str]` | normalized | | | |
| | `technique` | `str` | stripped | Required for propose/revise | | |
| | `duration_days` | `int` | `ge=0` | | | |
| | `required_equipment` | `list[str]` | normalized | | | |
| | `required_reagents` | `list[str]` | normalized | | | |
| | `questions` | `list[str]` | normalized | Required non-empty for request_info | | |
| | `rationale` | `str` | stripped | Required for propose/revise | | |
| **Validation rules:** | |
| - `propose_protocol` / `revise_protocol`: sample_size >= 1, technique required, rationale required, questions must be empty | |
| - `request_info`: questions non-empty, no protocol payload fields | |
| - `accept`: no questions, no protocol payload fields | |
| ### `LabManagerAction(BaseModel)` β `extra="forbid"` | |
| MOD 02. Strict contract with feasible-flag consistency. | |
| | Field | Type | Constraint | Notes | | |
| |-------|------|-----------|-------| | |
| | `action_type` | `LabManagerActionType` | required | | | |
| | `feasible` | `bool` | required | Must equal AND of all constraint flags | | |
| | `budget_ok` | `bool` | required | | | |
| | `equipment_ok` | `bool` | required | | | |
| | `reagents_ok` | `bool` | required | | | |
| | `schedule_ok` | `bool` | required | | | |
| | `staff_ok` | `bool` | required | | | |
| | `suggested_technique` | `str` | stripped | Only for suggest_alternative | | |
| | `suggested_sample_size` | `int` | `ge=0` | Only for suggest_alternative | | |
| | `suggested_controls` | `list[str]` | normalized | Only for suggest_alternative | | |
| | `explanation` | `str` | required non-empty | | | |
| **Validation rules:** | |
| - `feasible` must equal `all(budget_ok, equipment_ok, reagents_ok, schedule_ok, staff_ok)` | |
| - `accept` requires `feasible=True` | |
| - `reject` requires `feasible=False` | |
| - `suggest_alternative` requires `feasible=False` + at least one suggestion field | |
| - Suggestion fields forbidden for non-suggest_alternative actions | |
| ## Observation Models | |
| ### `ConversationEntry(BaseModel)` β `extra="forbid"` | |
| | Field | Type | Notes | | |
| |-------|------|-------| | |
| | `role` | `Literal["scientist", "lab_manager", "system"]` | | | |
| | `message` | `str` | Required non-empty | | |
| | `round_number` | `int` | `ge=0` | | |
| | `action_type` | `Optional[str]` | Null or non-empty | | |
| ### `Protocol(BaseModel)` β `extra="forbid"` | |
| Shared protocol payload used in observations and actions. | |
| | Field | Type | Notes | | |
| |-------|------|-------| | |
| | `sample_size` | `int` | `ge=0` | | |
| | `controls` | `list[str]` | normalized | | |
| | `technique` | `str` | required non-empty | | |
| | `duration_days` | `int` | `ge=0` | | |
| | `required_equipment` | `list[str]` | normalized | | |
| | `required_reagents` | `list[str]` | normalized | | |
| | `rationale` | `str` | required non-empty | | |
| ### `ScientistObservation(BaseModel)` β `extra="forbid"` | |
| | Field | Type | | |
| |-------|------| | |
| | `paper_title` | `str` | | |
| | `paper_hypothesis` | `str` | | |
| | `paper_method` | `str` | | |
| | `paper_key_finding` | `str` | | |
| | `experiment_goal` | `str` | | |
| | `conversation_history` | `list[ConversationEntry]` | | |
| | `current_protocol` | `Optional[Protocol]` | | |
| | `round_number` | `int` (ge=0) | | |
| | `max_rounds` | `int` (ge=0) | | |
| ### `LabManagerObservation(BaseModel)` β `extra="forbid"` | |
| | Field | Type | | |
| |-------|------| | |
| | `budget_total` | `float` (ge=0) | | |
| | `budget_remaining` | `float` (ge=0) | | |
| | `equipment_available` | `list[str]` | | |
| | `equipment_booked` | `list[str]` | | |
| | `reagents_in_stock` | `list[str]` | | |
| | `reagents_out_of_stock` | `list[str]` | | |
| | `staff_count` | `int` (ge=0) | | |
| | `time_limit_days` | `int` (ge=0) | | |
| | `safety_restrictions` | `list[str]` | | |
| | `conversation_history` | `list[ConversationEntry]` | | |
| | `current_protocol` | `Optional[Protocol]` | | |
| | `round_number` | `int` (ge=0) | | |
| | `max_rounds` | `int` (ge=0) | | |
| ### `Observation(BaseModel)` β `extra="forbid"` | |
| Combined wrapper. Each role receives its own view. | |
| | Field | Type | | |
| |-------|------| | |
| | `scientist` | `Optional[ScientistObservation]` | | |
| | `lab_manager` | `Optional[LabManagerObservation]` | | |
| ## Reward & Step Models | |
| ### `RewardBreakdown(BaseModel)` β default `extra="forbid"` | |
| MOD 11. Component scores from judge rubric engine. | |
| | Field | Type | Default | Range | | |
| |-------|------|---------|-------| | |
| | `rigor` | `float` | 0.0 | [0, 1] | | |
| | `feasibility` | `float` | 0.0 | [0, 1] | | |
| | `fidelity` | `float` | 0.0 | [0, 1] | | |
| | `efficiency_bonus` | `float` | 0.0 | unbounded | | |
| | `communication_bonus` | `float` | 0.0 | unbounded | | |
| | `penalties` | `dict[str, float]` | {} | unbounded | | |
| ### `StepInfo(BaseModel)` β `extra="allow"` | |
| MOD 11. Extensible metadata returned with each step. | |
| | Field | Type | Default | | |
| |-------|------|---------| | |
| | `agreement_reached` | `bool` | False | | |
| | `error` | `Optional[str]` | None | | |
| | `reward_breakdown` | `Optional[RewardBreakdown]` | None | | |
| | `judge_notes` | `Optional[str]` | None | | |
| | `verdict` | `Optional[str]` | None | | |
| ### `StepResult(BaseModel)` | |
| | Field | Type | Default | | |
| |-------|------|---------| | |
| | `observation` | `Optional[Observation]` | None | | |
| | `reward` | `float` | 0.0 | | |
| | `done` | `bool` | False | | |
| | `info` | `StepInfo` | StepInfo() | | |
| ## Episode Models | |
| ### `EpisodeState(BaseModel)` β MOD 04 | |
| Full internal state for debugging and replay. | |
| | Field | Type | Default | | |
| |-------|------|---------| | |
| | `seed` | `int` | 0 | | |
| | `scenario_template` | `str` | "" | | |
| | `difficulty` | `str` | "easy" | | |
| | `paper_title` | `str` | "" | | |
| | `paper_hypothesis` | `str` | "" | | |
| | `paper_method` | `str` | "" | | |
| | `paper_key_finding` | `str` | "" | | |
| | `experiment_goal` | `str` | "" | | |
| | `lab_budget_total` | `float` | 0.0 | | |
| | `lab_budget_remaining` | `float` | 0.0 | | |
| | `lab_equipment` | `list[str]` | [] | | |
| | `lab_reagents` | `list[str]` | [] | | |
| | `lab_staff_count` | `int` | 0 | | |
| | `lab_time_limit_days` | `int` | 0 | | |
| | `current_protocol` | `Optional[Protocol]` | None | | |
| | `conversation_history` | `list[ConversationEntry]` | [] | | |
| | `round_number` | `int` | 0 | | |
| | `max_rounds` | `int` | 0 | | |
| | `done` | `bool` | False | | |
| | `agreement_reached` | `bool` | False | | |
| | `reward` | `float` | 0.0 | | |
| | `rigor_score` | `float` | 0.0 | | |
| | `feasibility_score` | `float` | 0.0 | | |
| | `fidelity_score` | `float` | 0.0 | | |
| ### `EpisodeLog(BaseModel)` β MOD 04 | |
| Completed episode record for logging, replay, evaluation. | |
| | Field | Type | Default | | |
| |-------|------|---------| | |
| | `episode_id` | `str` | "" | | |
| | `seed` | `int` | 0 | | |
| | `scenario_template` | `str` | "" | | |
| | `difficulty` | `str` | "easy" | | |
| | `final_state` | `Optional[EpisodeState]` | None | | |
| | `transcript` | `list[ConversationEntry]` | [] | | |
| | `reward_breakdown` | `Optional[RewardBreakdown]` | None | | |
| | `total_reward` | `float` | 0.0 | | |
| | `rounds_used` | `int` | 0 | | |
| | `agreement_reached` | `bool` | False | | |
| | `judge_notes` | `str` | "" | | |
| | `verdict` | `str` | "" | | |
| ## Helper Functions | |
| | Function | Purpose | | |
| |----------|---------| | |
| | `_normalize_string_list(value)` | Strip whitespace, reject empty strings | | |