focus_buddy / CONTRIBUTING.md
idormoy's picture
Local backends never route nudges to a paid API; plain hyphens
ff78bf9 verified
|
Raw
History Blame Contribute Delete
2.8 kB

Contributing to Focus Buddy

Thanks for taking a look. Issues and pull requests are both welcome.

Getting set up

git clone https://github.com/dormoyi/focus_buddy
cd focus_buddy
python -m venv .venv && source .venv/bin/activate
pip install -e . --group dev
cp .env.example .env      # add your OPENAI_API_KEY

Check that everything works:

pytest                          # no network, camera or models needed
ruff check . && ruff format --check .
mypy src/

Running it

focus-buddy --desktop --debug   # laptop webcam, short intervals
focus-buddy                     # connect to a Reachy Mini

--debug shortens the nudge cooldown to 15 seconds and the summary interval to three minutes, which makes a full demo take a minute rather than an hour.

The shape of the code

The loop is one tick: grab a frame, classify it into an Observation, record it, and sometimes speak. Four things are pluggable, each behind a Protocol with a small factory that reads Settings:

Thing Protocol Factory
Vision perception.base.VisionBackend perception.build_vision_backend
Nudge phrasing brain.base.NudgeWriter brain.build_nudge_writer
Speech speech.base.SpeechBackend speech.build_speech_backend
Camera + speaker hardware.base.Body constructed in main

Adding a backend means adding a file and one branch in the relevant factory. It should not mean touching loop.py.

Two conventions worth respecting:

  • Import heavy dependencies inside functions. The robot dashboard imports main.py just to list installed apps; it should not pull in OpenCV or a model as a side effect.
  • Never read the environment at import time. Configuration is resolved once, into Settings, and passed down. This is what keeps the tests hermetic.

Tests

tests/conftest.py has fakes for every collaborator, so the whole loop can run without a camera, a robot, a model or a network. New behaviour in loop.py should be testable there.

tests/test_captions.py is a regression suite: every case is something a real vision model actually said. If you tune a pattern in perception/captions.py, run it - those tests are the only thing that catches a change that silently breaks detection for a phrasing you were not thinking about. When you fix a new misclassification, add the caption that caused it.

Pull requests

  • Keep ruff, mypy and pytest green.
  • One concern per PR.
  • If you change what the buddy says or when it says it, say so in the description - that is the part users actually experience.

Code of conduct

Be decent to each other. Harassment or personal attacks are not welcome here, and maintainers will remove contributions and contributors that involve them.