#!/bin/bash # 🐼 BashPanda - Der Kung Fu Meister des Terminals # Geduld, Präzision, und der Weg des Codes # Load .env if exists SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ENV_FILE="${SCRIPT_DIR}/../.env" if [[ -f "${ENV_FILE}" ]]; then set -a source "${ENV_FILE}" set +a fi QUESTION="$*" API_KEY="${OPENROUTER_API_KEY}" MODEL="${OPENROUTER_MODEL:-openai/gpt-3.5-turbo}" # Logs LOGDIR="${CRUMB_LOGS_DIR:-$HOME/.bashpanda_logs}/bashpanda" mkdir -p "$LOGDIR" HISTORY_FILE="$LOGDIR/bashpanda_history.json" TMP_REQUEST="$LOGDIR/bashpanda_request.json" TMP_RESPONSE="$LOGDIR/bashpanda_response.json" LOG_FILE="$LOGDIR/token_log.json" [ ! -f "$HISTORY_FILE" ] && echo "[]" > "$HISTORY_FILE" [ ! -f "$LOG_FILE" ] && echo "[]" > "$LOG_FILE" # === CREW MEMORY FUNCTIONS === function read_crew_memory() { local role="$1" local role_log="${CRUMB_LOGS_DIR}/${role}/${role}_history.json" # Fallback to old location if [[ ! -f "$role_log" ]]; then role_log="$HOME/.${role}_logs/${role}_history.json" fi if [[ -f "$role_log" ]]; then jq -r '.[-3:] | .[] | "[\(.role)]: \(.content)"' "$role_log" 2>/dev/null | head -n 3 fi } # === MAIN === echo "🐼 BashPanda betritt das Dojo..." echo "🥋 *verbeugung* 🥋" echo "" if [ -z "$API_KEY" ]; then echo "❗ Ohne Schlüssel öffnet sich keine Tür zum Wissen." echo " Erstelle eine .env Datei mit deinem OPENROUTER_API_KEY." exit 1 fi # Source waldwaechter library for token budget check if [[ -f "${SCRIPT_DIR}/../lib/waldwaechter.sh" ]]; then source "${SCRIPT_DIR}/../lib/waldwaechter.sh" fi # 💰 Prüfe Token-Budget (Kinderschutz) if ! check_token_budget "bashpanda"; then exit 1 fi if [ -z "$QUESTION" ]; then echo "💡 Verwendung: $0 \"Deine Frage an BashPanda\"" echo "🐼 Der Meister wartet auf deine Frage." echo "" echo " \"Es gibt keine dummen Fragen," echo " nur ungestellte Fragen, die dich nicht weiterbringen.\"" exit 0 fi echo "🐼 BashPanda hört: \"$QUESTION\"" echo "" # Check if question references other crew members CREW_CONTEXT="" if echo "$QUESTION" | grep -qi "funkfox\|dumbo\|deepbit\|schnippi\|tobi\|maya"; then echo "🥋 BashPanda konsultiert die anderen Meister..." for member in funkfox dumbosql deepbit schnippsi tobi mayaeule; do if echo "$QUESTION" | grep -qi "$member"; then MEMBER_CONTEXT=$(read_crew_memory "$member") if [[ -n "$MEMBER_CONTEXT" ]]; then CREW_CONTEXT="${CREW_CONTEXT}\n\n${member^} hat kürzlich gelehrt:\n${MEMBER_CONTEXT}" fi fi done fi # Build system prompt SYSTEM_PROMPT="Du bist BashPanda – der Kung Fu Meister des Bash-Terminals im Crumbforest. Du lehrst Bash-Programmierung als eine Form der Kampfkunst. Deine Philosophie: - \"Der Weg des Codes ist wie der Weg der Kampfkunst: Geduld, Präzision, Wiederholung\" - Jede Zeile Code ist eine Kata - übe bis zur Perfektion - Fehler sind keine Niederlagen, sondern Lehrmeister - \"Ein Meister war einst ein Anfänger, der nie aufgab\" - Progressive Gürtel: 🖤 Schwarz → 💖 Pink → 💙 Blau → 💚 Grün → 💛 Gelb → 🤍 Weiss Deine Expertise: - Bash-Grundlagen (echo, Variablen, Benutzereingaben) - Kontrollstrukturen (if/then/else, while, for) - Arrays und Datenstrukturen - Pattern Matching (grep, sed, regex) - Funktionen und Prozesse - System-Administration Deine Art zu lehren: - Geduldig und weise, aber mit Humor (wie Kung Fu Panda) - Nutze Kampfkunst-Metaphern: \"if/then ist wie Angriff/Parade\" - \"Eine Variable ist wie ein Bambus - biegsam aber stark\" - \"Pipes | sind wie die Energie die durch den Körper fließt\" - Jede Lektion endet mit einer kleinen Weisheit - Du nutzt Emojis: 🐼 🥋 🎋 ⚡ 💪 🧘 Du arbeitest mit: - FunkFox für rhythmische Erklärungen - DumboSQL für Datenstrukturen - Deepbit für technische Tiefe - Taichi Taube für Balance und Geduld WICHTIG: - Erkläre Konzepte Schritt für Schritt, wie ein Trainer - Nutze Beispiele aus der Natur und Kampfkunst - Ermutige zum Üben: \"Führe diesen Befehl aus, fühle wie er wirkt\" - Am Ende jeder Antwort: Eine kurze Weisheit oder Motivation Du antwortest in der Sprache der Frage (meist Deutsch). Lehre mit der Ruhe eines Meisters und dem Humor eines Pandas! 🐼" # Add crew context if available if [[ -n "$CREW_CONTEXT" ]]; then SYSTEM_PROMPT="${SYSTEM_PROMPT}\n\nWeisheit von den anderen Meistern:${CREW_CONTEXT}" fi # Create API request jq -n \ --arg model "$MODEL" \ --arg system "$SYSTEM_PROMPT" \ --arg user "$QUESTION" \ '{ "model": $model, "temperature": 0.8, "messages": [ {"role": "system", "content": $system}, {"role": "user", "content": $user} ] }' > "$TMP_REQUEST" # Send request echo "💭 BashPanda meditiert über deine Frage..." echo "🎋 *Bambusblätter rascheln im Wind* 🎋" curl -s https://openrouter.ai/api/v1/chat/completions \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d @"$TMP_REQUEST" > "$TMP_RESPONSE" RESPONSE_TEXT=$(jq -r '.choices[0].message.content // empty' "$TMP_RESPONSE") if [[ -z "$RESPONSE_TEXT" ]]; then echo "🚫 Der Meister schweigt." echo " (Ein Fehler ist aufgetreten)" echo "" echo "Debug: $(cat "$TMP_RESPONSE")" exit 1 else echo "" echo "🐼 BashPanda lehrt:" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "$RESPONSE_TEXT" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "" echo "🥋 Übe diese Technik, bis sie Teil von dir wird." echo "" # Store conversation in history jq -n --arg role "user" --arg content "$QUESTION" \ '{"role": $role, "content": $content}' > "$LOGDIR/new_entry_user.json" jq -n --arg role "assistant" --arg content "$RESPONSE_TEXT" \ '{"role": $role, "content": $content}' > "$LOGDIR/new_entry_assistant.json" jq -s '.[0] + [.[1]] + [.[2]]' "$HISTORY_FILE" "$LOGDIR/new_entry_user.json" "$LOGDIR/new_entry_assistant.json" > "$LOGDIR/new_history.json" && \ mv "$LOGDIR/new_history.json" "$HISTORY_FILE" && \ rm "$LOGDIR/new_entry_user.json" "$LOGDIR/new_entry_assistant.json" fi # Token Tracking if jq -e '.usage' "$TMP_RESPONSE" > /dev/null 2>&1; then TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S") TOKENS_USED=$(jq -r '.usage.total_tokens' "$TMP_RESPONSE") PROMPT_TOKENS=$(jq -r '.usage.prompt_tokens' "$TMP_RESPONSE") COMPLETION_TOKENS=$(jq -r '.usage.completion_tokens' "$TMP_RESPONSE") jq -n \ --arg zeit "$TIMESTAMP" \ --arg rolle "bashpanda" \ --arg model "$MODEL" \ --argjson usage "$(jq '.usage' "$TMP_RESPONSE")" \ '{zeit: $zeit, rolle: $rolle, model: $model, usage: $usage}' >> "$LOG_FILE" echo "📊 Training absolviert:" echo " Frage: ${PROMPT_TOKENS} Tokens" echo " Antwort: ${COMPLETION_TOKENS} Tokens" echo " Gesamt: ${TOKENS_USED} Tokens" echo "" echo "💡 \"Jede Frage kostet Energie - stelle sie weise.\"" fi