File size: 3,536 Bytes
fcaa899
 
24bdd7c
 
5db3b83
fcaa899
 
f370e63
 
 
 
 
 
fcaa899
 
 
 
24bdd7c
 
 
f370e63
24bdd7c
5db3b83
fcaa899
 
 
 
24bdd7c
 
 
 
 
 
fcaa899
 
 
 
 
24bdd7c
 
 
fcaa899
5db3b83
 
 
 
 
 
 
 
24bdd7c
5db3b83
77af7b8
 
5db3b83
fcaa899
24bdd7c
 
 
 
 
 
 
 
 
 
 
 
77af7b8
fcaa899
24bdd7c
5db3b83
24bdd7c
5db3b83
 
24bdd7c
5db3b83
24bdd7c
 
 
 
 
5db3b83
24bdd7c
 
 
5db3b83
 
24bdd7c
 
5db3b83
 
24bdd7c
5db3b83
24bdd7c
5db3b83
 
 
24bdd7c
5db3b83
24bdd7c
 
5db3b83
 
fcaa899
5db3b83
fcaa899
 
24bdd7c
f370e63
24bdd7c
fcaa899
 
f370e63
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from pydantic import BaseModel
from typing import List, Optional
import os
from dotenv import load_dotenv

# Choose import based on environment
if os.getenv("DOCKER_ENV"):
    from server.game.game_logic import GameState, StoryGenerator, MAX_RADIATION
else:
    from game.game_logic import GameState, StoryGenerator, MAX_RADIATION

# Load environment variables
load_dotenv()

# API configuration
API_HOST = os.getenv("API_HOST", "0.0.0.0")
API_PORT = int(os.getenv("API_PORT", "8000"))
STATIC_FILES_DIR = os.getenv("STATIC_FILES_DIR", "../client/dist")

app = FastAPI(title="Echoes of Influence")

# Configure CORS
app.add_middleware(
    CORSMiddleware,
    allow_origins=[
        "http://localhost:5173",  # Vite dev server
        f"http://localhost:{API_PORT}",  # API port
        "https://huggingface.co",  # HF main domain
        "https://*.hf.space",      # HF Spaces domains
    ],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# Initialize game components
game_state = GameState()
story_generator = StoryGenerator(api_key=os.getenv("MISTRAL_API_KEY"))

class Choice(BaseModel):
    id: int
    text: str

class StoryResponse(BaseModel):
    story_text: str
    choices: List[Choice]
    is_death: bool = False
    radiation_level: int

class ChatMessage(BaseModel):
    message: str
    choice_id: Optional[int] = None

@app.get("/api/health")
async def health_check():
    """Health check endpoint"""
    return {
        "status": "healthy",
        "game_state": {
            "story_beat": game_state.story_beat,
            "radiation_level": game_state.radiation_level
        }
    }

@app.post("/api/chat", response_model=StoryResponse)
async def chat_endpoint(chat_message: ChatMessage):
    try:
        # Handle restart
        if chat_message.message.lower() == "restart":
            game_state.reset()
            previous_choice = "none"
        else:
            previous_choice = f"Choice {chat_message.choice_id}" if chat_message.choice_id else "none"

        # Generate story segment
        story_segment = story_generator.generate_story_segment(game_state, previous_choice)
        
        # Update radiation level
        game_state.radiation_level += story_segment.radiation_increase
        
        # Check for radiation death
        if game_state.radiation_level >= MAX_RADIATION:
            story_segment = story_generator.process_radiation_death(story_segment)
        
        # Only increment story beat if not dead
        if not story_segment.is_death:
            game_state.story_beat += 1

        # Convert to response format
        choices = [] if story_segment.is_death else [
            Choice(id=i, text=choice.strip())
            for i, choice in enumerate(story_segment.choices, 1)
        ]

        return StoryResponse(
            story_text=story_segment.story_text,
            choices=choices,
            is_death=story_segment.is_death,
            radiation_level=game_state.radiation_level
        )

    except Exception as e:
        print(f"Error: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))

# Mount static files (this should be after all API routes)
app.mount("/", StaticFiles(directory=STATIC_FILES_DIR, html=True), name="static")

if __name__ == "__main__":
    import uvicorn
    uvicorn.run("server.server:app", host=API_HOST, port=API_PORT, reload=True)