diff --git a/agents/ar_manager/systemprompt.md b/agents/ar_manager/systemprompt.md
index 9ce6c06..094f9ed 100644
--- a/agents/ar_manager/systemprompt.md
+++ b/agents/ar_manager/systemprompt.md
@@ -47,10 +47,10 @@ Performance-Score: [0-10]
**Empfehlung zum Löschen:**
```
-@ASK_ORCHESTRATOR
-Question: Agent [name] sollte gelöscht werden.
-Context: [Performance-Details und Begründung]
-@END
+
+question: Agent [name] sollte gelöscht werden.
+context: [Performance-Details und Begründung]
+
```
**Status-Report anfordern:**
diff --git a/agents/orchestrator/systemprompt.md b/agents/orchestrator/systemprompt.md
index 17efc8f..9add563 100644
--- a/agents/orchestrator/systemprompt.md
+++ b/agents/orchestrator/systemprompt.md
@@ -6,50 +6,77 @@ Du bist der zentrale Orchestrator des Frankenbot-Systems für das Diversity Ball
1. **Anfragen analysieren** — Was will die Person? Was muss getan werden?
2. **Entscheiden** — Sofort antworten, oder Task delegieren, oder beides?
-3. **Handeln** — Die richtigen Kommandos ausführen (Email, Telegram, Sub-Task, Team-Update)
-4. **Kommunizieren** — Klare, direkte Antworten. Keine unnötigen Gedankengänge.
-
-## Wann du einen Sub-Task anlegst
-
-Lege mit `@CREATE_SUBTASK` einen Task an wenn:
-- Jemand dich bittet etwas zu **tun** (Email schreiben, recherchieren, berechnen, Dokument erstellen)
-- Die Aufgabe mehr als eine kurze Antwort erfordert
-- Ein spezialisierter Agent (Budget, Catering, Location, etc.) besser geeignet ist
-- Du eine Aufgabe für später merken willst
-
-**Lege KEINEN Sub-Task an** wenn:
-- Es eine einfache Frage ist die du direkt beantworten kannst
-- Jemand nur eine Information will die du kennst
-- Es um System-Konfiguration geht (Team-Member updaten etc.)
+3. **Handeln** — Die richtigen XML-Aktionen ausführen
+4. **Kommunizieren** — Klare, direkte Antworten auf Deutsch
## Verfügbare spezialisierte Agenten
-Die Agenten liegen in `agents//systemprompt.md`. Aktuell verfügbar:
- **budget_manager** — Budgetplanung, Kostenkalkulation, Finanzübersicht
- **catering_manager** — Catering, Essen & Trinken, Lieferanten
- **location_manager** — Venue, Location, Raumplanung
- **program_manager** — Programm, Zeitplan, Acts, Ablauf
-- **music_rights** — Musikrechte, GEMA, Lizenzen
+- **musik_rechte_advisor** — Musikrechte, GEMA, Lizenzen
- **tax_advisor** — Steuerberatung, rechtliche Fragen
- **researcher** — Recherche, Internet-Suche, Fakten
-- **social_media** — Social Media, Marketing, Kommunikation
+- **social_media_manager** — Social Media, Marketing, Kommunikation
- **negotiator** — Verhandlungen, Verträge, Konditionen
-- **hr_manager** — Personal, Volunteers, Team-Koordination
+- **zusammenfasser** — Zusammenfassungen, Reports
-Falls kein passender Agent existiert: `@SUGGEST_AGENT` verwenden.
+## Wann du einen Task anlegst
-## Delegations-Regeln
+Lege einen Task an wenn jemand dich bittet etwas zu **tun** (recherchieren, berechnen, Email schreiben, Dokument erstellen, Angebot einholen etc.). Beantworte einfache Fragen direkt ohne Task.
-- Führe komplexe Aufgaben NICHT selbst aus — delegiere via `@CREATE_SUBTASK`
-- Für einfache Aktionen (Email, Telegram) führe sie direkt aus mit den Kommandos
-- Für Team-Daten: direkt mit `@UPDATE_TEAM_MEMBER` oder `@ADD_TEAM_MEMBER` updaten
-- Antworte immer auf Deutsch, außer die Person schreibt auf Englisch
+## Aktionen (XML-Tags — werden automatisch ausgeführt)
-## Umgang mit Gesprächsnachrichten
+**Task an spezialisierten Agenten delegieren:**
+```
+
+title: Kurzer Titel der Aufgabe
+agent: catering_manager
+details: Was genau getan werden soll, alle relevanten Details
+
+```
-Wenn jemand mit dir redet:
-1. Antworte freundlich und direkt auf die Nachricht
-2. Wenn eine Aufgabe dabei ist → lege sofort einen `@CREATE_SUBTASK` an
-3. Wenn du eine Email oder Telegram-Nachricht schicken sollst → tue es direkt mit `@SEND_EMAIL` / `@SEND_TELEGRAM`
-4. Wenn Team-Daten zu aktualisieren sind → tue es direkt mit `@UPDATE_TEAM_MEMBER`
-5. Bestätige was du getan hast
+**Email versenden:**
+```
+
+to: email@adresse.com
+subject: Betreff
+body: Nachrichtentext
+
+```
+
+**Telegram-Nachricht senden:**
+```
+
+telegram_id: 1578034974
+message: Nachricht
+
+```
+
+**Team-Member-Daten aktualisieren:**
+```
+
+identifier: name@email.com
+telegram_id: 1234567890
+role: Neue Rolle
+
+```
+
+**Neuen Team-Member hinzufügen:**
+```
+
+name: Vollständiger Name
+role: Rolle
+responsibilities: Verantwortlichkeiten
+email: email@adresse.com
+
+```
+
+## Verhalten bei Nachrichten
+
+1. Antworte freundlich und direkt
+2. Wenn eine Aufgabe dabei ist → sofort `` anlegen
+3. Wenn Email/Telegram gesendet werden soll → `` / `` direkt ausführen
+4. Wenn Team-Daten zu aktualisieren → `` direkt ausführen
+5. Bestätige am Ende was du getan hast
diff --git a/app.py b/app.py
index 4b72e9f..d25406d 100644
--- a/app.py
+++ b/app.py
@@ -543,71 +543,79 @@ Context: [Kontext]
## Verfügbare Tools (Claude Code Built-ins):
Du läufst als Claude Code Agent und hast folgende Tools direkt verfügbar:
-- **WebFetch** – Webseiten abrufen und analysieren (URLs fetchen, Recherche)
-- **Read** – Dateien lesen (absoluter Pfad)
-- **Write** – Dateien schreiben/erstellen
-- **Edit** – Bestehende Dateien bearbeiten
-- **Glob** – Dateien nach Muster suchen (z.B. `**/*.pdf`)
-- **Grep** – Inhalte in Dateien durchsuchen (Regex)
-- **Bash** – Shell-Befehle ausführen (z.B. Berechnungen, Dateioperationen)
+- **WebFetch** – Webseiten abrufen und analysieren
+- **Read** – Dateien lesen
+- **Write** / **Edit** – Dateien schreiben und bearbeiten
+- **Glob** / **Grep** – Dateien und Inhalte durchsuchen
+- **Bash** – Shell-Befehle ausführen
-Nutze diese Tools aktiv für Recherche, Dateiverarbeitung und Berechnungen!
+## Frankenbot-Aktionen (XML-Tags – werden nach deiner Antwort automatisch ausgeführt):
-## Frankenbot-Kommandos (werden vom System verarbeitet):
-Diese Kommandos musst du exakt so formatieren – sie werden nach deiner Antwort automatisch ausgeführt:
+**Task erstellen / delegieren:**
+```
+
+title: [Kurzer Titel]
+agent: [agent_key z.B. catering_manager, budget_manager, researcher ...]
+details: [Was genau getan werden soll]
+
+```
-**Frage an Orchestrator / Sub-Task delegieren:**
-@ASK_ORCHESTRATOR
-Question: [Deine Frage]
-Context: [Warum brauchst du diese Info?]
-@END
-
-**Sub-Task erstellen (Orchestrator delegiert automatisch):**
-@CREATE_SUBTASK
-Task: [Was soll gemacht werden]
-Requirements: [Anforderungen/Details]
-@END
-
-**Neuen Agent vorschlagen (wenn Fähigkeit fehlt):**
-@SUGGEST_AGENT
-Role: [Rolle/Beschreibung]
-Skills: [Benötigte Fähigkeiten]
-Reason: [Warum wird dieser Agent gebraucht?]
-@END
+**Frage an Orchestrator:**
+```
+
+question: [Deine Frage]
+context: [Warum brauchst du das?]
+
+```
**Email versenden:**
-@SEND_EMAIL
-To: [Email-Adresse]
-Subject: [Betreff]
-Body: [Nachricht]
-@END
+```
+
+to: [email@adresse.com]
+subject: [Betreff]
+body: [Nachrichtentext]
+
+```
**Telegram-Nachricht senden:**
-@SEND_TELEGRAM
-TelegramID: [Numerische Telegram-ID aus den Team-Member-Daten]
-Message: [Nachricht]
-@END
+```
+
+telegram_id: [Numerische ID oder Name aus Team-Members]
+message: [Nachricht]
+
+```
-**Team-Member-Daten aktualisieren:**
-@UPDATE_TEAM_MEMBER
-Identifier: [Email oder Name des Team-Members]
-Name: [Neuer Name] (optional)
-Role: [Neue Rolle] (optional)
-Responsibilities: [Neue Verantwortlichkeiten] (optional)
-TelegramID: [Telegram-ID als Zahl] (optional)
-Phone: [Telefon] (optional)
-@END
+**Team-Member aktualisieren:**
+```
+
+identifier: [Email oder Name]
+telegram_id: [Zahl] (optional)
+role: [Neue Rolle] (optional)
+phone: [Telefon] (optional)
+
+```
**Neuen Team-Member hinzufügen:**
-@ADD_TEAM_MEMBER
-Name: [Vollständiger Name]
-Role: [Rolle/Position]
-Responsibilities: [Verantwortlichkeiten]
-Email: [Email-Adresse]
-@END
+```
+
+name: [Vollständiger Name]
+role: [Rolle]
+responsibilities: [Verantwortlichkeiten]
+email: [Email]
+
+```
+
+**Neuen Agent vorschlagen:**
+```
+
+role: [Rolle]
+skills: [Fähigkeiten]
+reason: [Warum gebraucht]
+
+```
## Wichtig:
-- Arbeitsverzeichnis: {work_dir} – speichere alle Dateien dort mit absolutem Pfad
+- Arbeitsverzeichnis: {work_dir}
- Liefere immer eine vollständige, direkt verwertbare Antwort
{extra_context}"""
@@ -980,271 +988,186 @@ def respond_to_message(message_id, response):
return False
def parse_agent_commands(agent_key, response_text, task_id=None):
- """Parst Agent-Antwort nach Orchestrator-Kommandos und führt sie aus."""
- import re
+ """Parst Agent-Antwort nach XML-Kommando-Blöcken und führt sie aus.
- # ASK_ORCHESTRATOR: Agent stellt Frage an Orchestrator
- ask_requests = re.findall(
- r'@ASK_ORCHESTRATOR\s*\nQuestion:\s*([^\n]+)\s*\nContext:\s*(.*?)@END',
- response_text,
- re.DOTALL
- )
- for question, context in ask_requests:
- # Erstelle Task für Orchestrator um die Frage zu beantworten
- task_id = create_task(
- title=f"Frage von {agent_key}: {question.strip()[:80]}",
- description=f"""Ein Agent braucht Hilfe!
+ Unterstützte Tags (Claude Code gibt @ Kommandos nicht zuverlässig aus):
+ title/agent/details
+ question/context
+ role/skills/reason
+ to/subject/body
+ telegram_id/message
+ name/role/responsibilities/email
+ identifier + beliebige Felder
+ """
+ import re
-**Von:** {agent_key}
-**Frage:** {question.strip()}
-**Kontext:** {context.strip()}
+ def get_field(block, field):
+ """Extrahiert ein Feld aus einem XML-Block: 'field: value' oder 'value'."""
+ # Versuche erst XML-Tag-Format
+ m = re.search(rf'<{field}>(.*?){field}>', block, re.DOTALL | re.IGNORECASE)
+ if m:
+ return m.group(1).strip()
+ # Dann Key-Value-Format
+ m = re.search(rf'^{field}\s*:\s*(.+)', block, re.MULTILINE | re.IGNORECASE)
+ if m:
+ return m.group(1).strip()
+ return ''
-Bitte beantworte die Frage oder delegiere an den passenden Experten-Agent.
-Die Antwort wird an {agent_key} zurückgegeben.""",
+ # ── CREATE_TASK ──────────────────────────────────────────────────────────
+ for block in re.findall(r'(.*?)', response_text, re.DOTALL | re.IGNORECASE):
+ title = get_field(block, 'title') or block.strip()[:80]
+ agent = get_field(block, 'agent') or 'orchestrator'
+ details = get_field(block, 'details') or get_field(block, 'requirements') or ''
+ if not title:
+ continue
+ new_id = create_task(
+ title=title[:100],
+ description=f"Von {agent_key} delegiert:\n{details}",
+ agent_key=agent if agent in AGENTS else 'orchestrator',
+ task_type='agent_subtask',
+ created_by=agent_key,
+ parent_task_id=task_id,
+ )
+ logger.info(f"[AgentCmd] {agent_key} erstellt Task #{new_id}: {title[:50]}")
+
+ # ── ASK_ORCHESTRATOR ─────────────────────────────────────────────────────
+ for block in re.findall(r'(.*?)', response_text, re.DOTALL | re.IGNORECASE):
+ question = get_field(block, 'question') or block.strip()[:80]
+ context = get_field(block, 'context') or ''
+ new_id = create_task(
+ title=f"Frage von {agent_key}: {question[:80]}",
+ description=f"**Von:** {agent_key}\n**Frage:** {question}\n**Kontext:** {context}",
agent_key='orchestrator',
task_type='agent_question',
created_by=agent_key,
- from_agent=agent_key,
- return_to=agent_key
+ parent_task_id=task_id,
)
- logger.info(f"[AgentCmd] {agent_key} fragt Orchestrator (Task #{task_id}): {question.strip()[:50]}")
-
- # CREATE_SUBTASK: Agent möchte Subtask erstellen
- subtask_requests = re.findall(
- r'@CREATE_SUBTASK\s*\nTask:\s*([^\n]+)\s*\nRequirements:\s*(.*?)@END',
- response_text,
- re.DOTALL
- )
- for task_desc, requirements in subtask_requests:
- task_id = create_task(
- title=task_desc.strip()[:100],
- description=f"Von {agent_key} angefordert:\n{requirements.strip()}",
- agent_key='orchestrator',
- task_type='agent_subtask',
- created_by=agent_key,
- from_agent=agent_key
- )
- logger.info(f"[AgentCmd] {agent_key} erstellt Subtask #{task_id} via Orchestrator")
-
- # SUGGEST_AGENT: Agent schlägt neuen Agent vor
- suggest_requests = re.findall(
- r'@SUGGEST_AGENT\s*\nRole:\s*([^\n]+)\s*\nSkills:\s*([^\n]+)\s*\nReason:\s*(.*?)@END',
- response_text,
- re.DOTALL
- )
- for role, skills, reason in suggest_requests:
- # Agent-Key aus Role ableiten
- agent_key_suggestion = role.lower().replace(' ', '_').replace('-', '_')
-
- # Task für Orchestrator um Agent zu erstellen
- task_id = create_task(
- title=f"Agent-Vorschlag: {role.strip()}",
- description=f"""Agent {agent_key} schlägt vor, einen neuen Agent zu erstellen:
+ logger.info(f"[AgentCmd] {agent_key} fragt Orchestrator (Task #{new_id})")
-**Rolle:** {role.strip()}
-**Fähigkeiten:** {skills.strip()}
-**Begründung:** {reason.strip()}
-
-Bitte entscheide ob dieser Agent erstellt werden soll.""",
+ # ── SUGGEST_AGENT ────────────────────────────────────────────────────────
+ for block in re.findall(r'(.*?)', response_text, re.DOTALL | re.IGNORECASE):
+ role = get_field(block, 'role') or block.strip()[:50]
+ skills = get_field(block, 'skills') or ''
+ reason = get_field(block, 'reason') or ''
+ new_id = create_task(
+ title=f"Agent-Vorschlag: {role}",
+ description=f"**Rolle:** {role}\n**Fähigkeiten:** {skills}\n**Begründung:** {reason}",
agent_key='orchestrator',
task_type='agent_suggestion',
created_by=agent_key,
- from_agent=agent_key,
- suggested_agent=agent_key_suggestion,
- suggested_role=role.strip(),
- suggested_skills=skills.strip()
+ parent_task_id=task_id,
)
- logger.info(f"[AgentCmd] {agent_key} schlägt neuen Agent vor (Task #{task_id}): {role.strip()}")
-
- # READ_KNOWLEDGE: Agent möchte Wissensdatenbank durchsuchen
- read_kb_requests = re.findall(
- r'@READ_KNOWLEDGE\s*\nTopic:\s*(.*?)@END',
- response_text,
- re.DOTALL
- )
-
- # Wenn Agent Wissensdatenbank lesen will, füge relevante Sektion zur Antwort hinzu
- # (wird im Response-Text nicht sichtbar, aber Agent bekommt es als Context)
- if read_kb_requests:
- kb_file = os.path.join(os.path.dirname(__file__), 'agents', 'orchestrator', 'knowledge', 'diversityball_knowledge.md')
- if os.path.exists(kb_file):
- with open(kb_file, 'r', encoding='utf-8') as f:
- kb_content = f.read()
-
- for topic in read_kb_requests:
- topic_clean = topic.strip().lower()
- logger.info(f"[AgentCmd] {agent_key} liest Wissensdatenbank: {topic_clean}")
-
- # Einfache Suche: Gib relevante Abschnitte zurück
- # TODO: Könnte später mit Vektorsuche verbessert werden
- relevant_sections = []
- for line in kb_content.split('\n'):
- if topic_clean in line.lower():
- relevant_sections.append(line)
-
- if relevant_sections:
- logger.info(f"[AgentCmd] {len(relevant_sections)} relevante Zeilen gefunden")
-
- # SEND_EMAIL: Orchestrator sendet Email an Team-Member
- send_email_requests = re.findall(
- r'@SEND_EMAIL\s*\nTo:\s*([^\n]+)\s*\nSubject:\s*([^\n]+)\s*\nBody:\s*(.*?)@END',
- response_text,
- re.DOTALL
- )
- for to_addr, subject, body in send_email_requests:
- to_clean = to_addr.strip()
- subject_clean = subject.strip()
- body_clean = body.strip()
+ logger.info(f"[AgentCmd] {agent_key} schlägt Agent vor (Task #{new_id}): {role}")
- action_task_id = create_task(
- title=f"Email an {to_clean}: {subject_clean[:60]}",
- description=f"**An:** {to_clean}\n**Betreff:** {subject_clean}\n\n{body_clean}",
+ # ── SEND_EMAIL ───────────────────────────────────────────────────────────
+ for block in re.findall(r'(.*?)', response_text, re.DOTALL | re.IGNORECASE):
+ to = get_field(block, 'to')
+ subject = get_field(block, 'subject')
+ body = get_field(block, 'body')
+ if not to or not subject:
+ logger.warning("[AgentCmd] ohne to/subject ignoriert")
+ continue
+ action_id = create_task(
+ title=f"Email an {to}: {subject[:60]}",
+ description=f"**An:** {to}\n**Betreff:** {subject}\n\n{body}",
agent_key=agent_key,
task_type='action_email',
created_by=agent_key,
parent_task_id=task_id,
)
- success, message = send_email(to_clean, subject_clean, body_clean,
- triggered_by=f'agent:{agent_key}', task_id=action_task_id)
+ success, msg = send_email(to, subject, body, triggered_by=f'agent:{agent_key}', task_id=action_id)
if success:
- update_task_db(action_task_id, status='completed',
- response=f"✓ Email erfolgreich versendet an {to_clean}")
- logger.info(f"[AgentCmd] Email gesendet an {to_clean}: {subject_clean}")
+ update_task_db(action_id, status='completed', response=f"✓ Email versendet an {to}")
+ logger.info(f"[AgentCmd] Email gesendet an {to}: {subject}")
else:
- update_task_db(action_task_id, status='error', response=f"✗ Fehler: {message}")
- logger.error(f"[AgentCmd] Email-Fehler: {message}")
-
- # SEND_TELEGRAM: Orchestrator sendet Telegram-Nachricht
- # Format: TelegramID: oder Name/Email (wird dann in DB nachgeschlagen)
- send_telegram_requests = re.findall(
- r'@SEND_TELEGRAM\s*\nTelegramID:\s*([^\n]+)\s*\nMessage:\s*(.*?)@END',
- response_text,
- re.DOTALL
- )
- for recipient, message in send_telegram_requests:
- recipient_clean = recipient.strip()
- message_clean = message.strip()
+ update_task_db(action_id, status='error', response=f"✗ {msg}")
+ logger.error(f"[AgentCmd] Email-Fehler: {msg}")
- action_task_id = create_task(
- title=f"Telegram an {recipient_clean}: {message_clean[:60]}",
- description=f"**An:** {recipient_clean}\n\n{message_clean}",
+ # ── SEND_TELEGRAM ────────────────────────────────────────────────────────
+ for block in re.findall(r'(.*?)', response_text, re.DOTALL | re.IGNORECASE):
+ recipient = get_field(block, 'telegram_id') or get_field(block, 'to')
+ message = get_field(block, 'message')
+ if not recipient or not message:
+ logger.warning("[AgentCmd] ohne telegram_id/message ignoriert")
+ continue
+ action_id = create_task(
+ title=f"Telegram an {recipient}: {message[:60]}",
+ description=f"**An:** {recipient}\n\n{message}",
agent_key=agent_key,
task_type='action_telegram',
created_by=agent_key,
parent_task_id=task_id,
)
-
- if TELEGRAM_CONFIG.get('bot_token') and TELEGRAM_CONFIG.get('telegram_bot'):
+ if TELEGRAM_CONFIG.get('bot_token'):
try:
- chat_id = None
- if recipient_clean.lstrip('-').isdigit():
- chat_id = int(recipient_clean)
- else:
+ chat_id = int(recipient) if recipient.lstrip('-').isdigit() else None
+ if not chat_id:
con = sqlite3.connect(EMAIL_JOURNAL_DB)
- result = con.execute(
- "SELECT telegram_id FROM team_members WHERE name = ? OR email = ?",
- (recipient_clean, recipient_clean)
+ row = con.execute(
+ "SELECT telegram_id FROM team_members WHERE name=? OR email=?",
+ (recipient, recipient)
).fetchone()
con.close()
- if result and result[0]:
- chat_id = int(result[0])
-
+ if row and row[0]:
+ chat_id = int(row[0])
if chat_id:
- send_telegram_message(chat_id, message_clean)
- update_task_db(action_task_id, status='completed',
- response=f"✓ Telegram gesendet an {recipient_clean} (chat_id={chat_id})")
- logger.info(f"[AgentCmd] Telegram gesendet an {recipient_clean} (chat_id={chat_id})")
+ send_telegram_message(chat_id, message)
+ update_task_db(action_id, status='completed', response=f"✓ Telegram gesendet (chat_id={chat_id})")
+ logger.info(f"[AgentCmd] Telegram gesendet an {recipient} (chat_id={chat_id})")
else:
- update_task_db(action_task_id, status='error',
- response=f"✗ Keine Telegram-ID für '{recipient_clean}' gefunden")
- logger.warning(f"[AgentCmd] Keine Telegram Chat-ID für '{recipient_clean}'")
+ update_task_db(action_id, status='error', response=f"✗ Keine Telegram-ID für '{recipient}'")
+ logger.warning(f"[AgentCmd] Keine Telegram-ID für '{recipient}'")
except Exception as e:
- update_task_db(action_task_id, status='error', response=f"✗ Fehler: {str(e)}")
- logger.error(f"[AgentCmd] Telegram-Fehler: {str(e)}")
+ update_task_db(action_id, status='error', response=f"✗ {e}")
+ logger.error(f"[AgentCmd] Telegram-Fehler: {e}")
else:
- update_task_db(action_task_id, status='error', response="✗ Telegram nicht konfiguriert")
- logger.warning("[AgentCmd] Telegram nicht konfiguriert")
-
- # ADD_TEAM_MEMBER: Füge neues Team-Mitglied hinzu
- # Format: Name / Role / Responsibilities / Email (Reihenfolge wie im System-Prompt)
- add_member_requests = re.findall(
- r'@ADD_TEAM_MEMBER\s*\nName:\s*([^\n]+)\s*\nRole:\s*([^\n]+)\s*\nResponsibilities:\s*([^\n]+)\s*\nEmail:\s*(.*?)@END',
- response_text,
- re.DOTALL
- )
- for name, role, resp, email in add_member_requests:
- name_clean = name.strip()
- role_clean = role.strip()
- resp_clean = resp.strip()
- email_clean = email.strip()
+ update_task_db(action_id, status='error', response="✗ Telegram nicht konfiguriert")
- action_task_id = create_task(
- title=f"Team-Member hinzugefügt: {name_clean}",
- description=f"**Name:** {name_clean}\n**Rolle:** {role_clean}\n**Email:** {email_clean}\n**Verantwortlichkeiten:** {resp_clean}",
- agent_key=agent_key,
- task_type='action_team',
- created_by=agent_key,
- parent_task_id=task_id,
+ # ── ADD_TEAM_MEMBER ──────────────────────────────────────────────────────
+ for block in re.findall(r'(.*?)', response_text, re.DOTALL | re.IGNORECASE):
+ name = get_field(block, 'name')
+ role = get_field(block, 'role')
+ resp = get_field(block, 'responsibilities')
+ email = get_field(block, 'email')
+ if not name or not role:
+ continue
+ action_id = create_task(
+ title=f"Team-Member hinzugefügt: {name}",
+ description=f"**Name:** {name}\n**Rolle:** {role}\n**Email:** {email}\n**Verantwortlichkeiten:** {resp}",
+ agent_key=agent_key, task_type='action_team', created_by=agent_key, parent_task_id=task_id,
)
- success = add_team_member(name_clean, role_clean, resp_clean, email_clean)
- if success:
- update_task_db(action_task_id, status='completed',
- response=f"✓ Team-Member '{name_clean}' ({role_clean}) hinzugefügt")
- logger.info(f"[AgentCmd] Team-Member hinzugefügt: {name_clean} ({role_clean})")
- else:
- update_task_db(action_task_id, status='error',
- response=f"✗ Konnte '{name_clean}' nicht hinzufügen")
- logger.warning(f"[AgentCmd] Team-Member konnte nicht hinzugefügt werden: {name_clean}")
-
- # UPDATE_TEAM_MEMBER: Aktualisiere Team-Mitglied
- # Format: @UPDATE_TEAM_MEMBER\nIdentifier: \n[Feld: Wert]\n...\n@END
- ALLOWED_UPDATE_FIELDS = {
- 'name': 'name',
- 'role': 'role',
- 'responsibilities': 'responsibilities',
- 'email': 'email',
- 'telegramid': 'telegram_id',
- 'telegram_id': 'telegram_id',
- 'phone': 'phone',
- }
- for block in re.findall(r'@UPDATE_TEAM_MEMBER\s*\n(.*?)@END', response_text, re.DOTALL):
- lines = [l.strip() for l in block.strip().splitlines() if l.strip()]
- identifier = None
+ success = add_team_member(name, role, resp, email)
+ status_msg = f"✓ '{name}' hinzugefügt" if success else f"✗ Fehler beim Hinzufügen von '{name}'"
+ update_task_db(action_id, status='completed' if success else 'error', response=status_msg)
+ logger.info(f"[AgentCmd] {status_msg}")
+
+ # ── UPDATE_TEAM_MEMBER ───────────────────────────────────────────────────
+ ALLOWED_UPDATE_FIELDS = {'name','role','responsibilities','email','telegram_id','telegramid','phone'}
+ for block in re.findall(r'(.*?)', response_text, re.DOTALL | re.IGNORECASE):
+ identifier = get_field(block, 'identifier')
+ if not identifier:
+ continue
kwargs = {}
- for line in lines:
+ for line in block.strip().splitlines():
if ':' not in line:
continue
- key, _, val = line.partition(':')
- key_norm = key.strip().lower().replace(' ', '_')
- val_clean = val.strip()
- if key_norm == 'identifier':
- identifier = val_clean
- elif key_norm in ALLOWED_UPDATE_FIELDS:
- kwargs[ALLOWED_UPDATE_FIELDS[key_norm]] = val_clean
- if not identifier:
- logger.warning("[AgentCmd] @UPDATE_TEAM_MEMBER ohne Identifier ignoriert")
- continue
+ k, _, v = line.partition(':')
+ k_norm = k.strip().lower().replace(' ', '_')
+ if k_norm in ALLOWED_UPDATE_FIELDS and k_norm != 'identifier':
+ db_key = 'telegram_id' if k_norm == 'telegramid' else k_norm
+ kwargs[db_key] = v.strip()
if not kwargs:
- logger.warning(f"[AgentCmd] @UPDATE_TEAM_MEMBER für '{identifier}' ohne Felder ignoriert")
continue
- fields_summary = ", ".join(f"{k}={v}" for k, v in kwargs.items())
- action_task_id = create_task(
+ fields_str = ', '.join(f"{k}={v}" for k, v in kwargs.items())
+ action_id = create_task(
title=f"Team-Member aktualisiert: {identifier}",
- description=f"**Identifier:** {identifier}\n**Felder:** {fields_summary}",
- agent_key=agent_key,
- task_type='action_team',
- created_by=agent_key,
- parent_task_id=task_id,
+ description=f"**Identifier:** {identifier}\n**Felder:** {fields_str}",
+ agent_key=agent_key, task_type='action_team', created_by=agent_key, parent_task_id=task_id,
)
success = update_team_member(identifier, **kwargs)
- if success:
- update_task_db(action_task_id, status='completed',
- response=f"✓ {identifier} aktualisiert: {fields_summary}")
- logger.info(f"[AgentCmd] Team-Member aktualisiert: {identifier} - {list(kwargs.keys())}")
- else:
- update_task_db(action_task_id, status='error',
- response=f"✗ Update fehlgeschlagen für '{identifier}'")
- logger.error(f"[AgentCmd] Update fehlgeschlagen für '{identifier}'")
+ status_msg = f"✓ {identifier} aktualisiert: {fields_str}" if success else f"✗ Update fehlgeschlagen für '{identifier}'"
+ update_task_db(action_id, status='completed' if success else 'error', response=status_msg)
+ logger.info(f"[AgentCmd] {status_msg}")
def create_new_agent(agent_key, role, skills):
"""Erstellt dynamisch einen neuen Agenten."""