fix/subconfirm: Push-Mechanismus — injiziert Alerts direkt in Orchestrator-Session
SubConfirm schrieb bisher nur in eine Alert-Datei, die der Guard nur beim nächsten Tool-Call liest. Ein idle Orchestrator schlief durch. Neu: --orchestrator <session> Parameter — bei Stasis wird ein Alert- Text via tmux send-keys direkt in die Orchestrator-Session getippt, sofern Pi nicht gerade "Working..." zeigt. AGENTS.md: Start-Befehl mit --orchestrator aktualisiert.
This commit is contained in:
parent
3e4e1a4bff
commit
8de9502f1c
2 changed files with 73 additions and 33 deletions
|
|
@ -52,7 +52,13 @@ Zu Beginn einer komplexen Aufgabe (bevor eigene Lösungen gebaut werden):
|
||||||
|
|
||||||
6. **Arbeitsweise laden:** `~/.pi/agent/memory/arbeitsweise.md` — Orchestrator + SubAgenten-Workflow. Der Orchestrator delegiert alle Arbeiten, SubAgenten speichern Ergebnisse in aufgabenspezifischen Unterverzeichnissen.
|
6. **Arbeitsweise laden:** `~/.pi/agent/memory/arbeitsweise.md` — Orchestrator + SubAgenten-Workflow. Der Orchestrator delegiert alle Arbeiten, SubAgenten speichern Ergebnisse in aufgabenspezifischen Unterverzeichnissen.
|
||||||
|
|
||||||
7. **SubConfirm starten:** `SubConfirm --skip "$(tmux display-message -p '#S')" &` — startet den Stasis-Detektor im Hintergrund. Läuft bereits? `pgrep -f SubConfirm` prüfen, nicht doppelt starten.
|
7. **SubConfirm starten:**
|
||||||
|
```bash
|
||||||
|
_ME=$(tmux display-message -p '#S')
|
||||||
|
SubConfirm --orchestrator "$_ME" --skip "$_ME" &
|
||||||
|
```
|
||||||
|
Startet den Stasis-Detektor. Bei Stasis: schreibt in Alert-Datei UND injiziert direkt in diese Session.
|
||||||
|
Läuft bereits? `pgrep -fa SubConfirm` prüfen — nicht doppelt starten.
|
||||||
|
|
||||||
8. **SubAgent Auto-Check System laden:** `~/.pi/agent/memory/subagent-autocheck.md` — Hintergrundinformation; SubConfirm übernimmt die proaktive Erkennung automatisch.
|
8. **SubAgent Auto-Check System laden:** `~/.pi/agent/memory/subagent-autocheck.md` — Hintergrundinformation; SubConfirm übernimmt die proaktive Erkennung automatisch.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,28 +3,28 @@
|
||||||
#
|
#
|
||||||
# Läuft als Hintergrund-Daemon und prüft alle 30 Sekunden alle tmux-Sessions.
|
# Läuft als Hintergrund-Daemon und prüft alle 30 Sekunden alle tmux-Sessions.
|
||||||
# Wenn eine Session ihren Output seit >30s nicht verändert hat (Stasis),
|
# Wenn eine Session ihren Output seit >30s nicht verändert hat (Stasis),
|
||||||
# wird der vollständige Pane-Inhalt in die Alert-Datei geschrieben.
|
# wird der vollständige Pane-Inhalt in die Alert-Datei geschrieben UND
|
||||||
# Die arbeitsweise-guard.ts Extension zeigt diesen Alert dem Orchestrator
|
# direkt in die Orchestrator-Session injiziert (tmux send-keys).
|
||||||
# beim nächsten Tool-Call — der Orchestrator beurteilt dann selbst ob
|
|
||||||
# Handlung nötig ist.
|
|
||||||
#
|
|
||||||
# KEIN Keyword-Matching — der Orchestrator entscheidet was zu tun ist.
|
|
||||||
#
|
#
|
||||||
# Architektur:
|
# Architektur:
|
||||||
# SubConfirm → /tmp/.pi-subagent-alert → arbeitsweise-guard.ts → Orchestrator
|
# SubConfirm → /tmp/.pi-subagent-alert → arbeitsweise-guard.ts → Orchestrator
|
||||||
|
# SubConfirm → tmux send-keys → Orchestrator-Session (direkter Push)
|
||||||
#
|
#
|
||||||
# Nutzung:
|
# Nutzung:
|
||||||
# SubConfirm & # Im Hintergrund starten
|
# SubConfirm --orchestrator "session-name" & # Mit Push in Orchestrator-Session
|
||||||
# SubConfirm --interval 15 & # Kürzeres Intervall
|
# SubConfirm --interval 15 & # Kürzeres Intervall
|
||||||
# SubConfirm --skip "main-session" & # Session ausschließen (Orchestrator-Session)
|
# SubConfirm --skip "main-session" & # Session ausschließen
|
||||||
# pkill -f SubConfirm # Beenden
|
# pkill -f SubConfirm # Beenden
|
||||||
#
|
#
|
||||||
# Autostart: In AGENTS.md Session-Start-Checkliste eingetragen.
|
# Der --orchestrator und --skip Parameter sind oft gleich:
|
||||||
|
# NAME=$(tmux display-message -p '#S')
|
||||||
|
# SubConfirm --orchestrator "$NAME" --skip "$NAME" &
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
INTERVAL=30
|
INTERVAL=30
|
||||||
SKIP_SESSION=""
|
SKIP_SESSION=""
|
||||||
|
ORCHESTRATOR_SESSION=""
|
||||||
REPORT_COOLDOWN=90 # Sekunden zwischen wiederholten Meldungen zur selben Session
|
REPORT_COOLDOWN=90 # Sekunden zwischen wiederholten Meldungen zur selben Session
|
||||||
ALERT_FILE="/tmp/.pi-subagent-alert"
|
ALERT_FILE="/tmp/.pi-subagent-alert"
|
||||||
STATE_DIR="/tmp/.pi-subconfirm-state"
|
STATE_DIR="/tmp/.pi-subconfirm-state"
|
||||||
|
|
@ -34,6 +34,7 @@ while [[ $# -gt 0 ]]; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
--interval) INTERVAL="$2"; shift 2 ;;
|
--interval) INTERVAL="$2"; shift 2 ;;
|
||||||
--skip) SKIP_SESSION="$2"; shift 2 ;;
|
--skip) SKIP_SESSION="$2"; shift 2 ;;
|
||||||
|
--orchestrator) ORCHESTRATOR_SESSION="$2"; shift 2 ;;
|
||||||
*) shift ;;
|
*) shift ;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
@ -45,16 +46,59 @@ log() {
|
||||||
echo "[SubConfirm $(date '+%H:%M:%S')] $1" >&2
|
echo "[SubConfirm $(date '+%H:%M:%S')] $1" >&2
|
||||||
}
|
}
|
||||||
|
|
||||||
alert() {
|
# Prüft ob Pi im Orchestrator-Terminal gerade auf Eingabe wartet.
|
||||||
local msg="$1"
|
# Pi zeigt am Ende des Pane-Inhalts einen Eingabe-Cursor (leere Zeile oder ">").
|
||||||
# In Alert-Datei schreiben (Guard zeigt das beim nächsten Tool-Call)
|
orchestrator_is_idle() {
|
||||||
echo "$(date '+%H:%M:%S') $msg" >> "$ALERT_FILE"
|
[ -z "$ORCHESTRATOR_SESSION" ] && return 1
|
||||||
# Desktop-Notification als zusätzlicher Hinweis
|
local last
|
||||||
zenity --notification --text="SubConfirm: $msg" 2>/dev/null &
|
last=$(tmux capture-pane -t "$ORCHESTRATOR_SESSION" -p 2>/dev/null \
|
||||||
echo -e "\a" 2>/dev/null || true
|
| sed 's/\x1b\[[0-9;]*[mGKHF]//g' \
|
||||||
|
| grep -v '^[[:space:]]*$' \
|
||||||
|
| tail -3)
|
||||||
|
# Pi ist idle wenn die letzte sichtbare Zeile den Status-Bar zeigt
|
||||||
|
# (kein "Working..." oder Spinner sichtbar)
|
||||||
|
echo "$last" | grep -qE '(Working\.\.\.|⠋|⠙|⠹|⠸|⠼|⠴|⠦|⠧|⠇|⠏)' && return 1
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
log "Gestartet (PID $$, Intervall: ${INTERVAL}s, Skip: '${SKIP_SESSION}')"
|
# Injiziert eine Nachricht in die Orchestrator-Session via tmux send-keys.
|
||||||
|
inject_to_orchestrator() {
|
||||||
|
local msg="$1"
|
||||||
|
[ -z "$ORCHESTRATOR_SESSION" ] && return
|
||||||
|
orchestrator_is_idle || return
|
||||||
|
# Nachricht tippen + Enter → Pi verarbeitet es als User-Input
|
||||||
|
tmux send-keys -t "$ORCHESTRATOR_SESSION" "$msg" Enter 2>/dev/null || true
|
||||||
|
log "Injiziert in Orchestrator-Session: ${msg:0:60}..."
|
||||||
|
}
|
||||||
|
|
||||||
|
alert() {
|
||||||
|
local session="$1"
|
||||||
|
local pane_display="$2"
|
||||||
|
local short_msg="⏸️ SUBAGENT-STASIS [$session] — braucht Eingabe"
|
||||||
|
|
||||||
|
# 1. In Alert-Datei schreiben (Guard zeigt das beim nächsten Tool-Call)
|
||||||
|
cat >> "$ALERT_FILE" <<EOF
|
||||||
|
$(date '+%H:%M:%S') $short_msg
|
||||||
|
|
||||||
|
Pane-Inhalt [$session]:
|
||||||
|
$pane_display
|
||||||
|
|
||||||
|
Mögliche Reaktionen:
|
||||||
|
Bestätigen (Yes): tmux send-keys -t "$session" "" Enter
|
||||||
|
Ablehnen (No): tmux send-keys -t "$session" "Down" && tmux send-keys -t "$session" "" Enter
|
||||||
|
Ignorieren: (nächste Meldung in ${REPORT_COOLDOWN}s)
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# 2. Desktop-Notification
|
||||||
|
zenity --notification --text="SubConfirm: $short_msg" 2>/dev/null &
|
||||||
|
echo -e "\a" 2>/dev/null || true
|
||||||
|
|
||||||
|
# 3. Direkt in Orchestrator-Session injizieren wenn idle
|
||||||
|
inject_to_orchestrator "$short_msg — bitte prüfen und reagieren (tmux capture-pane -t '$session' -p | tail -20)"
|
||||||
|
}
|
||||||
|
|
||||||
|
log "Gestartet (PID $$, Intervall: ${INTERVAL}s, Skip: '${SKIP_SESSION}', Orchestrator: '${ORCHESTRATOR_SESSION}')"
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
sleep "$INTERVAL"
|
sleep "$INTERVAL"
|
||||||
|
|
@ -80,26 +124,16 @@ while true; do
|
||||||
PREV=$(cat "$STATE_FILE" 2>/dev/null || echo "")
|
PREV=$(cat "$STATE_FILE" 2>/dev/null || echo "")
|
||||||
|
|
||||||
if [ "$CURRENT" = "$PREV" ]; then
|
if [ "$CURRENT" = "$PREV" ]; then
|
||||||
# Stasis — Output hat sich nicht verändert seit letztem Check
|
|
||||||
NOW=$(date +%s)
|
NOW=$(date +%s)
|
||||||
LAST_REPORT=$(cat "$REPORT_FILE" 2>/dev/null || echo 0)
|
LAST_REPORT=$(cat "$REPORT_FILE" 2>/dev/null || echo 0)
|
||||||
|
|
||||||
if [ $((NOW - LAST_REPORT)) -gt "$REPORT_COOLDOWN" ]; then
|
if [ $((NOW - LAST_REPORT)) -gt "$REPORT_COOLDOWN" ]; then
|
||||||
PANE_DISPLAY=$(echo "$CURRENT" | tr '§' '\n')
|
PANE_DISPLAY=$(echo "$CURRENT" | tr '§' '\n')
|
||||||
alert "⏸️ SUBAGENT-STASIS [$session] — Output seit >${INTERVAL}s unverändert.
|
alert "$session" "$PANE_DISPLAY"
|
||||||
|
|
||||||
Pane-Inhalt:
|
|
||||||
$PANE_DISPLAY
|
|
||||||
|
|
||||||
Mögliche Reaktionen:
|
|
||||||
Bestätigen (Yes): tmux send-keys -t \"$session\" \"\" Enter
|
|
||||||
Ablehnen (No): tmux send-keys -t \"$session\" \"\" && tmux send-keys -t \"$session\" \"\" Enter
|
|
||||||
Ignorieren: (keine Aktion — nächste Meldung in ${REPORT_COOLDOWN}s wenn noch Stasis)"
|
|
||||||
log "Stasis gemeldet: $session"
|
log "Stasis gemeldet: $session"
|
||||||
echo "$NOW" > "$REPORT_FILE"
|
echo "$NOW" > "$REPORT_FILE"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
# Aktivität — State aktualisieren, Stasis-Zustand zurücksetzen
|
|
||||||
echo "$CURRENT" > "$STATE_FILE"
|
echo "$CURRENT" > "$STATE_FILE"
|
||||||
rm -f "$REPORT_FILE"
|
rm -f "$REPORT_FILE"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue