Assistente pessoal orientado a ferramentas, com API FastAPI e CLI, integrado a Google Workspace (Gmail + Calendar), Spotify, memória opt-in, auditoria e fluxo de confirmações para ações sensíveis.
O NICKEL foi projetado para separar planejamento e execução de ações:
- Planeja com LLM (
/chat/plan) - Executa ação explicitamente (
/chat/execute) ou via fluxo compatível (/chat) - Exige confirmação para operações de escrita críticas (
/confirme/cancel)
- Google Workspace
- Gmail: pesquisa, leitura, rascunho e envio
- Calendar: listagem, criação e alteração de eventos
- Spotify
- Play, pause e skip
- OAuth dedicado do Spotify + fallback por token manual
- Memória opt-in (
/memory/ask,/memory/confirm,GET /memory) - Auditoria (
GET /audit) - Persistência local de tokens, ações pendentes, notas, tarefas, memória e trilha de auditoria
- Python 3.11+
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtImportante: nunca commite credenciais reais. Use valores de exemplo no
.enve segredos reais apenas no ambiente de execução.
# Google OAuth
export GOOGLE_CLIENT_ID="your_google_client_id"
export GOOGLE_CLIENT_SECRET="your_google_client_secret"
export GOOGLE_REDIRECT_URI="http://localhost:8000/auth/google/callback"
export GOOGLE_SCOPES="https://www.googleapis.com/auth/gmail.readonly,https://www.googleapis.com/auth/gmail.compose,https://www.googleapis.com/auth/gmail.send,https://www.googleapis.com/auth/calendar.readonly,https://www.googleapis.com/auth/calendar.events"
# Chave para criptografia de tokens OAuth no armazenamento local
export OAUTH_TOKEN_KEY="your_fernet_key"
# LLM provider
export LLM_BASE_URL="https://api.groq.com/openai/v1"
export LLM_API_KEY="your_llm_api_key"
export LLM_MODEL="llama-3.1-8b-instant"
export LLM_TIMEOUT_SECONDS="60"
# Persistência local
export TOKEN_STORE_PATH="./data/token_store.json"
export PENDING_ACTIONS_PATH="./data/pending_actions.json"
export NOTES_STORE_PATH="./data/notes.json"
export TASKS_STORE_PATH="./data/tasks.json"
export MEMORY_STORE_PATH="./data/memory.json"
export AUDIT_STORE_PATH="./data/audit.json"
# Spotify OAuth
export SPOTIFY_CLIENT_ID="your_spotify_client_id"
export SPOTIFY_CLIENT_SECRET="your_spotify_client_secret"
export SPOTIFY_REDIRECT_URI="http://localhost:8000/auth/spotify/callback"
export SPOTIFY_SCOPES="user-read-playback-state,user-modify-playback-state,user-read-currently-playing"
# Spotify opcional (modo manual/fallback)
export SPOTIFY_ACCESS_TOKEN="optional_spotify_access_token"
export SPOTIFY_DEVICE_ID="optional_device_id"
export SPOTIFY_BASE_URL="https://api.spotify.com/v1"python - <<'PY'
from cryptography.fernet import Fernet
print(Fernet.generate_key().decode("utf-8"))
PYmake startexport NICKEL_API_BASE_URL="http://localhost:8000"
python -m cli.mainA CLI mantém histórico local para conversas multi-turno e suporta confirmações com /confirm e /cancel.
- Inicie o fluxo em
/auth/google/start. - Complete o fluxo em
/auth/google/callback?code=...&state=....
- Liste eventos em
/tools/calendar/list_events.
- Pesquise emails em
/tools/email/search. - Leia emails em
/tools/email/read.
- Crie rascunho em
/tools/email/draft(sem confirmação). - Envie email em
/tools/email/send(com confirmação).
- Compatibilidade: continue usando
POST /chatcom{ "message": "..." }. - Novo planejamento:
POST /chat/planretorna plano estruturado comresponse,action,confidence,requires_confirmatione não executa tool. - Nova execução:
POST /chat/executeexecuta uma ação já planejada (ou responde normalmente quandoactionénull). - Fluxo unificado: internamente,
/chatusaplan -> execute. - Para manter contexto entre turnos, envie também
history, por exemplo{ "message": "...", "history": [{"role":"user","content":"..."},{"role":"assistant","content":"..."}] }. - Benefícios do split plan/execute: depuração mais simples, UI mais previsível e menor acoplamento com o provider de LLM.
make api # API em http://localhost:8000
make cli # CLI conectada à API- Iniciar:
GET /auth/google/start - Callback:
GET /auth/google/callback?code=...&state=...
- Iniciar:
GET /auth/spotify/start - Callback:
GET /auth/spotify/callback?code=...&state=... - Alternativa: usar
SPOTIFY_ACCESS_TOKENmanualmente
POST /tools/calendar/list_eventsPOST /tools/calendar/create_event(requer confirmação)POST /tools/calendar/modify_event(requer confirmação)
POST /tools/email/searchPOST /tools/email/readPOST /tools/email/draftPOST /tools/email/send(requer confirmação)
POST /tools/spotify/playPOST /tools/spotify/pausePOST /tools/spotify/skip
POST /tools/notes/create(requer confirmação)POST /tools/tasks/create(requer confirmação)POST /tools/tasks/list
- Compatível:
POST /chat - Planejamento sem execução:
POST /chat/plan - Execução explícita:
POST /chat/execute - Suporte a histórico via
historyno payload
Ações de escrita sensíveis não executam imediatamente:
- API cria
pending_action - Cliente confirma via
POST /confirmcomaction_ideconfirmed: true - Ou cancela via
POST /cancel
- Memória opt-in:
/memory/ask,/memory/confirm,GET /memory - Auditoria:
GET /audit
pytestEste README descreve o NICKEL v1.0.