From e608a75159fc5cca70485d83ffb8ee681c9da385 Mon Sep 17 00:00:00 2001 From: Ogulcan Celik Date: Fri, 24 Jul 2026 02:49:33 +0300 Subject: fix: make known-agent exit process-owned refs #1792 refs #1648 --- src/integration/assets/hermes/__init__.py | 17 +++++++++-- src/integration/assets/kilo/herdr-agent-state.js | 7 +++-- src/integration/assets/kimi/herdr-agent-state.ps1 | 4 +-- src/integration/assets/kimi/herdr-agent-state.sh | 3 +- .../assets/mastracode/herdr-agent-state.sh | 12 +++++--- src/integration/assets/omp/herdr-agent-state.ts | 35 +++------------------- src/integration/assets/pi/herdr-agent-state.ts | 34 +-------------------- 7 files changed, 37 insertions(+), 75 deletions(-) (limited to 'src/integration/assets') diff --git a/src/integration/assets/hermes/__init__.py b/src/integration/assets/hermes/__init__.py index e6f6971d..5474e5e3 100644 --- a/src/integration/assets/hermes/__init__.py +++ b/src/integration/assets/hermes/__init__.py @@ -1,7 +1,7 @@ """Hermes plugin installed by Herdr to report agent lifecycle state.""" # HERDR_INTEGRATION_ID=hermes -# HERDR_INTEGRATION_VERSION=3 +# HERDR_INTEGRATION_VERSION=4 from __future__ import annotations @@ -71,6 +71,19 @@ def _report(state: str, **kwargs) -> None: _send("pane.report_agent", params) +def _session_started(**kwargs) -> None: + session_id = _session_id(kwargs) + if session_id: + _send( + "pane.report_agent_session", + { + "agent_session_id": session_id, + "session_start_source": "startup", + }, + ) + _idle(**kwargs) + + def _working(**kwargs) -> None: _report("working", **kwargs) @@ -84,7 +97,7 @@ def _idle(**kwargs) -> None: def register(ctx): - ctx.register_hook("on_session_start", _idle) + ctx.register_hook("on_session_start", _session_started) ctx.register_hook("pre_llm_call", _working) ctx.register_hook("pre_api_request", _working) ctx.register_hook("pre_tool_call", _working) diff --git a/src/integration/assets/kilo/herdr-agent-state.js b/src/integration/assets/kilo/herdr-agent-state.js index e8600ab1..8071670c 100644 --- a/src/integration/assets/kilo/herdr-agent-state.js +++ b/src/integration/assets/kilo/herdr-agent-state.js @@ -2,7 +2,7 @@ // managed by herdr; reinstalling or updating the integration overwrites this file. // add custom hooks/plugins beside this file instead of editing it. // HERDR_INTEGRATION_ID=kilo -// HERDR_INTEGRATION_VERSION=3 +// HERDR_INTEGRATION_VERSION=4 import net from "node:net"; @@ -88,7 +88,10 @@ function reportSession(sessionID) { if (!sessionID) { return Promise.resolve(); } - return request("pane.report_agent_session", { agent_session_id: sessionID }); + return request("pane.report_agent_session", { + agent_session_id: sessionID, + session_start_source: "startup", + }); } function reportState(state, sessionID) { diff --git a/src/integration/assets/kimi/herdr-agent-state.ps1 b/src/integration/assets/kimi/herdr-agent-state.ps1 index 16c9eb4d..c298dda4 100644 --- a/src/integration/assets/kimi/herdr-agent-state.ps1 +++ b/src/integration/assets/kimi/herdr-agent-state.ps1 @@ -2,7 +2,7 @@ # managed by herdr; reinstalling or updating the integration overwrites this file. # add custom hooks beside this file instead of editing it. # HERDR_INTEGRATION_ID=kimi -# HERDR_INTEGRATION_VERSION=5 +# HERDR_INTEGRATION_VERSION=6 param([string]$Action = "") @@ -23,7 +23,7 @@ $sessionId = if ($null -ne $payload -and -not [string]::IsNullOrWhiteSpace($payl try { if ($Action -eq "session") { if ([string]::IsNullOrWhiteSpace($sessionId)) { exit 0 } - & herdr pane report-agent-session $env:HERDR_PANE_ID --source herdr:kimi --agent kimi --agent-session-id $sessionId --seq $seq 2>$null | Out-Null + & herdr pane report-agent-session $env:HERDR_PANE_ID --source herdr:kimi --agent kimi --agent-session-id $sessionId --session-start-source startup --seq $seq 2>$null | Out-Null } else { if ([string]::IsNullOrWhiteSpace($sessionId)) { & herdr pane report-agent $env:HERDR_PANE_ID --source herdr:kimi --agent kimi --state $Action --seq $seq 2>$null | Out-Null diff --git a/src/integration/assets/kimi/herdr-agent-state.sh b/src/integration/assets/kimi/herdr-agent-state.sh index 7dac1b49..e919300f 100644 --- a/src/integration/assets/kimi/herdr-agent-state.sh +++ b/src/integration/assets/kimi/herdr-agent-state.sh @@ -1,7 +1,7 @@ #!/bin/sh # managed by herdr; reinstalling the integration replaces this file. # HERDR_INTEGRATION_ID=kimi -# HERDR_INTEGRATION_VERSION=5 +# HERDR_INTEGRATION_VERSION=6 action="${1:-}" case "$action" in @@ -42,6 +42,7 @@ if action == "session": if session_id is None: raise SystemExit(0) method = "pane.report_agent_session" + params["session_start_source"] = "startup" else: method = "pane.report_agent" params["state"] = action diff --git a/src/integration/assets/mastracode/herdr-agent-state.sh b/src/integration/assets/mastracode/herdr-agent-state.sh index b8e0a26a..39a8461b 100644 --- a/src/integration/assets/mastracode/herdr-agent-state.sh +++ b/src/integration/assets/mastracode/herdr-agent-state.sh @@ -3,7 +3,7 @@ # managed by herdr; reinstalling or updating the integration overwrites this file. # add custom hooks beside this file instead of editing it. # HERDR_INTEGRATION_ID=mastracode -# HERDR_INTEGRATION_VERSION=1 +# HERDR_INTEGRATION_VERSION=2 set -eu @@ -13,7 +13,7 @@ trap 'rm -f "$hook_input_file"' EXIT HUP INT TERM cat >"$hook_input_file" 2>/dev/null || true case "$action" in - working|idle|blocked|release) ;; + session|working|idle|blocked) ;; *) exit 0 ;; esac @@ -55,14 +55,18 @@ if isinstance(session_id, str) and session_id: agent_session_id = session_id else: agent_session_id = None -if action == "release": +if action == "session": + if not agent_session_id: + raise SystemExit(0) request = { "id": request_id, - "method": "pane.release_agent", + "method": "pane.report_agent_session", "params": { "pane_id": pane_id, "source": source, "agent": "mastracode", + "agent_session_id": agent_session_id, + "session_start_source": "startup", "seq": report_seq, }, } diff --git a/src/integration/assets/omp/herdr-agent-state.ts b/src/integration/assets/omp/herdr-agent-state.ts index 350cdea7..b3f88c93 100644 --- a/src/integration/assets/omp/herdr-agent-state.ts +++ b/src/integration/assets/omp/herdr-agent-state.ts @@ -2,7 +2,7 @@ // managed by herdr; reinstalling or updating the integration overwrites this file. // add custom hooks/plugins beside this file instead of editing it. // HERDR_INTEGRATION_ID=omp -// HERDR_INTEGRATION_VERSION=6 +// HERDR_INTEGRATION_VERSION=7 // @ts-nocheck import net from "node:net"; @@ -168,29 +168,6 @@ function sendState(state: AgentState, message?: string, seq = nextReportSeq()): }); } -function releaseAgent(): Promise { - return sendRequest({ - id: `${source}:release:${Date.now()}:${Math.random().toString(36).slice(2)}`, - method: "pane.release_agent", - params: { - pane_id: paneId, - source, - agent: "omp", - seq: nextReportSeq(), - }, - }); -} - -function shouldReleaseOnSessionShutdown(event: any): boolean { - // OMP tears down and rebinds extension runtimes for internal lifecycle actions - // such as /reload, /new, /resume, and /fork. Those do not mean the pane's - // agent process has exited, and releasing hook authority there can suppress - // legitimate reports from the replacement runtime. Only a user/process quit - // should release Herdr's full-lifecycle authority. - const reason = event?.reason; - return reason === "quit"; -} - let sendInFlight = false; let queuedState: QueuedState | undefined; @@ -470,13 +447,9 @@ export default function (pi) { scheduleIdle(); }); - pi.on("session_shutdown", async (event) => { - if (!rootSession) { - return; - } - clearPendingTimers(); - if (shouldReleaseOnSessionShutdown(event)) { - await releaseAgent(); + pi.on("session_shutdown", () => { + if (rootSession) { + clearPendingTimers(); } }); } diff --git a/src/integration/assets/pi/herdr-agent-state.ts b/src/integration/assets/pi/herdr-agent-state.ts index caa50ed9..2e79c7c6 100644 --- a/src/integration/assets/pi/herdr-agent-state.ts +++ b/src/integration/assets/pi/herdr-agent-state.ts @@ -2,7 +2,7 @@ // managed by herdr; reinstalling or updating the integration overwrites this file. // add custom hooks/plugins beside this file instead of editing it. // HERDR_INTEGRATION_ID=pi -// HERDR_INTEGRATION_VERSION=6 +// HERDR_INTEGRATION_VERSION=7 // @ts-nocheck import net from "node:net"; @@ -142,29 +142,6 @@ function sendState(state: AgentState, message?: string, seq = nextReportSeq()): }); } -function releaseAgent(): Promise { - return sendRequest({ - id: `${source}:release:${Date.now()}:${Math.random().toString(36).slice(2)}`, - method: "pane.release_agent", - params: { - pane_id: paneId, - source, - agent: "pi", - seq: nextReportSeq(), - }, - }); -} - -function shouldReleaseOnSessionShutdown(event: any): boolean { - // Pi tears down and rebinds extension runtimes for internal lifecycle actions - // such as /reload, /new, /resume, and /fork. Those do not mean the pane's - // agent process has exited, and releasing hook authority there can suppress - // legitimate reports from the replacement runtime. Only a user/process quit - // should release Herdr's full-lifecycle authority. - const reason = event?.reason; - return reason === "quit"; -} - let sendInFlight = false; let queuedState: QueuedState | undefined; @@ -275,13 +252,4 @@ export default function (pi) { agentActive = false; publishState(); }); - - pi.on("session_shutdown", async (event) => { - if (!rootSession) { - return; - } - if (shouldReleaseOnSessionShutdown(event)) { - await releaseAgent(); - } - }); } -- cgit v1.2.3