Imported from axtrace/alisa_chess (
AGENTS.md). Install upstream withnpx skills add axtrace/alisa_chess. Copyright stays with the author.
AGENTS.md
Instructions for LLM agents (Codex, Cursor, Cline, Continue, Claude Code, etc.) working with the alisa_chess repository. The goal of this document is to set common rules of the game, list project invariants, and help the agent get into the current context without lengthy exploration.
Note: The project's
README.mdis written in Russian. Keep it in Russian when updating.
1. About the project in one paragraph
alisa_chess is a voice chess skill for Yandex Alice. It is deployed as a Yandex Cloud Function (alice_serverless.handler). Engine moves are computed by a local Stockfish binary launched via UCI using python-chess. Game state is passed between requests via state.user.game_state (the schema is described in game_state.py).
2. Strict invariants (do NOT violate without explicit discussion)
These are contracts that must NOT be broken. If it seems a task requires breaking one — ask first.
- Stockfish is initialized lazily (
Game.engine). Do not callpopen_uciin__init__without considering serverless cold start. engine.quit()is mandatory. The current solution isGame.__exit__andwith AliceChess() as aliceinalice_serverless.handler. Any code path that opens the engine must guarantee it is closed.- Idempotency by
message_id. A repeated request with the samemessage_idmust returnprevious_responsefromsession_statewithout a second engine move. YANDEX.REPEATlives insession_state.previous_response, not inuser_state_update.user_state_updateis ALWAYS saved, including in the catch-all. Never return a response withoutuser_state_updatewhen state exists — this would lose the player's game.- The session is NOT closed on a handler error.
end_session: True— only in the catastrophic catch inalice_serverlessand onGAME_OVER. - State serialization is via Pydantic (
GameStateV2) with versioning (_version) and graceful V1→V2 migration. SkillStateis an enum (skill_state.py). When comparing states, preferSkillState.WAITING_MOVEover the string'WAITING_MOVE'(migration in progress — task №11).- Tests must stay green. Currently 69/69 passed. Any change that breaks tests requires updating the tests in the same PR with an explanation of why the assertion is outdated.
- The Stockfish binary is NOT committed, it is added separately. Do not touch any mentions of it in
.gitignorewithout coordination.
3. Architecture and where things are
| Layer | Files | Purpose |
|---|---|---|
| Entry point (Cloud Function) | alice_serverless.py |
handler(event, context), catch-all, response building |
| Coordinator | alice_chess.py |
AliceChess, routing by SkillState, idempotency, session_state |
| Game model | game.py |
Game: chess.Board wrapper + UCI, lazy engine |
| State | game_state.py |
Pydantic schemas V1/V2, migrations, (de)serialize |
| State enum | skill_state.py |
SkillState |
| Handlers | handlers/ |
One file per state, inherit BaseHandler |
| Move parser | move_extractor.py |
Extracts a move from intents and text (RU/EN, SAN, long notation) |
| Texts/TTS | text_preparer.py, speaker.py, texts.py |
Building the response text/tts |
| Validators | request_validators/ |
Intent validation |
| Alice intents | intents/*.yaml |
NLU description |
| Tests | tests/ |
pytest/unittest |
| Documentation | docs/ |
Architecture, deployment, diagrams |
State diagram: docs/diagrams/state_diagram.md.
Request processing sequence diagram: docs/diagrams/sd_request_processing.md.
4. Commands for the agent
Running tests
python3 -m pytest tests/ -v
The minimum requirement before a commit is all tests green. Do not push red tests.
A single file / single test
python3 -m pytest tests/test_alice_chess.py::TestAliceChess::test_handle_request_promotion -v
Lint / formatting
ruff check . # style check
ruff format . # automatic formatting
mypy . # type checking (gradually adopted)
pre-commit run --all-files # run all pre-commit hooks
Configured as part of task №17: ruff (lint+format), mypy (gradual), pre-commit + CI check.
Local handler run
Place the Stockfish binary at the project root as ./stockfish and run chmod +x on it. Without it, engine initialization will fail on a real computer move.
5. Style and conventions
- Code language: Python 3.14+ (Yandex Cloud Functions runtime).
- Commas — a space after, operators (
=,==,>,<,||, etc.) — spaces around. - Names:
snake_casefor functions/files/variables,PascalCasefor classes,UPPER_SNAKEfor constants. - Logging — via
logging(a module-level logger), noprintin production code.printin tests is acceptable for debugging but should preferably be removed before merge. - Pydantic v2:
@field_validator+@classmethod,model_dump()instead of.dict(). - Markdown in YAML/docs — correct links and code blocks with a language specified.
Commit messages
- Version control system: git.
- Short description in Russian or English.
- One commit — one logical idea.
- PR size — up to ~650 lines of changes (
coding-standard.md).
6. Change strategy
Minimal invasiveness
Do not do extra refactoring unless the task requires it. Preserve the existing style and structure. If you see an improvement opportunity unrelated to the task — a separate PR.
Test-aware
Before changing logic, check which tests cover it:
grep -rn "<function_name>" tests/
If you change a class's public contract — update the tests in the same PR, explaining in the description why the assertion is outdated.
Fact-based
Do not assume the existence of files/functions that are not in the repository. Before using a function/method in new code — open the source and check the signature.
Alice contracts
Any response fields (response.text, response.tts, end_session, buttons) and state fields (game_state, session_state) are a contract with the platform. Before changing — check the official Alice docs and existing tests.
7. Common pitfalls
| Symptom | Cause | Solution |
|---|---|---|
A test with a Game mock tries to run the real Stockfish |
@patch('game.Game') does not patch the from game import Game import in alice_chess.py |
Use @patch('alice_chess.Game') |
An AliceChess mock does not work in the serverless test |
The code uses with AliceChess() as alice:, the actual object is __enter__() |
mock_instance.__enter__.return_value = mock_instance |
_find_matching_moves returns empty on a mock |
board.legal_moves on a MagicMock is an empty collection |
Replace game.board with a real chess.Board(fen) |
previous_response is lost between moves |
It is written to user_state_update instead of session_state |
Store it in session_state.previous_response |
| The game "forgets" the match after an error | user_state_update is not passed in the error response |
Snapshot the input state → the catastrophic catch returns it |
8. Roadmap
Future improvements may include:
- Expanding golden tests with more complex scenarios
- Adding engine performance metrics
- Supporting additional voice platforms
9. Checklist before completing a task
- Tests are green:
python3 -m pytest tests/ -v - If a public contract changed — tests updated + explanation in the PR description
- All invariants from section 2 are respected
- No
print()andsetLevel()in production code (unless a conscious decision within the task) -
requirements.txtis synchronized if dependencies were added/removed - Documentation (
README.md,docs/) is updated if API/behavior changes - The change fits into one logical idea (PR ≤ ~650 lines)
10. What NOT to do without an explicit request
- Change code formatting style.
- Rename public methods/classes.
- Delete "redundant" code from your point of view — it may be needed for compatibility with old state in production.
- Change the text format from
texts.py— this affects TTS and therefore the user experience. - Add new dependencies to
requirements.txtwithout discussion (serverless cold start). - Commit local configs:
.venv/,tokens.py,exp.py, thestockfishbinary. - Run
git pushwithout an explicit command from the owner.
11. Useful links
- Project README:
README.md - Architecture:
docs/architecture.md - Deployment:
docs/deployment.md - Skill API:
docs/api.md - Catalog skill description:
docs/skill_description.md - Diagrams:
docs/diagrams/ - Alice protocol: https://yandex.ru/dev/dialogs/alice/doc/protocol.html
- python-chess: https://python-chess.readthedocs.io/
If this document contradicts the code reality — the codebase is authoritative. After discovering a discrepancy, immediately update AGENTS.md in the same PR.