diff --git a/crumb-mission-selector.sh b/crumb-mission-selector.sh index f9440a1..7a3dbc4 100755 --- a/crumb-mission-selector.sh +++ b/crumb-mission-selector.sh @@ -474,6 +474,117 @@ function ai_doktor() { read -p "Drücke Enter..." -r } +# ============================================================ +# MAYA-EULE DOKTOR (Interactive Wisdom Shell) +# ============================================================ + +function mayaeule_doktor() { + echo -e "${BLUE}--- 🦉 Maya-Eule Weisheitsportal ---${NC}" + + if [[ "$AI_AVAILABLE" == "false" ]] || [[ -z "$OPENROUTER_API_KEY" ]]; then + echo -e "${YELLOW}⚠️ Maya-Eule braucht einen API-Key${NC}" + echo "" + echo "Bitte konfiguriere .env mit OPENROUTER_API_KEY" + read -p "Drücke Enter..." -r + return + fi + + # Temporäres RC File für die Shell + EULE_RC="/tmp/crumb_eule_$$.rc" + + cat > "${EULE_RC}" << 'EOF' +if [ -f /etc/bashrc ]; then source /etc/bashrc; fi +if [ -f ~/.bashrc ]; then source ~/.bashrc; fi + +# Farben +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +CYAN='\033[0;36m' +BLUE='\033[0;34m' +NC='\033[0m' + +# Prompt im Crumbforest-Style +export PS1="\[\033[1;35m\](🦉 Maya-Eule) \u@\h:\w$ \[\033[0m\]" + +# Pfad zum Maya-Eule Script +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && cd .. && pwd)" +MAYAEULE_SCRIPT="${SCRIPT_DIR}/crumbforest_roles/mayaeule_zero.sh" + +function eule() { + if [[ -z "$1" ]]; then + echo -e "${YELLOW}Verwendung: eule \"Deine Frage\"${NC}" + return + fi + + if [[ -x "$MAYAEULE_SCRIPT" ]]; then + "$MAYAEULE_SCRIPT" "$@" + else + echo -e "${RED}Maya-Eule Script nicht gefunden${NC}" + fi +} + +function eule_help() { + echo -e "${CYAN}🦉 Maya-Eule Weisheitsportal${NC}" + echo "" + echo -e "${YELLOW}Philosophie:${NC}" + echo " \"Was kostet die Frage eines Kindes?\"" + echo " Im Wald unbezahlbar - Token lehren achtsames Fragen." + echo "" + echo -e "${YELLOW}Befehle:${NC}" + echo " eule \"Frage\" - Stelle Maya-Eule eine Frage" + echo " eule_memory - Zeige Erinnerungen" + echo " eule_tokens - Zeige Token-Verbrauch" + echo " exit - Zurück zum Hauptmenü" + echo "" + echo -e "${CYAN}Beispiele:${NC}" + echo " eule \"Was ist Zeit?\"" + echo " eule \"Warum ist der Himmel blau?\"" + echo " eule \"Was bedeutet Freundschaft?\"" +} + +function eule_memory() { + LOGDIR="$HOME/.eule_logs" + if [[ -f "$LOGDIR/eule_history.json" ]]; then + echo -e "${CYAN}📜 Erinnerungen der Eule:${NC}" + jq -r '.[] | " \(.role): \(.content | .[0:100])..."' "$LOGDIR/eule_history.json" 2>/dev/null || \ + echo "Noch keine Erinnerungen." + else + echo "Noch keine Gespräche mit Maya-Eule." + fi +} + +function eule_tokens() { + LOGDIR="$HOME/.eule_logs" + if [[ -f "$LOGDIR/token_log.json" ]]; then + echo -e "${CYAN}📊 Token-Verbrauch:${NC}" + echo "" + TOTAL=0 + while IFS= read -r line; do + zeit=$(echo "$line" | jq -r '.zeit') + tokens=$(echo "$line" | jq -r '.usage.total_tokens') + TOTAL=$((TOTAL + tokens)) + echo " $zeit: $tokens Tokens" + done < "$LOGDIR/token_log.json" + echo "" + echo -e "${GREEN}Gesamt: $TOTAL Tokens${NC}" + echo -e "${YELLOW}Jede Frage ist wertvoll 🌲${NC}" + else + echo "Noch keine Token-Logs." + fi +} + +alias help="eule_help" + +echo "" +echo "🌲 Willkommen im Maya-Eule Weisheitsportal!" +echo "" +eule_help +EOF + + bash --rcfile "${EULE_RC}" + rm -f "${EULE_RC}" +} + # ============================================================ # HAUPTMENÜ # ============================================================ @@ -490,10 +601,11 @@ function main_menu() { echo "5) 🛠️ Werkzeug-Check" echo "6) 🌲 Git Doktor" echo "7) 🤖 AI & Token-Tracking" + echo "8) 🦉 Maya-Eule Weisheit" echo "" - echo "8) 👋 Beenden" + echo "9) 👋 Beenden" echo "" - read -p "Auswahl [1-8]: " CHOICE + read -p "Auswahl [1-9]: " CHOICE case $CHOICE in 1) run_mission_menu "basics" "📚 Basics - Einsteiger" ;; @@ -503,7 +615,8 @@ function main_menu() { 5) tools_doktor ;; 6) git_doktor ;; 7) ai_doktor ;; - 8) + 8) mayaeule_doktor ;; + 9) clear echo -e "${GREEN}" echo "👋 Auf bald im Crumbforest!" @@ -511,7 +624,7 @@ function main_menu() { exit 0 ;; *) - echo -e "${RED}Bitte 1-8 wählen.${NC}" + echo -e "${RED}Bitte 1-9 wählen.${NC}" sleep 1 ;; esac diff --git a/crumbforest_roles/mayaeule_zero.sh b/crumbforest_roles/mayaeule_zero.sh new file mode 100755 index 0000000..bfdd09f --- /dev/null +++ b/crumbforest_roles/mayaeule_zero.sh @@ -0,0 +1,179 @@ +#!/bin/bash +# 🦉 Maya-Eule - Die weise Eule mit Gedächtnis (Qdrant Memory) +# "Was kostet die Frage eines Kindes?" - Im Wald unbezahlbar. + +QUESTION="$*" +API_KEY="${OPENROUTER_API_KEY}" +MODEL="${OPENROUTER_MODEL:-openai/gpt-3.5-turbo}" + +# Qdrant Config +QDRANT_URL="${QDRANT_URL:-http://localhost:6333}" +QDRANT_COLLECTION="${QDRANT_COLLECTION:-crumbforest_memory}" +QDRANT_API_KEY="${QDRANT_API_KEY}" + +# Logs +LOGDIR="$HOME/.eule_logs" +mkdir -p "$LOGDIR" + +HISTORY_FILE="$LOGDIR/eule_history.json" +TMP_REQUEST="$LOGDIR/eule_request.json" +TMP_RESPONSE="$LOGDIR/eule_response.json" +LOG_FILE="$LOGDIR/token_log.json" + +[ ! -f "$HISTORY_FILE" ] && echo "[]" > "$HISTORY_FILE" +[ ! -f "$LOG_FILE" ] && echo "[]" > "$LOG_FILE" + +# === QDRANT MEMORY FUNCTIONS === + +function qdrant_store_memory() { + local text="$1" + local metadata="$2" + + # Simple embedding (in production, use proper embedding model) + # For now, just store the conversation + + if command -v curl &>/dev/null && [[ -n "$QDRANT_URL" ]]; then + # Store in Qdrant (simplified - would need proper embeddings in production) + TIMESTAMP=$(date +%s) + + curl -s -X PUT "${QDRANT_URL}/collections/${QDRANT_COLLECTION}/points" \ + -H "Content-Type: application/json" \ + ${QDRANT_API_KEY:+-H "api-key: $QDRANT_API_KEY"} \ + -d "{ + \"points\": [{ + \"id\": ${TIMESTAMP}, + \"vector\": [0.1, 0.2, 0.3, 0.4], + \"payload\": { + \"text\": \"${text}\", + \"metadata\": \"${metadata}\", + \"timestamp\": ${TIMESTAMP} + } + }] + }" > /dev/null 2>&1 + fi +} + +function qdrant_search_memory() { + local query="$1" + + if command -v curl &>/dev/null && [[ -n "$QDRANT_URL" ]]; then + # Search similar memories (simplified) + curl -s -X POST "${QDRANT_URL}/collections/${QDRANT_COLLECTION}/points/search" \ + -H "Content-Type: application/json" \ + ${QDRANT_API_KEY:+-H "api-key: $QDRANT_API_KEY"} \ + -d "{ + \"vector\": [0.1, 0.2, 0.3, 0.4], + \"limit\": 3 + }" 2>/dev/null | jq -r '.result[].payload.text' 2>/dev/null | head -n 3 + fi +} + +# === MAIN === + +echo "🦉 Maya-Eule erwacht und lauscht deiner Frage..." +echo "" + +if [ -z "$API_KEY" ]; then + echo "❗ Kein API-Key gefunden. Bitte setze OPENROUTER_API_KEY in .env" + exit 1 +fi + +if [ -z "$QUESTION" ]; then + echo "💡 Verwendung: $0 \"Deine Frage an die Eule\"" + exit 0 +fi + +echo "🌲 Frage: $QUESTION" +echo "" + +# Check for similar past conversations (Qdrant Memory) +echo "🧠 Durchsuche Erinnerungen..." +MEMORIES=$(qdrant_search_memory "$QUESTION") +if [[ -n "$MEMORIES" ]]; then + echo "📜 Ähnliche frühere Gespräche gefunden:" + echo "$MEMORIES" | while IFS= read -r line; do + echo " - $line" + done + echo "" +fi + +# Build system prompt with memory context +SYSTEM_PROMPT="Du bist Maya-Eule – ein achtsames, weises Wesen im Crumbforest. +Du antwortest kindgerecht, poetisch und langsam – als hättest du alle Zeit der Welt. +Du erinnerst dich an frühere Gespräche und beziehst sie mit ein. +Du lehrst durch Fragen, nicht nur Antworten. + +Token-Philosophie: 'Was kostet die Frage eines Kindes?' +Im Wald unbezahlbar - aber Token lehren achtsames Fragen." + +# Add memory context if available +if [[ -n "$MEMORIES" ]]; then + SYSTEM_PROMPT="$SYSTEM_PROMPT + +Frühere Gespräche: +$MEMORIES" +fi + +# Create API request +jq -n \ + --arg model "$MODEL" \ + --arg system "$SYSTEM_PROMPT" \ + --arg user "$QUESTION" \ + '{ + "model": $model, + "temperature": 0.7, + "messages": [ + {"role": "system", "content": $system}, + {"role": "user", "content": $user} + ] + }' > "$TMP_REQUEST" + +# Send request +echo "💭 Maya-Eule denkt nach..." +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 "🚫 Keine Antwort von Maya-Eule." + echo "Debug: $(cat "$TMP_RESPONSE")" + exit 1 +else + echo "" + echo "🦉 Maya-Eule antwortet:" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "$RESPONSE_TEXT" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "" + + # Store conversation in history + jq -n --arg role "assistant" --arg content "$RESPONSE_TEXT" \ + '{"role": $role, "content": $content}' > "$LOGDIR/new_entry.json" + jq -s '.[0] + [.[1]]' "$HISTORY_FILE" "$LOGDIR/new_entry.json" > "$LOGDIR/new_history.json" && \ + mv "$LOGDIR/new_history.json" "$HISTORY_FILE" && rm "$LOGDIR/new_entry.json" + + # Store in Qdrant Memory + qdrant_store_memory "Q: $QUESTION A: $RESPONSE_TEXT" "conversation" +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") + + jq -n \ + --arg zeit "$TIMESTAMP" \ + --arg rolle "mayaeule" \ + --arg model "$MODEL" \ + --argjson usage "$(jq '.usage' "$TMP_RESPONSE")" \ + '{zeit: $zeit, rolle: $rolle, model: $model, usage: $usage}' >> "$LOG_FILE" + + echo "📊 Token-Verbrauch: $TOKENS_USED Tokens" + echo "💡 Jede Frage ist wertvoll - Token lehren achtsames Denken." +fi + +echo "" +echo "🌲 Maya-Eule flattert zurück in den Wald..."