What's Happening
CI (.github/workflows/ci.yml) runs flake8 main.py --max-line-length=120 --ignore=E501,W503 plus python -m py_compile main.py — and that's the entire quality gate. Ignoring E501 and setting max-line-length makes the length rule self-contradictory, flake8 does no import sorting or modernization checks, there is no formatter, and there is no type checking at all — even though CONTRIBUTING.md ("Coding Standards", Python Style item 2) explicitly requires type hints for parameters and return values.
The code shows it: active_chats = {} (main.py, line 48) is untyped, get_safety_settings() (line 81) has no return annotation, the route handlers' odd formatting around /ping (lines 103-104: doubled spaces, single-space indent, trailing semicolon) sails through the current lint config, and history-building (lines 148-162) relies on hasattr duck-typing that mypy would force to be explicit. As Wave contributors add code, there's no tooling holding the standard CONTRIBUTING.md promises.
Where to Find This
.github/workflows/ci.yml — lint job (lines 30-34)
main.py — the only source file; annotations and formatting issues throughout
- New:
pyproject.toml for tool configuration
- CONTRIBUTING.md — "Coding Standards" section to update with the actual commands
What We Want
- Adopt ruff for linting and formatting, replacing flake8: a
pyproject.toml with a curated rule set (at least E, F, I for import sorting, UP for modernization, B for bugbear), line length 120 to match current convention
- Run
ruff format and fix all ruff check findings across the repo (excluding venv/)
- Adopt mypy with a reasonably strict config (
disallow_untyped_defs = true for main.py) and add the missing annotations: active_chats: dict[str, ...], return types on all functions/handlers, typed safety-settings return
- Update CI: replace the flake8 step with
ruff check + ruff format --check + mypy, pinning tool versions so CI is reproducible
- Update CONTRIBUTING.md's coding-standards section with the exact commands contributors run locally (
ruff check ., ruff format ., mypy .)
- Optional but welcome: a
pre-commit config wiring the same tools
Technical Context
google-generativeai ships incomplete type stubs — expect to need ignore_missing_imports (scoped via [[tool.mypy.overrides]] to the google.* modules, not globally) rather than fighting it
- Behavior-preserving PR: formatting and annotations only; if ruff/mypy expose a genuine bug (they will point at the
/ping set literal and the line-129 tuple, both already tracked in another issue), don't fix it here — note it and stay out of that issue's way
- CI runs Python 3.11 (
ci.yml, line 21); use 3.11-compatible syntax for annotations
- Keep the tool config in
pyproject.toml (single file), not separate .flake8/mypy.ini fragments
Acceptance Criteria
- CI runs ruff (lint + format check) and mypy with pinned versions and passes on the PR
mypy passes with untyped defs disallowed for main.py; every function has parameter and return annotations
- flake8 is fully removed from the workflow
- CONTRIBUTING.md documents the local commands
- No runtime behavior change (endpoints respond identically before/after)
What's Happening
CI (
.github/workflows/ci.yml) runsflake8 main.py --max-line-length=120 --ignore=E501,W503pluspython -m py_compile main.py— and that's the entire quality gate. Ignoring E501 and setting max-line-length makes the length rule self-contradictory, flake8 does no import sorting or modernization checks, there is no formatter, and there is no type checking at all — even though CONTRIBUTING.md ("Coding Standards", Python Style item 2) explicitly requires type hints for parameters and return values.The code shows it:
active_chats = {}(main.py, line 48) is untyped,get_safety_settings()(line 81) has no return annotation, the route handlers' odd formatting around/ping(lines 103-104: doubled spaces, single-space indent, trailing semicolon) sails through the current lint config, and history-building (lines 148-162) relies onhasattrduck-typing that mypy would force to be explicit. As Wave contributors add code, there's no tooling holding the standard CONTRIBUTING.md promises.Where to Find This
.github/workflows/ci.yml— lint job (lines 30-34)main.py— the only source file; annotations and formatting issues throughoutpyproject.tomlfor tool configurationWhat We Want
pyproject.tomlwith a curated rule set (at leastE,F,Ifor import sorting,UPfor modernization,Bfor bugbear), line length 120 to match current conventionruff formatand fix allruff checkfindings across the repo (excludingvenv/)disallow_untyped_defs = trueformain.py) and add the missing annotations:active_chats: dict[str, ...], return types on all functions/handlers, typed safety-settings returnruff check+ruff format --check+mypy, pinning tool versions so CI is reproducibleruff check .,ruff format .,mypy .)pre-commitconfig wiring the same toolsTechnical Context
google-generativeaiships incomplete type stubs — expect to needignore_missing_imports(scoped via[[tool.mypy.overrides]]to thegoogle.*modules, not globally) rather than fighting it/pingset literal and the line-129 tuple, both already tracked in another issue), don't fix it here — note it and stay out of that issue's wayci.yml, line 21); use 3.11-compatible syntax for annotationspyproject.toml(single file), not separate.flake8/mypy.inifragmentsAcceptance Criteria
mypypasses with untyped defs disallowed formain.py; every function has parameter and return annotations