@posthog/agent 2.1.67 → 2.1.69

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@posthog/agent",
3
- "version": "2.1.67",
3
+ "version": "2.1.69",
4
4
  "repository": "https://github.com/PostHog/twig",
5
5
  "description": "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
6
6
  "exports": {
@@ -33,7 +33,7 @@ import { v7 as uuidv7 } from "uuid";
33
33
  import packageJson from "../../../package.json" with { type: "json" };
34
34
  import type { SessionContext } from "../../otel-log-writer.js";
35
35
  import type { SessionLogWriter } from "../../session-log-writer.js";
36
- import { unreachable } from "../../utils/common.js";
36
+ import { unreachable, withTimeout } from "../../utils/common.js";
37
37
  import { Logger } from "../../utils/logger.js";
38
38
  import { Pushable } from "../../utils/streams.js";
39
39
  import { BaseAcpAgent } from "../base-acp-agent.js";
@@ -66,6 +66,8 @@ import type {
66
66
  ToolUseCache,
67
67
  } from "./types.js";
68
68
 
69
+ const SESSION_VALIDATION_TIMEOUT_MS = 10_000;
70
+
69
71
  export interface ClaudeAcpAgentOptions {
70
72
  onProcessSpawned?: (info: ProcessSpawnedInfo) => void;
71
73
  onProcessExited?: (pid: number) => void;
@@ -247,6 +249,16 @@ export class ClaudeAcpAgent extends BaseAcpAgent {
247
249
 
248
250
  this.registerPersistence(sessionId, meta as Record<string, unknown>);
249
251
 
252
+ // Validate the resumed session is alive. For stale sessions this throws
253
+ // (e.g. "No conversation found"), preventing a broken session.
254
+ const validation = await withTimeout(
255
+ q.initializationResult(),
256
+ SESSION_VALIDATION_TIMEOUT_MS,
257
+ );
258
+ if (validation.result === "timeout") {
259
+ throw new Error("Session validation timed out");
260
+ }
261
+
250
262
  // Deferred: slash commands + MCP metadata (not needed to return configOptions)
251
263
  this.deferBackgroundFetches(q, sessionId, mcpServers);
252
264
 
@@ -1,5 +1,24 @@
1
1
  import type { Logger } from "./logger.js";
2
2
 
3
+ /**
4
+ * Races an operation against a timeout.
5
+ * Returns success with the value if the operation completes in time,
6
+ * or timeout if the operation takes longer than the specified duration.
7
+ */
8
+ export async function withTimeout<T>(
9
+ operation: Promise<T>,
10
+ timeoutMs: number,
11
+ ): Promise<{ result: "success"; value: T } | { result: "timeout" }> {
12
+ const timeoutPromise = new Promise<{ result: "timeout" }>((resolve) =>
13
+ setTimeout(() => resolve({ result: "timeout" }), timeoutMs),
14
+ );
15
+ const operationPromise = operation.then((value) => ({
16
+ result: "success" as const,
17
+ value,
18
+ }));
19
+ return Promise.race([operationPromise, timeoutPromise]);
20
+ }
21
+
3
22
  export const IS_ROOT =
4
23
  typeof process !== "undefined" &&
5
24
  (process.geteuid?.() ?? process.getuid?.()) === 0;