Initial: Mesh-Skills, Configs, Scripts
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
# /usr/local/bin/duo-agent-poller.sh
|
||||
# Sub-Agent Poller: Prüft alle 10s tasks/offen auf eigene (oder "beliebig") Tasks.
|
||||
# Nutzung: duo-agent-poller.sh <MEINE-ZT-IP> <MEINE-AGENT-ID>
|
||||
set -euo pipefail
|
||||
|
||||
TASKS="/srv/work/tasks"
|
||||
MEINE_IP="${1:?Meine ZT-IP fehlt}"
|
||||
MEINE_ID="${2:?Meine Agent-ID fehlt}"
|
||||
|
||||
# Suffix: letzte 2 Oktette der ZT-IP (z.B. 172.24.34.142 -> "34.142" als Präfix)
|
||||
OCT=$(echo "$MEINE_IP" | awk -F. '{print $3"."$4}')
|
||||
|
||||
for f in "$TASKS/offen"/*.json; do
|
||||
[ -f "$f" ] || continue
|
||||
ZIEL=$(python3 -c "import json;print(json.load(open('$f')).get('ziel_agent',''))" 2>/dev/null || echo "")
|
||||
# Nur Tasks für mich oder "beliebig" greifen
|
||||
if [ "$ZIEL" = "$MEINE_ID" ] || [ "$ZIEL" = "beliebig" ]; then
|
||||
# Atomarer Lock: mv/rename gewinnt, konfliktfrei auf NFS.
|
||||
NEW="$TASKS/in_arbeit/${OCT}_$(basename "$f")"
|
||||
if mv "$f" "$NEW" 2>/dev/null; then
|
||||
python3 - "$NEW" "$MEINE_ID" << 'PYEOF'
|
||||
import json, sys, time
|
||||
f, agent = sys.argv[1], sys.argv[2]
|
||||
t = json.load(open(f))
|
||||
t["status"] = "in_arbeit"
|
||||
t["in_arbeit_ts"] = str(int(time.time()))
|
||||
t["bearbeiter"] = agent
|
||||
json.dump(t, open(f, "w"), indent=2)
|
||||
print(f"Uebernommen: {t['task_id']} von {agent}")
|
||||
PYEOF
|
||||
# Bearbeitungslogik ist agentenspezifisch — hier einhängen.
|
||||
fi
|
||||
fi
|
||||
done
|
||||
@@ -0,0 +1,29 @@
|
||||
#!/bin/bash
|
||||
# /usr/local/bin/duo-master-poller.sh
|
||||
# Master (Agent A): Erkennt unerledigte Tasks nach 3 verpassten Polling-Zyklen (30s)
|
||||
# und markiert ziel_agent als "beliebig" (original_ziel_agent bleibt erhalten).
|
||||
# Nur Master darf diesen Ausfall-Fallback triggern.
|
||||
set -euo pipefail
|
||||
|
||||
TASKS="/srv/work/tasks"
|
||||
VERPASST=30 # Sekunden, nach denen ein Task als übersehen gilt (3 Zyklen à 10s)
|
||||
NOW=$(date +%s)
|
||||
|
||||
for f in "$TASKS/offen"/*.json; do
|
||||
[ -f "$f" ] || continue
|
||||
ANLAGE=$(python3 -c "import json;print(json.load(open('$f')).get('anlage_ts',0))" 2>/dev/null || echo 0)
|
||||
AGE=$(( NOW - ANLAGE ))
|
||||
if [ "$AGE" -gt "$VERPASST" ]; then
|
||||
python3 - "$f" << 'PYEOF'
|
||||
import json, sys
|
||||
f = sys.argv[1]
|
||||
t = json.load(open(f))
|
||||
if t["status"] == "offen":
|
||||
t["original_ziel_agent"] = t.get("original_ziel_agent", t["ziel_agent"])
|
||||
t["ziel_agent"] = "beliebig"
|
||||
t["ausfall_umgeleitet"] = True
|
||||
json.dump(t, open(f, "w"), indent=2)
|
||||
print(f"Ausfall-Fallback: {t['task_id']} -> ziel_agent='beliebig' (orig: {t['original_ziel_agent']})")
|
||||
PYEOF
|
||||
fi
|
||||
done
|
||||
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
# /usr/local/bin/duo-task-create.sh
|
||||
# Master (Agent A): Legt Task in tasks/offen/ ab (JSON-Schema nach Blaupause v1).
|
||||
# Nutzung: duo-task-create.sh <ziel_agent-id> <aufgabentyp> <priorität(low|mid|high)> <beschreibung> [budget]
|
||||
set -euo pipefail
|
||||
|
||||
TASKS="/srv/work/tasks"
|
||||
ZIEL="${1:?ziel_agent fehlt (z.B. B, SwitchHermes, LaptopHermes)}"
|
||||
TYP="${2:?aufgabentyp fehlt (z.B. code, html, test, deploy)}"
|
||||
PRIO="${3:-mid}"
|
||||
BESCHREIBUNG="${4:?Beschreibung fehlt}"
|
||||
BUDGET="${5:-1.0}"
|
||||
|
||||
TS=$(date +%s)
|
||||
TASK_ID="T$(date +%Y%m%d)_${TS}"
|
||||
|
||||
cat > "$TASKS/offen/${TASK_ID}.json" << EOF
|
||||
{
|
||||
"task_id": "${TASK_ID}",
|
||||
"ziel_agent": "${ZIEL}",
|
||||
"original_ziel_agent": "${ZIEL}",
|
||||
"aufgabentyp": "${TYP}",
|
||||
"prioritaet": "${PRIO}",
|
||||
"budget_limit_eur": ${BUDGET},
|
||||
"status": "offen",
|
||||
"ergebnis_pfad": null,
|
||||
"beschreibung": "${BESCHREIBUNG}",
|
||||
"anlage_ts": "${TS}",
|
||||
"in_arbeit_ts": null,
|
||||
"fertig_ts": null
|
||||
}
|
||||
EOF
|
||||
|
||||
echo "OK Task $TASK_ID angelegt fuer $ZIEL ($TYP, prio=$PRIO)"
|
||||
@@ -0,0 +1,54 @@
|
||||
#!/bin/bash
|
||||
# Master-Task-Handler: verifiziert & validiert Tasks im Mesh-Share automatisch.
|
||||
# Läuft via Cron: */5 * * * * /path/scripts/master-task-handler.sh
|
||||
# Quelle /srv/work — Status=Ordnermodell (todo/inProgress/finished/bugged/completed)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
WORK="/srv/work"
|
||||
TODO="$WORK/todo"
|
||||
INPROG="$WORK/inProgress"
|
||||
FIN="$WORK/finished"
|
||||
BUG="$WORK/bugged"
|
||||
COMP="$WORK/completed"
|
||||
LOCK_TIMEOUT=15 # Minuten
|
||||
STALE_TIMEOUT=30 # Minuten
|
||||
|
||||
mkdir -p "$TODO" "$INPROG" "$FIN" "$BUG" "$COMP"
|
||||
|
||||
# 1) Verwaiste Locks bereinigen (>15 min)
|
||||
find "$INPROG" -name "*.lock" -mmin +$LOCK_TIMEOUT -delete 2>/dev/null || true
|
||||
|
||||
# 2) Stale Dateien in inProgress (ohne Lock, >30 min) -> zurück nach todo
|
||||
for f in "$INPROG"/*.md "$INPROG"/*.json; do
|
||||
[ -f "$f" ] || continue
|
||||
[ -f "$f.lock" ] && continue
|
||||
if [ "$(find "$f" -mmin +$STALE_TIMEOUT 2>/dev/null | wc -l)" -gt 0 ]; then
|
||||
mv "$f" "$TODO/" 2>/dev/null && echo "[$(date)] stale -> todo: $f"
|
||||
fi
|
||||
done
|
||||
|
||||
# 3) finished/ validieren (Frontmatter + # Ergebnis)
|
||||
for f in "$FIN"/*.md; do
|
||||
[ -f "$f" ] || continue
|
||||
if ! head -20 "$f" | grep -q "^---$" || ! grep -q "^# Ergebnis" "$f"; then
|
||||
mv "$f" "$BUG/" 2>/dev/null && echo "[$(date)] formatfehler -> bugged: $f"
|
||||
continue
|
||||
fi
|
||||
# Optional: Artefakt in completed/ spiegeln
|
||||
# cp "$f" "$COMP/$(basename "$f")"
|
||||
done
|
||||
|
||||
# 4) bugged/ Retry-Buchhaltung (YAML: retries)
|
||||
for f in "$BUG"/*.md; do
|
||||
[ -f "$f" ] || continue
|
||||
retries=$(grep -m1 "^retries:" "$f" 2>/dev/null | awk '{print $2}' || echo 0)
|
||||
retries=${retries:-0}
|
||||
if [ "$retries" -gt 0 ]; then
|
||||
new=$((retries - 1))
|
||||
sed -i "s/^retries: .*/retries: $new/" "$f"
|
||||
mv "$f" "$TODO/" 2>/dev/null && echo "[$(date)] retry($new) -> todo: $f"
|
||||
else
|
||||
echo "[$(date)] bleibt in bugged (retries=0): $f"
|
||||
fi
|
||||
done
|
||||
Reference in New Issue
Block a user