paper-dynasty-gameplay-webapp/app/models/ai_responses.py
Cal Corum 1c24161e76 CLAUDE: Achieve 100% test pass rate with comprehensive AI service testing
- Fix TypeError in check_steal_opportunity by properly mocking catcher defense
- Correct tag_from_third test calculation to account for all adjustment conditions
- Fix pitcher replacement test by setting appropriate allowed runners threshold
- Add comprehensive test coverage for AI service business logic
- Implement VS Code testing panel configuration with pytest integration
- Create pytest.ini for consistent test execution and warning management
- Add test isolation guidelines and factory pattern implementation
- Establish 102 passing tests with zero failures

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-28 17:55:34 -05:00

72 lines
1.8 KiB
Python

"""
AI Response models for decision-making output.
These models represent the output of AI decision-making processes,
migrated from Discord app managerai_responses.py.
"""
from pydantic import BaseModel
class AiResponse(BaseModel):
"""Base class for AI decision responses."""
ai_note: str = ""
class RunResponse(AiResponse):
"""Response for running decisions."""
min_safe: int | None = None
class JumpResponse(RunResponse):
"""Response for steal attempt decisions."""
must_auto_jump: bool = False
run_if_auto_jump: bool = False
class TagResponse(RunResponse):
"""Response for tag-up decisions."""
pass
class UncappedRunResponse(RunResponse):
"""Response for uncapped advance decisions."""
send_trail: bool = False
trail_min_safe: int = 10
trail_min_safe_delta: int = 0
class ThrowResponse(AiResponse):
"""Response for throw target decisions."""
cutoff: bool = False # Stops on True
at_lead_runner: bool = True
at_trail_runner: bool = False # Stops on False
trail_max_safe: int = 10
trail_max_safe_delta: int = -6
class DefenseResponse(AiResponse):
"""Response for defensive alignment decisions."""
hold_first: bool = False
hold_second: bool = False
hold_third: bool = False
outfield_in: bool = False
infield_in: bool = False
corners_in: bool = False
def defender_in(self, position: str) -> bool:
"""Check if a defender should play in based on position."""
if self.infield_in and position in ['C', '1B', '2B', '3B', 'SS', 'P']:
return True
elif self.corners_in and position in ['C', '1B', '3B', 'P']:
return True
elif self.outfield_in and position in ['LF', 'CF', 'RF']:
return True
return False