Files
ai-town/engine-python/app/models.py
empty 1fd318c9e3 feat(engine): add faction power system with event triggers
- Add FactionData model with power and members fields
- Add FactionEventResult model for faction event responses
- Add faction field to AgentState
- Implement faction classification based on emotion
- Add faction event triggers (festival/panic) when power >= 5
- Update StepResponse to include triggered_faction_event
- Add tests for new faction system

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 12:01:07 +08:00

123 lines
3.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from __future__ import annotations
from pydantic import BaseModel, Field
from typing import List, Dict, Optional
from enum import Enum
class Emotion(str, Enum):
CALM = "calm"
HAPPY = "happy"
ANXIOUS = "anxious"
class Weather(str, Enum):
SUNNY = "sunny"
RAINY = "rainy"
class GlobalMeter(BaseModel):
"""全体能量条"""
value: int = 0
threshold: int = 100
cooldown: int = 0
class WorldEffect(BaseModel):
"""持续影响效果"""
type: str
name: str
intensity: int = 1
remaining_ticks: int = 5
mood_modifier: int = 0
class Opinion(BaseModel):
"""角色对事件的观点"""
about: str # 事件类型 (effect_type)
text: str # 观点内容
tick: int # 生成时的 tick
class Stance(BaseModel):
"""角色立场"""
optimism: float = Field(default=0.5, ge=0.0, le=1.0)
fear: float = Field(default=0.5, ge=0.0, le=1.0)
class FactionData(BaseModel):
"""单个派系的数据"""
power: int = 0
members: List[str] = Field(default_factory=list)
class Factions(BaseModel):
"""派系分布(带 power 和 members"""
optimists: FactionData = Field(default_factory=FactionData)
fearful: FactionData = Field(default_factory=FactionData)
class FactionEventResult(BaseModel):
"""阵营事件触发结果"""
type: Optional[str] = None # "festival" | "panic" | None
source_faction: Optional[str] = None # "optimists" | "fearful"
class AgentState(BaseModel):
emotion: Emotion = Emotion.CALM
goal: str = ""
memory: List[str] = Field(default_factory=list)
opinion: Optional[Opinion] = None
# 记录已评论过的事件,防止重复生成
commented_effects: List[str] = Field(default_factory=list)
# 角色立场
stance: Stance = Field(default_factory=Stance)
# 所属阵营
faction: str = "neutral" # "optimists" | "fearful" | "neutral"
class WorldState(BaseModel):
tick: int = 0
weather: Weather = Weather.SUNNY
town_mood: int = Field(default=0, ge=-10, le=10)
agents: Dict[str, AgentState] = Field(default_factory=dict)
events: List[str] = Field(default_factory=list)
global_meter: GlobalMeter = Field(default_factory=GlobalMeter)
world_effects: List[WorldEffect] = Field(default_factory=list)
factions: Factions = Field(default_factory=Factions)
class Event(BaseModel):
type: str
text: str
user: str
ts: float
class StepRequest(BaseModel):
events: List[Event] = Field(default_factory=list)
class Action(BaseModel):
agent_id: str
say: str
do: str
class GlobalEventInfo(BaseModel):
"""世界级事件信息"""
name: str
description: str
class GlobalEventResult(BaseModel):
"""世界级事件触发结果"""
triggered: bool = False
event: Optional[GlobalEventInfo] = None
class StepResponse(BaseModel):
world_state: WorldState
actions: List[Action]
global_event: GlobalEventResult = Field(default_factory=GlobalEventResult)
triggered_faction_event: FactionEventResult = Field(default_factory=FactionEventResult)