aboutsummaryrefslogtreecommitdiff
path: root/src/integration/assets/pi
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-05-23 21:27:26 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-05-23 21:37:05 +0300
commitdb67e9d74ffafc9c63bdf78fcf712419359f634b (patch)
tree9d181b55e65aaf6a2fad2d6cf785bb09a8d9748f /src/integration/assets/pi
parent1bab1d2ce21507747ea1f506fb891fe7cd5a13c9 (diff)
feat: restore agent sessions
refs #233
Diffstat (limited to 'src/integration/assets/pi')
-rw-r--r--src/integration/assets/pi/herdr-agent-state.ts44
1 files changed, 39 insertions, 5 deletions
diff --git a/src/integration/assets/pi/herdr-agent-state.ts b/src/integration/assets/pi/herdr-agent-state.ts
index 26869f1c..450fd48c 100644
--- a/src/integration/assets/pi/herdr-agent-state.ts
+++ b/src/integration/assets/pi/herdr-agent-state.ts
@@ -1,7 +1,7 @@
// installed by herdr
// safe to edit. this integration only activates inside herdr-managed panes.
// HERDR_INTEGRATION_ID=pi
-// HERDR_INTEGRATION_VERSION=1
+// HERDR_INTEGRATION_VERSION=2
// @ts-nocheck
import { createConnection } from "node:net";
@@ -52,6 +52,8 @@ const retryGraceMs = parseDurationEnv("HERDR_PI_RETRY_GRACE_MS", 2500);
const retryableErrorPattern =
/overloaded|provider.?returned.?error|rate.?limit|too many requests|429|500|502|503|504|service.?unavailable|server.?error|internal.?error|network.?error|connection.?error|connection.?refused|connection.?lost|websocket.?closed|websocket.?error|other side closed|fetch failed|upstream.?connect|reset before headers|socket hang up|ended without|http2 request did not get a response|timed? out|timeout|terminated|retry delay/i;
let reportSeq = Date.now() * 1000;
+let currentAgentSessionId: string | undefined;
+let currentAgentSessionPath: string | undefined;
function nextReportSeq(): number {
reportSeq += 1;
@@ -70,18 +72,45 @@ function parseDurationEnv(name: string, fallback: number): number {
return parsed;
}
+function updateSessionRef(ctx: any): void {
+ try {
+ const file = ctx?.sessionManager?.getSessionFile?.();
+ currentAgentSessionPath =
+ typeof file === "string" && file.startsWith("/") ? file : undefined;
+ } catch {
+ currentAgentSessionPath = undefined;
+ }
+
+ try {
+ const id = ctx?.sessionManager?.getSessionId?.();
+ currentAgentSessionId = typeof id === "string" && id.length > 0 ? id : undefined;
+ } catch {
+ currentAgentSessionId = undefined;
+ }
+}
+
+function withSessionRef(params: Record<string, unknown>): Record<string, unknown> {
+ if (currentAgentSessionPath) {
+ return { ...params, agent_session_path: currentAgentSessionPath };
+ }
+ if (currentAgentSessionId) {
+ return { ...params, agent_session_id: currentAgentSessionId };
+ }
+ return params;
+}
+
function sendState(state: AgentState, message?: string, seq = nextReportSeq()): Promise<void> {
return sendRequest({
id: `${source}:${Date.now()}:${Math.random().toString(36).slice(2)}`,
method: "pane.report_agent",
- params: {
+ params: withSessionRef({
pane_id: paneId,
source,
agent: "pi",
state,
message,
seq,
- },
+ }),
});
}
@@ -200,9 +229,9 @@ export default function (pi) {
return { state: "idle" as const, message: undefined };
}
- function publishState() {
+ function publishState(force = false) {
const next = desiredState();
- if (next.state === lastState && next.message === lastMessage) {
+ if (!force && next.state === lastState && next.message === lastMessage) {
return;
}
lastState = next.state;
@@ -220,6 +249,11 @@ export default function (pi) {
idleTimer.unref?.();
}
+ pi.on("session_start", (_event, ctx) => {
+ updateSessionRef(ctx);
+ publishState(true);
+ });
+
function holdForRetry(message: string) {
clearPendingTimers();
retryHoldActive = true;