Peanut is a secure, lightweight AI personal assistant that reads Trello tasks, adds read-only Gmail context, asks Gemini for concise prioritization, remembers carry-over work, and sends a daily briefing to Telegram.
This repository is public. Do not commit secrets, OAuth tokens, local memory files, kubeconfigs, plaintext Kubernetes Secrets, or personally identifiable local paths.
flowchart TD
Cron[Cereal CronJob / Daily Schedule] --> Run[python -m app.run]
Telegram[Telegram update command] --> Webhook[FastAPI /webhook/telegram]
Webhook --> Pipeline[Peanut planning pipeline]
Run --> Pipeline
Pipeline --> Trello[Trello board tasks]
Pipeline --> Gmail[Gmail read-only context]
Pipeline --> Memory[(Persistent memory.json PVC)]
Pipeline --> Gemini[Gemini LLM]
Gemini --> Briefing[Prioritized daily briefing]
Briefing --> TelegramOut[Telegram message]
AppRepo[Peanut app repo] --> Actions[GitHub Actions]
Actions --> Image[Docker Hub hedche/peanut]
Nature[~/dv/Nature GitOps repo] --> Flux[Flux Kustomization]
Image --> Flux
Flux --> Cereal[Cereal Kubernetes cluster]
NatureSecrets[gitignored Nature secrets.yaml] --> SecretPush[scripts/secrets.sh push]
SecretPush --> CerealSecret[peanut-secrets in cluster]
CerealSecret --> Pipeline
- Python 3.12
- FastAPI + Uvicorn
- uv for dependency management
- Google Gemini Developer API via
google-genai - Trello REST API
- Gmail OAuth2 read-only context
- Telegram bot delivery and webhook command handling
- Docker multi-arch image publishing to
hedche/peanut - Flux GitOps deployment to the Cereal Kubernetes cluster
- Local credentials live in
.env.local; this file is gitignored. - Commit only
.env.exampleplaceholders. - GitHub Actions uses repository secrets for Docker Hub auth:
DOCKER_USERNAMEDOCKER_TOKEN
- Cereal Kubernetes credentials are managed from the Nature GitOps repo with:
- local path:
~/dv/Nature - local plaintext file:
~/dv/Nature/secrets.yaml(gitignored) - helper:
~/dv/Nature/scripts/secrets.sh
- local path:
- Never commit real
.envfiles, OAuth refresh tokens, API keys, kubeconfigs, local memory data, or plaintext Kubernetes Secret manifests.
Copy the local environment file from the reference app only after confirming
.gitignore is present:
cp /path/to/reference-assistant/.env.local .env.local
git status --short --ignored .env.localExpected: .env.local is shown as ignored, not untracked.
For new environments, start from:
cp .env.example .env.localRequired provider variables:
TRELLO_API_KEYTRELLO_API_TOKENTRELLO_BOARD_IDTRELLO_LIST_NAME(optional; exact list name to read, blank reads all lists)GOOGLE_API_KEYTELEGRAM_BOT_TOKENTELEGRAM_CHAT_ID
Optional Gmail context:
GMAIL_CLIENT_IDGMAIL_CLIENT_SECRETGMAIL_REFRESH_TOKENGMAIL_SENDER_EMAILS
uv sync
uv run uvicorn app.main:app --host 127.0.0.1 --port 8000 --reloadHealth and metrics:
curl -fsS http://127.0.0.1:8000/health
curl -fsS http://127.0.0.1:8000/metricsRun a one-shot briefing:
uv run python -m app.runNote: the one-shot command sends a real Telegram briefing when credentials are configured.
uv run pytestdocker build -t peanut:local .
docker run --rm --env-file .env.local -p 8000:8000 peanut:localGitHub Actions publishes multi-architecture images to:
hedche/peanut
The app repo owns application code, Docker build config, tests, and public docs. The Cereal cluster desired state lives in the Nature GitOps repo:
~/dv/Nature
Expected live manifest locations:
~/dv/Nature/kubernetes/peanut~/dv/Nature/kubernetes/flux/peanut.yaml~/dv/Nature/kubernetes/flux/kustomization.yaml
Create/update the peanut-secrets Kubernetes Secret through Nature’s secret
helper, not by committing plaintext Secret YAML.
GET /health— health checkGET /metrics— Prometheus-compatible LLM metricsGET /metrics/json— JSON metricsGET /report— generate and send today’s briefingPOST /webhook/telegram— handle Telegramupdatecommand