{"id":17513028,"url":"https://github.com/hmasdev/langchain_werewolf","last_synced_at":"2026-03-01T13:35:32.242Z","repository":{"id":257831409,"uuid":"864946874","full_name":"hmasdev/langchain_werewolf","owner":"hmasdev","description":"A CUI-based simple werewolf game with `langchain` and `langgraph`","archived":false,"fork":false,"pushed_at":"2025-11-01T03:36:52.000Z","size":3765,"stargazers_count":1,"open_issues_count":5,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-11-01T05:26:30.270Z","etag":null,"topics":["game","langchain","langgraph","llm","werewolf"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hmasdev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-09-29T15:37:30.000Z","updated_at":"2025-09-23T06:37:20.000Z","dependencies_parsed_at":"2024-10-16T16:10:39.873Z","dependency_job_id":"c3a92fa2-d774-4717-b081-cdde94ee8a54","html_url":"https://github.com/hmasdev/langchain_werewolf","commit_stats":null,"previous_names":["hmasdev/langchain_werewolf"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/hmasdev/langchain_werewolf","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hmasdev%2Flangchain_werewolf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hmasdev%2Flangchain_werewolf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hmasdev%2Flangchain_werewolf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hmasdev%2Flangchain_werewolf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hmasdev","download_url":"https://codeload.github.com/hmasdev/langchain_werewolf/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hmasdev%2Flangchain_werewolf/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29970501,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-01T13:32:00.443Z","status":"ssl_error","status_checked_at":"2026-03-01T13:32:00.084Z","response_time":124,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["game","langchain","langgraph","llm","werewolf"],"created_at":"2024-10-20T06:06:46.157Z","updated_at":"2026-03-01T13:35:32.196Z","avatar_url":"https://github.com/hmasdev.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# :chains: :wolf: :chains: `langchain_werewolf` :chains: :wolf: :chains:\n\nA CUI-based simple werewolf game with `langchain` and `langgraph`\n\n![GitHub top language](https://img.shields.io/github/languages/top/hmasdev/langchain_werewolf)\n![GitHub tag (latest SemVer)](https://img.shields.io/github/v/tag/hmasdev/langchain_werewolf?sort=semver)\n![GitHub](https://img.shields.io/github/license/hmasdev/langchain_werewolf)\n![GitHub last commit](https://img.shields.io/github/last-commit/hmasdev/langchain_werewolf)\n![Scheduled Test](https://github.com/hmasdev/langchain_werewolf/actions/workflows/tests-on-schedule.yaml/badge.svg)\n\n![langchain_werewolf_header_image](pics/langchain_werewolf_header_image.png)\n\n## Requirements\n\n- LLM service API keys\n  - OpenAI API Key\n    - [https://platform.openai.com/api-keys](https://platform.openai.com/api-keys)\n  - Groq API Key\n    - [https://console.groq.com/keys](https://console.groq.com/keys)\n  - Gemini API Key\n    - [https://aistudio.google.com/app/apikey](https://aistudio.google.com/app/apikey)\n\n- Python \u003e= 3.10\n- Graphviz\n\n## How to Use\n\n### How to Install\n\n```bash\ngit clone https://github.com/hmasdev/langchain_werewolf.git\ncd langchain_werewolf\npython -m pip install .\n```\n\nIf you have `uv`, `uv sync` is also available to install `langchain_werewolf` instead of `python -m pip install .`.\n\nYou can also install `langchain_werewolf` directly from the repository.\n\n```bash\npython -m pip install git+https://github.com/hmasdev/langchain_werewolf.git\n```\n\n### Preparation\n\n1. Create `.env` file\n2. Set `OPENAI_API_KEY`, `GROQ_API_KEY` or `GOOGLE_API_KEY` in the `.env` file as follows:\n\n   ```text\n   OPENAI_API_KEY=HERE_IS_YOUR_API_KEY\n   GROQ_API_KEY=HERE_IS_YOUR_API_KEY\n   GOOGLE_API_KEY=HERE_IS_YOUR_API_KEY\n   ```\n\n### How to Run\n\nIn your command line interface like `bash`,\n\n```bash\npython -m langchain_werewolf {HERE_IS_YOUR_FAVORITE_OPTIONS}\n```\n\nOn the other hand, you can also enjoy `langchain_werewolf` in python environment\n\n```bash\n$ python\nPython 3.10.11 (main, Sep 20 2024, 18:41:54) [GCC 11.4.0] on linux\nType \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n\u003e\u003e\u003e from langchain_werewolf.main import main\n\u003e\u003e\u003e main(**HERE_IS_YOUR_FAVORITE_OPTIONS)\n```\n\n## Document\n\n### Available Options\n\n```bash\n$ python -m langchain_werewolf --help\nUsage: python -m langchain_werewolf [OPTIONS]\n\nOptions:\n  -n, --n-players INTEGER         The number of players. Default is 4.\n  --n-werewolf INTEGER            The number of players with role='werewolf'.\n                                  Default is 1.\n  --n-villager INTEGER            The number of players with role='villager'.\n                                  Default is 0.\n  --n-knight INTEGER              The number of players with role='knight'.\n                                  Default is 0.\n  --n-fortuneteller INTEGER       The number of players with\n                                  role='fortuneteller'. Default is 0.\n  -o, --output TEXT               The output file. Defaults to \"\".\n  -l, --system-output-level TEXT  The output type of the CLI. ['all',\n                                  'public', 'off'] and player names are valid.\n                                  Default is All.\n  --system-output-interface TEXT  The system interface. Default is\n                                  EInputOutputType.standard.\n  --system-formatter TEXT         The system formatter. The format should not\n                                  include anything other than \"{name}\",\n                                  \"{timestamp}\", \"{message}\",\n                                  \"{participants}\", \"{template}\".\n  -c, --config TEXT               The configuration file. Defaults to \"\". Note\n                                  that you can specify CLI arguments in this\n                                  config file but the config file overwrite\n                                  the CLI arguments.\n  --seed INTEGER                  The random seed. Defaults to -1.\n  --model TEXT                    The model to use. Default is gpt-4o-mini.\n  --recursion-limit INTEGER       The recursion limit. Default is 1000.\n  --debug                         Enable debug mode.\n  --verbose                       Enable verbose mode.\n  --help                          Show this message and exit.\n\n```\n\nYou can also another options in the configuration json file like the followings:\n\n\n\n```json\n{\n    \"general\": {\n        \"n_players\": 5,\n        \"n_players_by_role\": {\n            \"werewolf\": 2,\n            \"fortuneteller\": 1,\n            \"knight\": 2\n        }\n    },\n    \"game\": {\n        \"daytime_chat_kwargs\": {\n            \"n_turns_per_day\": 2,\n            \"select_speaker\": \"round_robin\"\n        },\n        \"nighttime_chat_kwargs\": {\n            \"n_turns_per_day\": 2,\n            \"select_speaker\": \"random\"\n        }\n    }\n}\n```\n\n\n\n```json\n{\n    \"general\": {\n        \"n_players\": 5,\n        \"n_players_by_role\": {\n            \"werewolf\": 2,\n            \"fortuneteller\": 1,\n            \"knight\": 2\n        },\n        \"system_output_interface\": \"none\"\n    },\n    \"game\": {\n        \"daytime_chat_kwargs\": {\n            \"n_turns_per_day\": 2,\n            \"select_speaker\": \"round_robin\"\n        },\n        \"nighttime_chat_kwargs\": {\n            \"n_turns_per_day\": 2,\n            \"select_speaker\": \"random\"\n        }\n    },\n    \"players\": [\n        {\n            \"name\": \"Me\",\n            \"player_input_interface\": \"click\",\n            \"player_output_interface\": \"click\",\n            \"language\": \"Japanese\"\n        }\n    ]\n}\n```\n\n\n\nThen, the configuration file can be specified by `-c` or `--config` option.\n\nSee [config.py](https://github.com/hmasdev/langchain_werewolf/blob/main/langchain_werewolf/models/config.py) for more details like the schema of the configuration json file.\n\n### Game Structure\n\n\u003cimg src=\"pics/langchain_werewolf_game_graph_simple.png\" width=\"50%\"\u003e\n\nYou can see a more detailed grpah in [.pics/langchain_werewolf_game_graph.png](./pics/langchain_werewolf_game_graph.png).\n\n\u003cdetails\u003e\n\n\u003csummary\u003eHow to Generate the Drawing of the Graphs\u003c/summary\u003e\n\n```python\nPython 3.10.11 (main, Sep 20 2024, 18:41:54) [GCC 11.4.0] on linux\nType \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n\u003e\u003e\u003e from dotenv import load_dotenv\n\u003e\u003e\u003e load_dotenv()\nTrue\n\u003e\u003e\u003e from langchain_werewolf.game.main import create_game_graph\n\u003e\u003e\u003e from langchain_werewolf.main import DEFAULT_CONFIG\n\u003e\u003e\u003e from langchain_werewolf.setup import generate_players\n\u003e\u003e\u003e players = generate_players(DEFAULT_CONFIG.general.n_players, DEFAULT_CONFIG.general.n_werewolves, DEFAULT_CONFIG.general.n_knights, DEFAULT_CONFIG.general.n_fortune_tellers, seed=DEFAULT_CONFIG.general.seed, custom_players=DEFAULT_CONFIG.players)\n\u003e\u003e\u003e graph = create_game_graph(players)\n\u003e\u003e\u003e graph.get_graph(xray=False).draw_png('pics/langchain_werewolf_game_graph_simple.png')\n\u003e\u003e\u003e graph.get_graph(xray=True).draw_png('pics/langchain_werewolf_game_graph.png')\n```\n\n\u003c/details\u003e\n\n### How to add your custom roles\n\nIn `langchain_werewolf`, you can add your custom roles by creating a new class with a decorator.\n\nThis section walks you through creating and registering a new role in **langchain_werewolf**.  \nFollow the checklist first, then consult the detailed steps and code samples.\n\n#### ✅ Quick Checklist\n\n1. [ ] **Subclass**\n   - `BaseGamePlayerRole`\n   - One *Side* mixin: `VillagerSideMixin`, `WerewolfSideMixin`, **or** your own subclass of `BasePlayerSideMixin`\n\n2. [ ] **Mandatory class attributes**\n   ```python\n   role: ClassVar[str] = \"YourCustomRole\"\n   night_action: ClassVar[str] = \"YourCustomRole Night Action Description Here\"\n   ```\n\n   If you want to implement a custom night action, override `act_in_night` method.\n\n3. [ ] **Registration**\n\n   * Add `@PlayerRoleRegistry.register` above your class.\n   * Import the module in `langchain_werewolf/game_players/player_roles/__init__.py`\n\n     ```python\n     from .your_custom_role import YourCustomRole        # add this line\n     ```\n\n#### Step-by-step guide\n\n1. Create a new module in `langchain_werewolf/game_players/player_roles/` directory, e.g. `your_custom_role.py`.\n2. Implement your custom role class in the module. The class must inherits from the above 2 classes and have `role` and `night_action` attributes as `ClassVar[str]`. You can implement your own night action method by overriding `act_in_night` method.\n\n   Here are existing role classes in \"langchain_werewolf/game_players/player_roles\" for example, one is without `act_in_night` and the other is with `act_in_night` method overridden.\n\n   \u003cdetails\u003e \u003csummary\u003e Villager Implementation \u003c/summary\u003e\n\n   ```python\n   from typing import ClassVar\n    \n    from ..base import BaseGamePlayerRole\n    from ..player_sides import VillagerSideMixin\n    from ..registry import PlayerRoleRegistry\n    \n    \n    @PlayerRoleRegistry.register\n    class Villager(BaseGamePlayerRole, VillagerSideMixin):\n    \n        role: ClassVar[str] = 'villager'\n        night_action: ClassVar[str] = 'No night action'\n    \n   ```\n\n   \u003c/details\u003e\n\n   \u003cdetails\u003e \u003csummary\u003e FortuneTeller Implementation \u003c/summary\u003e\n\n   ```python\n   import json\n    from typing import ClassVar, Iterable\n    from langchain_core.exceptions import OutputParserException\n    from pydantic import Field\n    from ..base import BaseGamePlayer, BaseGamePlayerRole\n    from ..player_sides import VillagerSideMixin\n    from ..registry import PlayerRoleRegistry\n    from ..utils import is_werewolf_role\n    from ...const import GAME_MASTER_NAME\n    from ...llm_utils import extract_name\n    from ...models.state import (\n        MsgModel,\n        StateModel,\n        create_dict_to_record_chat,\n    )\n    from ..utils import find_player_by_name\n    \n    \n    @PlayerRoleRegistry.register\n    class FortuneTeller(BaseGamePlayerRole, VillagerSideMixin):\n    \n        role: ClassVar[str] = 'fortuneteller'\n        night_action: ClassVar[str] = 'Check whether a player is a werewolf or not'  # noqa\n    \n        question_to_decide_night_action: str = Field(\n            default='Who do you want to check whether he/she is a werewolf or not?',  # noqa\n            title=\"the question to decide the night action of the player\",\n        )\n    \n        def act_in_night(\n            self,\n            players: Iterable[BaseGamePlayer],\n            messages: Iterable[MsgModel],\n            state: StateModel,\n        ) -\u003e dict[str, object]:\n            target_player_name_raw = self.generate_message(\n                prompt=self.question_to_decide_night_action,\n                system_prompt=json.dumps([m.model_dump() for m in messages]),\n            )\n            try:\n                target_player_name = extract_name(\n                    target_player_name_raw.message,\n                    [p.name for p in players if p.name in state.alive_players_names],  # noqa\n                    context=f'Extract the valid name of the player as the answer to \"{self.question_to_decide_night_action}\"',  # noqa\n                    chat_model=self.runnable,\n                )\n            except OutputParserException:\n                return create_dict_to_record_chat(  # type: ignore # noqa\n                    self.name,\n                    [GAME_MASTER_NAME],\n                    'Failed to decide the target player.',\n                )\n            try:\n                target_player = find_player_by_name(target_player_name, players)\n                return create_dict_to_record_chat(  # type: ignore # noqa\n                    self.name,\n                    [GAME_MASTER_NAME],\n                    f'{target_player.name} is a werewolf'\n                    if is_werewolf_role(target_player)\n                    else f'{target_player.name} is not a werewolf'\n                )\n            except ValueError:\n                return create_dict_to_record_chat(  # type: ignore # noqa\n                    self.name,\n                    [GAME_MASTER_NAME],\n                    f'Failed to find the target player: {target_player_name}'\n                )\n    \n   ```\n\n   \u003c/details\u003e\n\n3. Finally, add the module name into `langchain_werewolf/game_players/player_roles/__init__.py` file.\n\n   ```python\n   from .fortune_teller import FortuneTeller\n   from .knight import Knight\n   from .villager import Villager\n   from .werewolf import Werewolf\n   from .your_custom_role import YourCustomRole\n\n   __all__ = [\n      FortuneTeller.__name__,\n      Knight.__name__,\n      Villager.__name__,\n      Werewolf.__name__,\n   ]\n   ```\n\n4. Test your custom role applied to the game by check the CLI help message.\n\n   ```bash\n   python -m langchain_werewolf --help\n   ```\n\n## Examples\n\nTBD\n\n## Contribution\n\n### How to Develop\n\n1. Fork the repository: [https://github.com/hmasdev/langchain_werewolf](https://github.com/hmasdev/langchain_werewolf)\n\n2. Clone the repository\n\n   ```bash\n   git clone https://github.com/{YOURE_NAME}/langchain_werewolf\n   cd langchain_werewolf\n   ```\n\n3. Create a virtual environment and install the required packages\n\n   ```bash\n   python -m venv venv\n   source venv/bin/activate\n   python -m pip install -e .[dev]\n   ```\n\n   or\n\n   ```bash\n   uv sync --extra dev\n   ```\n\n   if you uses `uv`.\n\n4. Checkout your working branch\n\n   ```bash\n   git checkout -b your-working-branch\n   ```\n\n5. Make your changes\n\n6. Test your changes\n\n   ```bash\n   pytest\n   flake8 langchain_werewolf tests\n   mypy langchain_werewolf tests\n   ```\n\n   or\n\n   ```bash\n   uv run pytest\n   uv run flake8 langchain_werewolf tests\n   uv run mypy langchain_werewolf tests\n   ```\n\n   Note that the above commands run only unit tests.\n   It is recommended to run integration tests with `uv run pytest -m integration`.\n\n7. Commit your changes\n\n   ```bash\n   git add .\n   git commit -m \"Your commit message\"\n   ```\n\n8. Push your changes\n\n   ```bash\n   git push origin your-working-branch\n   ```\n\n9. Create a pull request: [https://github.com/hmasdev/langchain_werewolf/compare](https://github.com/hmasdev/langchain_werewolf/compare)\n\n## LICENSE\n\n[MIT](https://github.com/hmasdev/langchain_werewolf/tree/main/LICENSE)\n\n## Authors\n\n- [hmasdev](https://github.com/hmasdev)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhmasdev%2Flangchain_werewolf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhmasdev%2Flangchain_werewolf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhmasdev%2Flangchain_werewolf/lists"}