feat/guard: watch_subagents Custom-Tool — proaktiver 30s-Watcher ohne externen Prozess
pi.registerTool('watch_subagents'): wartet 30s (respektiert AbortSignal),
gibt dann tmux-Status aller Sessions zurück. AGENTS.md: Orchestrator MUSS
das Tool nach jedem Return sofort neu aufrufen — permanente Polling-Schleife.
Kein SubConfirm, kein tmux send-keys, kein externer Prozess nötig.
This commit is contained in:
parent
8de9502f1c
commit
5057f500a0
2 changed files with 45 additions and 7 deletions
|
|
@ -52,13 +52,10 @@ 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:**
|
7. **`watch_subagents` sofort aufrufen** — das ist der permanente Subagenten-Watcher.
|
||||||
```bash
|
Das Tool wartet 30 Sekunden, gibt dann den Status aller tmux-Sessions zurück.
|
||||||
_ME=$(tmux display-message -p '#S')
|
**Nach dem Return SOFORT wieder aufrufen** — immer und ohne Ausnahme.
|
||||||
SubConfirm --orchestrator "$_ME" --skip "$_ME" &
|
Das ist die Polling-Schleife. Sie stoppt nie während die Session läuft.
|
||||||
```
|
|
||||||
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.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
||||||
import { isToolCallEventType } from "@earendil-works/pi-coding-agent";
|
import { isToolCallEventType } from "@earendil-works/pi-coding-agent";
|
||||||
|
import { Type } from "typebox";
|
||||||
import { execSync } from "node:child_process";
|
import { execSync } from "node:child_process";
|
||||||
import { readFileSync, writeFileSync, existsSync } from "node:fs";
|
import { readFileSync, writeFileSync, existsSync } from "node:fs";
|
||||||
|
|
||||||
|
|
@ -205,6 +206,46 @@ function tmuxSubagentenStatus(): string | null {
|
||||||
export default function (pi: ExtensionAPI) {
|
export default function (pi: ExtensionAPI) {
|
||||||
if (!ORCHESTRATOR_AKTIV) return;
|
if (!ORCHESTRATOR_AKTIV) return;
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
// watch_subagents — Proaktiver 30s-Watcher
|
||||||
|
//
|
||||||
|
// Wartet 30 Sekunden, dann gibt es den aktuellen Status aller tmux-Sessions
|
||||||
|
// zurück. Der Orchestrator MUSS dieses Tool sofort nach dem Return neu
|
||||||
|
// aufrufen — so entsteht eine permanente 30s-Polling-Schleife ohne externen
|
||||||
|
// Prozess. AbortSignal wird respektiert: bei Nutzer-Input endet der Sleep
|
||||||
|
// sofort und der Status wird sofort zurückgegeben.
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
pi.registerTool({
|
||||||
|
name: "watch_subagents",
|
||||||
|
label: "Subagenten-Watcher (30s)",
|
||||||
|
description:
|
||||||
|
"Wartet 30 Sekunden und prüft dann alle Subagenten-Sessions. " +
|
||||||
|
"PFLICHT: Nach dem Return sofort wieder aufrufen. " +
|
||||||
|
"Nur im Orchestrator aktiv. Nutzer-Input unterbricht den Sleep sofort.",
|
||||||
|
parameters: Type.Object({}),
|
||||||
|
execute: async (_toolCallId, _params, signal, _onUpdate, _ctx) => {
|
||||||
|
await new Promise<void>((resolve) => {
|
||||||
|
const timer = setTimeout(resolve, 30_000);
|
||||||
|
signal?.addEventListener("abort", () => {
|
||||||
|
clearTimeout(timer);
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const status = tmuxSubagentenStatus();
|
||||||
|
const alerts = leseSubWatcherAlerts();
|
||||||
|
const parts = ["⏱️ [watch_subagents] 30s-Check:"];
|
||||||
|
if (status) parts.push(status);
|
||||||
|
if (alerts) parts.push(alerts);
|
||||||
|
if (!status && !alerts) parts.push("Alle Sessions aktiv, kein Handlungsbedarf.");
|
||||||
|
|
||||||
|
return {
|
||||||
|
content: [{ type: "text" as const, text: parts.join("\n\n") }],
|
||||||
|
details: {},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
pi.on("tool_call", async (event, ctx) => {
|
pi.on("tool_call", async (event, ctx) => {
|
||||||
let grund: string | null = null;
|
let grund: string | null = null;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue