Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
b4b9f61
werewolf game in progress
Keyu-He Sep 21, 2025
155b794
werewolf game in progress
Keyu-He Sep 21, 2025
70a7f33
updated prompt
Keyu-He Oct 31, 2025
c640a1a
current progress
Keyu-He Nov 13, 2025
b7bbfbb
Fix custom/local model support bugs
Keyu-He Nov 13, 2025
f8841e9
fix mypy errors
Keyu-He Nov 13, 2025
80954e7
Design Social Game class, werewolf demo working in progress
Keyu-He Nov 14, 2025
7d1fefe
update on the SocialGame class / SocialDeductionGame class
Keyu-He Nov 26, 2025
e7aedd3
fix mypy errors
Keyu-He Nov 26, 2025
0fd87ff
debugging on the prompts
Keyu-He Nov 30, 2025
3bd7812
refactor SocialDeductionGame for real-time history and fix some visib…
Keyu-He Dec 3, 2025
17651b4
werewolf game debug
Keyu-He Dec 4, 2025
0afc26d
Refactor social_game.py and update werewolves example
Keyu-He Dec 7, 2025
ac09af2
Add Social Game Engine documentation
Keyu-He Dec 7, 2025
e7e6a37
Delete examples/experimental/negotiation_arena/NegotiationArena_1_Buy…
Keyu-He Dec 7, 2025
e431c6a
Revert unnessarily changes in the uniform_sample and server.py
Keyu-He Dec 7, 2025
8dc91c8
Minor update on werewolf prompt, Compatibility on uniform sampler and…
Keyu-He Dec 7, 2025
f1616ce
update uniform_sampler and server.py to the correct versions
Keyu-He Dec 7, 2025
99d059f
move visibility prompt inside werewolf game's config
Keyu-He Dec 7, 2025
0064c31
Fix premature termination and LiteLLM schema validation errors
Keyu-He Dec 7, 2025
a60177d
feat: add werewolf Redis state store
nikitachaudharicodes Dec 9, 2025
e2df06a
feat: add werewolf async game loop
nikitachaudharicodes Dec 9, 2025
38dadbc
feat: scaffold matchmaking + werewolf models
nikitachaudharicodes Dec 9, 2025
e4e9df8
feat: expand fastapi server with werewolf + matchmaking APIs
nikitachaudharicodes Dec 9, 2025
7d8fea6
feat: add arena game contract dataclasses
nikitachaudharicodes Dec 9, 2025
3f0105d
chore: add arena frontend tooling and scaffold
nikitachaudharicodes Dec 9, 2025
4dde649
feat: add arena app routes, layouts, and styling
nikitachaudharicodes Dec 9, 2025
deb457d
feat: add shared arena shell, hooks, and UI components
nikitachaudharicodes Dec 9, 2025
665b421
feat: add werewolf frontend module (api, hooks, UI)
nikitachaudharicodes Dec 9, 2025
32f01ce
feat: add sotopia chatbot application
nikitachaudharicodes Dec 9, 2025
1a2a227
update gitignore
nikitachaudharicodes Dec 9, 2025
504d2b7
Minor fastapi_server.py edit
nikitachaudharicodes Dec 9, 2025
16ed54d
feat: add configurable prisoners dilemma backend
nikitachaudharicodes Dec 9, 2025
108714b
feat: add prisoners dilemma frontend module
nikitachaudharicodes Dec 9, 2025
d4a55d2
feat: add Public Goods Game backend
nikitachaudharicodes Dec 9, 2025
e079642
feat: add Public Goods frontend module
nikitachaudharicodes Dec 9, 2025
4fed048
fix: add features to game summary type
nikitachaudharicodes Dec 12, 2025
2662229
fix: relax game module loader types
nikitachaudharicodes Dec 12, 2025
fdb51ff
fix: guard prisoners dilemma error rendering
nikitachaudharicodes Dec 12, 2025
c3d1efb
fix: normalize public goods session types
nikitachaudharicodes Dec 12, 2025
b777dea
minor fix
nikitachaudharicodes Dec 12, 2025
723d72e
fix: relax dynamic module types
nikitachaudharicodes Dec 12, 2025
ee200dc
chore: configure railway python build
nikitachaudharicodes Dec 12, 2025
c43ae9c
edit build command
nikitachaudharicodes Dec 12, 2025
4100bfc
chore: add requirements and railway config for deployment
nikitachaudharicodes Dec 12, 2025
56dc906
add tool versions
nikitachaudharicodes Dec 12, 2025
3bb19d8
fix: swap backend to absolute imports and package game folders
nikitachaudharicodes Dec 13, 2025
40ea477
fix: examples import error
nikitachaudharicodes Dec 17, 2025
9d6ac61
Update: railway.config.json
nikitachaudharicodes Dec 17, 2025
3a87c7c
Update: railway.config.json
nikitachaudharicodes Dec 17, 2025
cb04991
Update: railway.config.json
nikitachaudharicodes Dec 17, 2025
da29d5c
Align core files with upstream/main
nikitachaudharicodes Jan 16, 2026
f84fa9f
Ignore sotopia-chatbot directory
nikitachaudharicodes Jan 16, 2026
fdb146a
Stop tracking and ignore sotopia-chatbot directory
nikitachaudharicodes Jan 16, 2026
8d21e26
Stop tracking .env.local; keep example only
nikitachaudharicodes Jan 16, 2026
130bc19
Remove duplicate FastAPI server; use api/fastapi_server.py as canonic…
nikitachaudharicodes Jan 16, 2026
8f0c722
Remove experimental PD and public goods stubs
nikitachaudharicodes Jan 16, 2026
7a40cfa
feat(database): storage backend and exports for user/game models
nikitachaudharicodes Mar 13, 2026
6650f91
feat(database): add UserProfile, GameResult, EloHistory, OAuthAccount
nikitachaudharicodes Mar 13, 2026
3493721
refactor(core): pass action_instruction to agenerate_action for Arena
nikitachaudharicodes Mar 13, 2026
3772ef6
feat(generation): phase instructions and AgentAction normalization fo…
nikitachaudharicodes Mar 13, 2026
222e8f8
feat(api): JWT auth, register, login, /me, legacy identity
nikitachaudharicodes Mar 13, 2026
b6b0464
feat(api): OAuth Google, GitHub, Discord
nikitachaudharicodes Mar 13, 2026
f4850bb
feat(api): ELO rating and leaderboard endpoints
nikitachaudharicodes Mar 13, 2026
c1956f3
feat(api): profile endpoints and shared profile stats helper
nikitachaudharicodes Mar 13, 2026
2385af6
feat(api): mount auth, oauth, profile, leaderboard routes; WebSocket …
nikitachaudharicodes Mar 13, 2026
ba51817
feat(api): WebSocket utils and human agent for Arena
nikitachaudharicodes Mar 13, 2026
a799cde
feat(api): werewolf WebSocket runner, voting, pack visibility
nikitachaudharicodes Mar 13, 2026
ce6cc25
feat(frontend): API config and auth client
nikitachaudharicodes Mar 13, 2026
5365e31
feat(frontend): WebSocket client for simulation
nikitachaudharicodes Mar 13, 2026
4b99df9
feat(frontend): AuthContext and AuthHeader
nikitachaudharicodes Mar 13, 2026
39f4004
feat(frontend): login and register pages
nikitachaudharicodes Mar 13, 2026
b832dea
feat(frontend): profile and history pages
nikitachaudharicodes Mar 13, 2026
605a085
feat(frontend): pluggable game module system
nikitachaudharicodes Mar 13, 2026
01b2b1e
feat(frontend): werewolf game module definition
nikitachaudharicodes Mar 13, 2026
1e137a2
feat(frontend): werewolf WebSocket session and actions
nikitachaudharicodes Mar 13, 2026
fddf84a
feat(frontend): werewolf lobby, board, and supporting UI
nikitachaudharicodes Mar 13, 2026
14b645a
feat(frontend): landing page and providers
nikitachaudharicodes Mar 13, 2026
d077814
refactor(frontend): identity and memory hooks for Arena
nikitachaudharicodes Mar 13, 2026
6066689
chore(frontend): Next.js and deployment config
nikitachaudharicodes Mar 13, 2026
1638b26
refactor: remove PD and public-goods stubs and legacy chat_server
nikitachaudharicodes Mar 14, 2026
a861d84
chore(examples): update werewolf example config and script
nikitachaudharicodes Mar 14, 2026
7f302c2
chore: deps and gitignore
nikitachaudharicodes Mar 14, 2026
e8a9c73
chore: add EC2 deployment scripts under scripts/ec2/
nikitachaudharicodes Mar 14, 2026
1e016c3
refactor(frontend): remove unused experiment-root and orphaned chat c…
nikitachaudharicodes Mar 14, 2026
cb8c409
chore(api): remove debug prints; fix(werewolf): ...
nikitachaudharicodes Mar 14, 2026
e198c66
chore: ignore root package-lock, test_websocket, redis_agent_bot, loc…
nikitachaudharicodes Mar 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ coverage.xml
*.py,cover
.hypothesis/
.pytest_cache/
tsconfig.tsbuildinfo

