grok-bot 9916940f5a
CI / lint + typecheck + test (push) Has been cancelled
quality: P1–P3 Coverage, Sanitize, DX und Doku
Coverage-Hotspots (providers 100 %, chat-Pfade), Key-Sanitize in Commands/CLI,
Test-Buffer (-b), mypy-Overrides, CONTRIBUTING/SECURITY, .env.example und
gitignore-Verfeinerung. CI-Safety prüft lokale .env nur wenn getrackt.
2026-08-04 12:31:34 +02:00

🤖 chatpy

Interaktiver CLI-Chat für OpenRouter, Groq, NVIDIA NIM und lokale OpenAI-kompatible Server (Ollama, LM Studio, vLLM) – OpenAI-kompatibel.

Version: 2.1.0 · Changelog

Dokumentation

Dokument Inhalt
docs/ Index & Lesepfade
Getting Started Tutorial (~10–15 Min): Setup → erster Chat
Changelog Versionshistorie
User-Guide Setup, CLI, Slash-Commands, Workflows
Architektur Module, Flows, Free-Tier-Schutz
Konfiguration ENV, .runtime/, Settings
Entwicklung Tests, Coverage, Konventionen
CONTRIBUTING Mitwirken, PR-Checkliste
SECURITY Keys, Sanitize, Meldungen

Schnellstart

Ausführliches Tutorial: docs/getting-started.md.

# 1. .env mit mindestens einem API-Key (oder Local-URL) anlegen
echo 'OPENROUTER_API_KEY=sk-or-...' > .env
echo 'GROQ_API_KEY=gsk_...' >> .env
echo 'NVIDIA_API_KEY=nvapi-...' >> .env
# optional lokal: OPENAI_COMPAT_BASE_URL=http://127.0.0.1:11434/v1

# 2. Umgebung (empfohlen: mise – siehe mise.toml)
mise trust                 # einmalig, falls Trust-Prompt
mise install               # Python 3.12
mise run install           # pip install -e . → .venv

# 3. Starten
mise run chat
# oder: python -m chatpy
# oder: .venv/bin/python chat.py   (Root-Launcher)

Ohne mise:

python3 -m venv .venv
.venv/bin/pip install -e .
python -m chatpy

CLI-Argumente

Nicht-interaktive Nutzung – alle interaktiven Prompts werden übersprungen:

# Einfache Frage
python -m chatpy --provider groq --no-stream "Was ist Python?"

# Pipe-Eingabe
echo "Erkläre Quantencomputing" | python -m chatpy --provider nvidia

# Code-Modus mit Temperatur
python -m chatpy --code --temp 0.3 --language de "Schreibe Hello World in Rust"
Argument Beschreibung
--provider {openrouter,groq,nvidia,local} Provider ohne Auswahl-Menü setzen
--model MODEL Modell per ID oder Name (z. B. llama-3.1-8b-instant)
--temperature FLOAT, --temp FLOAT Temperatur (wird auf 0.0–2.0 begrenzt)
--stream / --no-stream Streaming an/aus
--language {de,en}, --lang {de,en} Sprache für System-Prompts
--code Code-Modus aktivieren
--reasoning Gedankengänge des Modells sichtbar machen
--system-prompt TEXT Benutzerdefinierter System-Prompt
--system-prompt-file PATH System-Prompt aus Datei
--session NAME Session beim Start laden
--file / -f PATH|URL Datei oder URL als Kontext (mehrfach)
--json Antwort als JSON
--quiet / -q Weniger Banner
--list-models Modelle anzeigen und beenden
--help Hilfe anzeigen
--version Version anzeigen
MESSAGE Einmalige Nachricht (nicht-interaktiv, als letztes Argument)

Exit-Codes (Pipe/Einmal): 0 OK, 1 Key/Config, 2 API-Fehler.

Interaktive Befehle

Im interaktiven Chat (ohne einmalige Message bzw. Pipe) stehen folgende Befehle zur Verfügung (--provider/--model überspringen nur die Auswahlmenüs):

Befehl Beschreibung
/provider Provider wechseln
/model Modell wechseln
/temp 0.7 Temperatur setzen (0.0–2.0)
/language de|en Sprache umschalten
/stream on|off Streaming ein/aus
/reasoning on|off Gedankengänge anzeigen/verbergen
/code on|off Code-Modus ein/aus
/system [prompt] System-Prompt setzen (ohne Argument = Default)
/prompt save <name> Aktuellen Prompt als Template speichern
/prompt load <name> Template laden und aktivieren
/prompt list Alle gespeicherten Templates anzeigen
/prompt delete <name> Template löschen
/context [n] Kontext anzeigen; optional Fenster (1–50) setzen
/context tokens N Token-Budget Kontext (0 = aus)
/maxtokens N max_tokens pro Request
/model [suche] Modell + optionaler Filter
/retry Letzte User-Nachricht erneut senden
/undo Letzten Austausch entfernen
/last Letzte Assistant-Antwort anzeigen
/sessions Gespeicherte Sessions listen
/session show|delete <name> Session-Metadaten / löschen
/theme dark|light|none Terminal-Theme
/clear Terminal leeren
/reset Chat-Verlauf löschen
/export [name] Als Markdown exportieren
/export json [name] Als JSON exportieren
/file <pfad> / /web <url> Anhang für nächste Nachricht
/attach / /attach clear Anhang-Buffer listen / leeren
/save [name] Session speichern (ohne Name → Zeitstempel)
/load [name] Session laden (Nachrichten + Settings)
/stats Statistiken anzeigen
/gen API-Modell & Generation-ID der letzten Antwort
/reload Modell-Listen neu laden
/help Hilfe anzeigen
/exit, /quit Beenden

