- 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>
38 lines
1.9 KiB
Python
38 lines
1.9 KiB
Python
"""
|
|
ManagerAi model - Pure data model for AI manager configuration.
|
|
|
|
Migrated from Discord app with business logic extracted to AIService.
|
|
Contains only field definitions and relationships.
|
|
"""
|
|
|
|
from sqlmodel import SQLModel, Field, Relationship
|
|
from sqlalchemy import Column, BigInteger
|
|
from typing import List, TYPE_CHECKING
|
|
|
|
if TYPE_CHECKING:
|
|
# from .play import Play # Will be uncommented when Play model is created
|
|
pass
|
|
|
|
|
|
class ManagerAiBase(SQLModel):
|
|
"""Base model for ManagerAi configuration data."""
|
|
|
|
id: int | None = Field(default=None, sa_column=Column(BigInteger(), primary_key=True, autoincrement=True))
|
|
name: str = Field(index=True)
|
|
steal: int = Field(default=5, ge=1, le=10, description="AI steal aggression level")
|
|
running: int = Field(default=5, ge=1, le=10, description="AI base running aggression")
|
|
hold: int = Field(default=5, ge=1, le=10, description="AI pitcher hold tendency")
|
|
catcher_throw: int = Field(default=5, ge=1, le=10, description="AI catcher throw decision")
|
|
uncapped_home: int = Field(default=5, ge=1, le=10, description="AI uncapped advance to home")
|
|
uncapped_third: int = Field(default=5, ge=1, le=10, description="AI uncapped advance to third")
|
|
uncapped_trail: int = Field(default=5, ge=1, le=10, description="AI trailing runner decisions")
|
|
bullpen_matchup: int = Field(default=5, ge=1, le=10, description="AI bullpen usage preference")
|
|
behind_aggression: int = Field(default=5, ge=1, le=10, description="AI aggression when behind")
|
|
ahead_aggression: int = Field(default=5, ge=1, le=10, description="AI aggression when ahead")
|
|
decide_throw: int = Field(default=5, ge=1, le=10, description="AI throw decision making")
|
|
|
|
|
|
class ManagerAi(ManagerAiBase, table=True):
|
|
"""ManagerAi model for AI configuration storage."""
|
|
|
|
# plays: List["Play"] = Relationship(back_populates="managerai") # Will be uncommented when Play model is created |