# Translations
*.mo
Expand Down Expand Up @@ -165,9 +166,27 @@ docs/node_modules/*
redis-data/*

sotopia/cli/install/redis-data/*

# Secrets and runtime files
*.pem
.backend.pid
.frontend.pid
redis-stack-server-*/

*.rdb
examples/experimental/negotiation_arena/redis-data/*
*.rdb
*.dot
sotopia-chatbot/


# Internal / scratch docs (not committed)
internal-docs/
.env.example
sotopia-chat/frontend/.env.local.example

# Frontend deployment diagram (local reference only)
sotopia-chat/frontend/deployment-architecture
# Local dev scripts (optional, not committed)
scripts/start_local.sh
scripts/stop_local.sh
5 changes: 4 additions & 1 deletion examples/experimental/werewolves/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"actions": [
"action"
],
"action_order": "simultaneous",
"visibility": "team"
},
"Night_seer": {
Expand All @@ -67,6 +68,7 @@
"actions": [
"action"
],
"action_order": "simultaneous",
"visibility": "private"
},
"Night_witch": {
Expand All @@ -76,6 +78,7 @@
"actions": [
"action"
],
"action_order": "simultaneous",
"visibility": "private",
"internal_state": {
"save_available": true,
Expand All @@ -86,7 +89,7 @@
"actions": [
"speak"
],
"action_order": "round-robin",
"action_order": "simultaneous",
"visibility": "public"
},
"Day_vote": {
Expand Down
53 changes: 29 additions & 24 deletions examples/experimental/werewolves/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
from pathlib import Path
import logging
from typing import Any, Dict, List
import random
from collections import Counter

from rich.logging import RichHandler
import redis
Expand Down Expand Up @@ -126,7 +124,7 @@ def handle_action(
env.internal_state["votes"][agent_name] = target

elif env.current_state == "Night_werewolf":
# Werewolves choose kill target
# Werewolves choose kill target (record proposals only; unanimity enforced in _should_transition_state)
role = env.agent_to_role.get(agent_name, "")
if role == "Werewolf" and action.action_type == "action":
if "kill" in action.argument.lower():
Expand All @@ -139,22 +137,6 @@ def handle_action(
if "kill_target_proposals" not in env.internal_state:
env.internal_state["kill_target_proposals"] = {}
env.internal_state["kill_target_proposals"][agent_name] = target
# Update the werewolf kill result
kill_votes = env.internal_state.get("kill_target_proposals", {})
if kill_votes:
# Count votes
vote_counts = Counter(kill_votes.values())
if vote_counts:
# Find max votes
max_votes = max(vote_counts.values())
# Get all targets with max votes
candidates = [
t for t, c in vote_counts.items() if c == max_votes
]
# Break tie randomly
env.internal_state["kill_target"] = random.choice(
candidates
)

elif env.current_state == "Night_seer":
# Seer inspects someone
Expand Down Expand Up @@ -192,7 +174,7 @@ def handle_action(
if target:
env.internal_state["saved_target"] = target
elif "poison" in action.argument.lower():
env.internal_state["witch_have_posion"] = False
env.internal_state["witch_have_poison"] = False
words = action.argument.split()
target = next(
(w for w in words if w[0].isupper() and w in env.agents),
Expand Down Expand Up @@ -223,10 +205,10 @@ def get_action_instruction(self, env: SocialDeductionGame, agent_name: str) -> s
elif env.current_state == "Night_witch":
if role == "Witch":
if env.internal_state.get(
"witch_have_posion", True
"witch_have_poison", True
) and env.internal_state.get("witch_have_save", True):
use_potion_guide = "You can use 'save NAME' or 'poison NAME'. If you don't want to use potions, you can put 'skip' in the argument of action."
elif env.internal_state.get("witch_have_posion", True):
elif env.internal_state.get("witch_have_poison", True):
use_potion_guide = "You can use 'poison NAME'. If you don't want to use potions, you can put 'skip' in the argument of action."
elif env.internal_state.get("witch_have_save", True):
use_potion_guide = "You can use 'save NAME'. If you don't want to use potions, you can put 'skip' in the argument of action."
Expand All @@ -245,11 +227,34 @@ def get_action_instruction(self, env: SocialDeductionGame, agent_name: str) -> s


class WerewolfEnv(SocialDeductionGame):
"""Werewolf game with voting, kills, and special roles."""
"""Werewolf game with voting, kills, and special roles.

Uses unanimity for werewolf kill target (both must pick the same player),
matching human play where wolves discuss and agree.
"""

def __init__(self, **kwargs: Any) -> None:
super().__init__(action_handler=WerewolfActionHandler(), **kwargs)

def _should_transition_state(self) -> bool:
"""Require werewolf unanimity on kill target before transitioning."""
if self.current_state == "Night_werewolf":
proposals = self.internal_state.get("kill_target_proposals", {}) or {}
alive_werewolves = [
n for n, r in self.agent_to_role.items()
if r == "Werewolf" and self.agent_alive.get(n, False)
]
if not alive_werewolves:
return True
if len(proposals) < len(alive_werewolves):
return False
targets = set(proposals.values())
if len(targets) == 1:
self.internal_state["kill_target"] = next(iter(targets))
return True
return False
return super()._should_transition_state()

def reset(
self,
seed: int | None = None,
Expand All @@ -268,7 +273,7 @@ def reset(
include_background_observations=include_background_observations,
)
# Witch has potions
self.internal_state["witch_have_posion"] = True
self.internal_state["witch_have_poison"] = True
self.internal_state["witch_have_save"] = True
# Werewolves have kill targets
self.internal_state["kill_target_proposals"] = {}
Expand Down
13 changes: 12 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,13 @@ dependencies = [
"pydantic>=2.5.0,<3.0.0",
"hiredis>=3.0.0",
"litellm>=1.80.11",
"aact"
"aact",
"uvicorn[standard]>=0.38.0",
"fastapi>=0.115.2",
"bcrypt>=4.0.0",
"PyJWT>=2.8.0",
"email-validator>=2.0.0",
"httpx>=0.25.0", # For OAuth HTTP requests
]

[build-system]
Expand All @@ -47,6 +53,11 @@ realtime = [
"websockets>=13.1,<14.0",
"pyaudio>=0.2.14,<0.3.0",
]
postgres = [
"asyncpg>=0.29.0",
"sqlalchemy>=2.0.0",
"psycopg2-binary>=2.9.0",
]

[dependency-groups]
dev = [
Expand Down
30 changes: 30 additions & 0 deletions scripts/ec2/clear_ec2_caches.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/bin/bash
# =============================================================================
# Clear caches on EC2 for a clean rebuild
# Run on EC2: bash scripts/ec2/clear_ec2_caches.sh
# =============================================================================

set -e
cd /opt/sotopia

echo "Clearing caches..."

# Python
rm -rf .venv
find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
find . -type f -name "*.pyc" -delete 2>/dev/null || true
rm -rf .pytest_cache 2>/dev/null || true

# Frontend
rm -rf sotopia-chat/frontend/node_modules
rm -rf sotopia-chat/frontend/.next
rm -rf sotopia-chat/frontend/.turbo 2>/dev/null || true
rm -rf sotopia-chat/frontend/out 2>/dev/null || true

# Pip cache (optional - saves space)
rm -rf ~/.cache/pip 2>/dev/null || true

# Pnpm store (optional - forces fresh install)
# rm -rf ~/.local/share/pnpm/store 2>/dev/null || true

echo "Done. Run scripts/ec2/redeploy_ec2.sh to rebuild."
Loading