Mehrzeilig: mit """ … """. Optional: readline-History (Pfeil-hoch) und Tab-Complete für Slash-Commands.
Inline-Datei: @./pfad.py · CLI: -f PATH|URL (mehrfach).

Provider

Provider Modell-Liste Limit (Free-Tier)
OpenRouter Dynamisch (nur :free-Modelle, Preis 0) 20 RPM / 50–1000 RPD
Groq Dynamisch 30 RPM / ~14k RPD
NVIDIA NIM Dynamisch 1000 Requests/Tag

OpenRouter – garantiert kostenlos

OpenRouter kann Modellpreise ändern oder auf andere Endpoints ausweichen. Deshalb:

  • Kein Cache: Free-Modell-Liste wird bei jedem Start frisch von der API geladen (Preisänderungen rutschen nie durch).
  • openrouter/free-Router deaktiviert: Es werden ausschließlich explizite :free-Modelle verwendet.
  • max_price: 0: Jeder OpenRouter-Request sendet provider.max_price mit 0 ($/Mio Tokens). OpenRouter lehnt den Request ab, sobald kein 0-Preis-Endpoint verfügbar ist – eine Abrechnung ist damit technisch unmöglich (Default: OPENROUTER_MAX_PRICE=0).
  • Kosten-Guard: Nicht-:free-Modelle werden in chat() blockiert, bevor ein API-Call passiert.
  • Kosten-Audit: usage.cost aus jeder Antwort wird protokolliert; Abweichungen > 0 lösen eine Warnung aus und tauchen in /stats und chat_history.json auf.

Empfehlung gegen unerklärte Restbeträge (z. B. Fallback/Testing anderer Tools): API-Key rotieren und unter https://openrouter.ai/settings/credits eine Spend Control / Kreditlimit setzen.

Konfiguration

.env

OPENROUTER_API_KEY=sk-or-...
GROQ_API_KEY=gsk_...
NVIDIA_API_KEY=nvapi-...
MAX_TOKENS=2048
DEFAULT_TEMPERATURE=0.7
DEFAULT_STREAM=true
DEFAULT_LANGUAGE=de
DEFAULT_PROVIDER=openrouter

Theme

Das Theme wird in chat_settings.json gesetzt. Verfügbare Werte:

  • dark – Dunkles Terminal-Theme (Standard)
  • light – Helles Terminal-Theme
  • none – Keine Farben (für einfache Terminals)
{
  "theme": "dark",
  "temperature": 0.7,
  "...": "..."
}

Prompt-Templates

Templates sind benannte, persistente System-Prompts. Sie werden in chat_settings.json gespeichert.

# Aktuellen Prompt speichern
/system Du bist ein Python-Experte. Antworte mit Code.
/prompt save python-dev

# Später laden
/prompt load python-dev

# Alle Templates anzeigen
/prompt list

# Löschen
/prompt delete python-dev

Templates und /system-Prompts nutzen dieselbe Variable – ein mit /prompt load geladener Prompt überschreibt den aktuellen /system-Prompt und umgekehrt.

Dateien

Pfad Zweck
chatpy/ Installierbares Package (Module, Fallback-JSON)
chat.py Dünner Root-Launcher
pyproject.toml Package + Console-Script chatpy
mise.toml mise: Python 3.12, .venv, Tasks
.runtime/ Laufzeit-JSONs (Settings, History, Caches; gitignored)
tests/ Unittest-Suite (~456 Tests; Live unter tests/live/)
requirements.txt Runtime-Deps (Spiegel von pyproject.toml)

Setup

# mise (empfohlen)
mise trust && mise install && mise run install

# ohne mise
python3 -m venv .venv
.venv/bin/pip install -e .

Laufzeitdaten landen unter .runtime/ (Override: CHATPY_DATA_DIR).

Tests

# Alle Tests
mise run test
# oder
make test

# Einzelne Test-Datei
.venv/bin/python -m unittest tests.test_client

# Mit Detail-Ausgabe
.venv/bin/python -m unittest discover -s tests -v

# Live-Tests (echte Keys, Free-Tier; unter tests/live/)
RUN_LIVE_TESTS=1 .venv/bin/python -m unittest discover -s tests/live -v

Coverage (Test-Metriken)

Zeilen- und Branch-Abdeckung pro Modul (chatpy/*). coverage.py ist eine optionale Dev-Abhängigkeit (nicht in den Runtime-Deps).

# einmalig Dev-Tools installieren
mise run install-dev

# Terminal-Report (Stmts / Miss / Branch / Cover / Missing)
mise run test-cov
# oder
make test-cov

# zusätzlich HTML unter htmlcov/index.html
mise run test-cov-html
S
Description
No description provided
Readme
1.5 MiB
0 Stars 1 Watchers 0 Forks
Languages
Python 99.7%
Makefile 0.3%