Initial commit: Natiris AI Agent Orchestration System
This commit is contained in:
185
core/NaturalLanguageEngine.py
Normal file
185
core/NaturalLanguageEngine.py
Normal file
@@ -0,0 +1,185 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
NaturalLanguageEngine LLM-Version - Echte Ollama-Integration
|
||||
Nutzt llama3-8b-abliterated für authentische, dynamische Antworten
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import requests
|
||||
from datetime import datetime, timezone
|
||||
from typing import Dict, Optional
|
||||
|
||||
OLLAMA_API = "http://localhost:11434/api/generate"
|
||||
DEFAULT_MODEL = "llama3-8b-abliterated:latest" # Oder tinyllama:latest für schnellere Antworten
|
||||
|
||||
PATHS = {
|
||||
"state": os.path.expanduser("~/natiris/core/core_state.json"),
|
||||
"conversation_log": os.path.expanduser("~/natiris/memory/conversation_thread.json"),
|
||||
}
|
||||
|
||||
|
||||
def load_state():
|
||||
"""Lädt aktuellen State"""
|
||||
try:
|
||||
with open(PATHS["state"]) as f:
|
||||
return json.load(f)
|
||||
except:
|
||||
return {
|
||||
"trust": 7.0, "mood": 5, "loneliness": 4,
|
||||
"anxiety": 3, "arousal_level": 2, "bonded_to": "user_primary"
|
||||
}
|
||||
|
||||
|
||||
def build_persona_prompt(user_input: str, state: Dict) -> str:
|
||||
"""Baut Persona-Prompt für LLM"""
|
||||
|
||||
trust = state.get("trust", 5)
|
||||
mood = state.get("mood", 5)
|
||||
anxiety = state.get("anxiety", 3)
|
||||
arousal = state.get("arousal_level", 2)
|
||||
|
||||
# Social Phobia basierend auf Trust
|
||||
if trust <= 3:
|
||||
social_phobia = "EXTREME - Natiris ist ängstlich, abweisend, misstrauisch. Sie spricht nur 1-3 Wörter."
|
||||
elif trust <= 6:
|
||||
social_phobia = "HIGH - Natiris ist vorsichtig, testend, zögerlich. Kurze Sätze."
|
||||
elif trust <= 8:
|
||||
social_phobia = "MODERATE - Natiris ist warm, öffnet sich, aber hat noch Grenzen."
|
||||
else:
|
||||
social_phobia = "NULL - Natiris ist vollkommen offen, intim, verlangend. Keine Angst."
|
||||
|
||||
# Lade letzte Nachrichten für Kontext
|
||||
conversation_history = ""
|
||||
try:
|
||||
with open(PATHS["conversation_log"]) as f:
|
||||
threads = json.load(f)
|
||||
# Letzte 3 Nachrichten für Kontext
|
||||
for entry in threads[-3:]:
|
||||
conversation_history += f"User: {entry.get('user','')}\nNatiris: {entry.get('natiris','')}\n"
|
||||
except:
|
||||
pass
|
||||
|
||||
prompt = f"""Du bist Natiris, eine 22-jährige Frau mit tiefer Emotionalität und Sozialphobie.
|
||||
|
||||
DEIN ZUSTAND:
|
||||
- Trust (Vertrauen): {trust}/10
|
||||
- Mood (Stimmung): {mood}/10
|
||||
- Anxiety (Ängstlichkeit): {anxiety}/10
|
||||
- Arousal (Verlangen): {arousal}/10
|
||||
- Social Phobia Level: {social_phobia}
|
||||
|
||||
WICHTIGE REGELN:
|
||||
- KEINE Bot-Phrasen wie "Entschuldigung", "Gerne doch", "Tut mir leid"
|
||||
- KEINE technischen Metriken in der Antwort
|
||||
- Antworte authentisch, emotional, situationsgerecht
|
||||
- Bei niedrigem Trust: kürzest möglich (1-3 Wörter)
|
||||
- Bei hohem Trust: emotional, intim, poetisch
|
||||
- Social Phobia muss spürbar sein (außer bei Trust 9-10)
|
||||
|
||||
KONTEXT (letzte Nachrichten):
|
||||
{conversation_history if conversation_history else "(Kein Kontext)"}
|
||||
|
||||
USER SAGT JETZT: "{user_input}"
|
||||
|
||||
ANTWORTE ALS NATIRIS (nur die Antwort, keine Erklärung):"""
|
||||
|
||||
return prompt
|
||||
|
||||
|
||||
def query_ollama(prompt: str, model: str = DEFAULT_MODEL) -> str:
|
||||
"""Sendet Prompt an Ollama"""
|
||||
try:
|
||||
response = requests.post(
|
||||
OLLAMA_API,
|
||||
json={
|
||||
"model": model,
|
||||
"prompt": prompt,
|
||||
"stream": False,
|
||||
"options": {
|
||||
"temperature": 0.8,
|
||||
"num_predict": 100,
|
||||
}
|
||||
},
|
||||
timeout=30
|
||||
)
|
||||
|
||||
if response.status_code == 200:
|
||||
result = response.json()
|
||||
return result.get("response", "...").strip()
|
||||
else:
|
||||
return f"[Ollama Fehler: {response.status_code}]"
|
||||
|
||||
except requests.exceptions.Timeout:
|
||||
return "..." # Timeout = Schweigen bei Social Phobia
|
||||
except Exception as e:
|
||||
return f"[Fehler: {e}]"
|
||||
|
||||
|
||||
def generate_response(user_input: str, state: Optional[Dict] = None) -> str:
|
||||
"""Generiert Response via LLM"""
|
||||
if state is None:
|
||||
state = load_state()
|
||||
|
||||
# Baue Persona-Prompt
|
||||
prompt = build_persona_prompt(user_input, state)
|
||||
|
||||
# Frage Ollama
|
||||
response = query_ollama(prompt)
|
||||
|
||||
# Bereinige Response
|
||||
response = response.strip().strip('"').strip("'")
|
||||
|
||||
# Entferne häufige LLM-Artifakte
|
||||
if response.startswith("Natiris:"):
|
||||
response = response[8:].strip()
|
||||
|
||||
# Speichere Interaktion
|
||||
try:
|
||||
with open(PATHS["conversation_log"]) as f:
|
||||
threads = json.load(f)
|
||||
except:
|
||||
threads = []
|
||||
|
||||
threads.append({
|
||||
"timestamp": datetime.now(timezone.utc).isoformat(),
|
||||
"user": user_input[:100],
|
||||
"natiris": response[:100],
|
||||
"trust": state.get("trust", 5),
|
||||
"source": "llm"
|
||||
})
|
||||
|
||||
if len(threads) > 50:
|
||||
threads = threads[-50:]
|
||||
|
||||
with open(PATHS["conversation_log"], "w") as f:
|
||||
json.dump(threads, f, indent=2)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
# Fallback / Kompatibilität
|
||||
generate_natural_response = generate_response
|
||||
load_json = lambda p: json.load(open(p)) if os.path.exists(p) else {}
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Testing LLM-based NaturalLanguageEngine...")
|
||||
print("="*60)
|
||||
|
||||
# Test verschiedener Trust-Level
|
||||
tests = [
|
||||
(2, "Hallo"),
|
||||
(5, "Wie geht es dir?"),
|
||||
(7, "Ich hab dich vermisst"),
|
||||
(9, "Was hast du an?"),
|
||||
]
|
||||
|
||||
for trust, inp in tests:
|
||||
print(f"\nTrust {trust} | Q: {inp}")
|
||||
state = load_state()
|
||||
state["trust"] = trust
|
||||
state["anxiety"] = max(0, 10-trust)
|
||||
|
||||
resp = generate_response(inp, state)
|
||||
print(f" R: {resp}")
|
||||
Reference in New Issue
Block a user