@posthog/agent 2.1.82 → 2.1.83

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.82",
3
+ "version": "2.1.83",
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": {
@@ -170,16 +170,17 @@ function createClaudeConnection(config: AcpConnectionConfig): AcpConnection {
170
170
  });
171
171
  }
172
172
 
173
+ const taskRunId = config.taskRunId;
173
174
  agentWritable = createTappedWritableStream(streams.agent.writable, {
174
175
  onMessage: (line) => {
175
- logWriter.appendRawLine(config.taskRunId!, line);
176
+ logWriter.appendRawLine(taskRunId, line);
176
177
  },
177
178
  logger,
178
179
  });
179
180
 
180
181
  clientWritable = createTappedWritableStream(streams.client.writable, {
181
182
  onMessage: (line) => {
182
- logWriter.appendRawLine(config.taskRunId!, line);
183
+ logWriter.appendRawLine(taskRunId, line);
183
184
  },
184
185
  logger,
185
186
  });
@@ -425,8 +426,8 @@ function createCodexConnection(config: AcpConnectionConfig): AcpConnection {
425
426
 
426
427
  const shouldTapLogs = config.taskRunId && logWriter;
427
428
 
428
- if (shouldTapLogs) {
429
- const taskRunId = config.taskRunId!;
429
+ if (shouldTapLogs && config.taskRunId) {
430
+ const taskRunId = config.taskRunId;
430
431
  if (!logWriter.isRegistered(taskRunId)) {
431
432
  logWriter.register(taskRunId, {
432
433
  taskId: config.taskId ?? taskRunId,
@@ -181,7 +181,7 @@ export class ClaudeAcpAgent extends BaseAcpAgent {
181
181
 
182
182
  if (meta?.taskRunId) {
183
183
  await this.client.extNotification("_posthog/sdk_session", {
184
- taskRunId: meta.taskRunId!,
184
+ taskRunId: meta.taskRunId,
185
185
  sessionId,
186
186
  adapter: "claude",
187
187
  });
@@ -5,7 +5,10 @@ import type {
5
5
  } from "@agentclientprotocol/sdk";
6
6
  import { RequestError } from "@agentclientprotocol/sdk";
7
7
  import type {
8
+ SDKAssistantMessage,
9
+ SDKMessage,
8
10
  SDKPartialAssistantMessage,
11
+ SDKResultMessage,
9
12
  SDKUserMessage,
10
13
  } from "@anthropic-ai/claude-agent-sdk";
11
14
  import type { ContentBlockParam } from "@anthropic-ai/sdk/resources";
@@ -357,7 +360,7 @@ function streamEventToAcpNotifications(
357
360
  }
358
361
 
359
362
  export async function handleSystemMessage(
360
- message: any,
363
+ message: Extract<SDKMessage, { type: "system" }>,
361
364
  context: MessageHandlerContext,
362
365
  ): Promise<void> {
363
366
  const { sessionId, client, logger } = context;
@@ -409,7 +412,7 @@ export async function handleSystemMessage(
409
412
  }
410
413
 
411
414
  export function handleResultMessage(
412
- message: any,
415
+ message: SDKResultMessage,
413
416
  context: MessageHandlerContext,
414
417
  ): { shouldStop: boolean; stopReason?: string; error?: Error } {
415
418
  const { session } = context;
@@ -556,7 +559,7 @@ function filterMessageContent(
556
559
  }
557
560
 
558
561
  export async function handleUserAssistantMessage(
559
- message: SDKUserMessage | { type: "assistant"; message: any },
562
+ message: SDKUserMessage | SDKAssistantMessage,
560
563
  context: MessageHandlerContext,
561
564
  ): Promise<{ shouldStop?: boolean; error?: Error }> {
562
565
  const { session, sessionId, client, toolUseCache, fileContentCache, logger } =
@@ -1,4 +1,7 @@
1
- import type { McpServerConfig } from "@anthropic-ai/claude-agent-sdk";
1
+ import type {
2
+ McpHttpServerConfig,
3
+ McpServerConfig,
4
+ } from "@anthropic-ai/claude-agent-sdk";
2
5
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
3
6
  import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
4
7
  import type { Tool } from "@modelcontextprotocol/sdk/types.js";
@@ -16,17 +19,17 @@ function buildToolKey(serverName: string, toolName: string): string {
16
19
 
17
20
  function isHttpMcpServer(
18
21
  config: McpServerConfig,
19
- ): config is McpServerConfig & { type: "http"; url: string } {
20
- return config.type === "http" && typeof (config as any).url === "string";
22
+ ): config is McpHttpServerConfig {
23
+ return config.type === "http" && typeof config.url === "string";
21
24
  }
22
25
 
23
26
  async function fetchToolsFromHttpServer(
24
27
  _serverName: string,
25
- config: McpServerConfig & { type: "http"; url: string },
28
+ config: McpHttpServerConfig,
26
29
  ): Promise<Tool[]> {
27
30
  const transport = new StreamableHTTPClientTransport(new URL(config.url), {
28
31
  requestInit: {
29
- headers: (config as any).headers || {},
32
+ headers: config.headers ?? {},
30
33
  },
31
34
  });
32
35
 
@@ -192,7 +192,7 @@ async function applyPlanApproval(
192
192
  async function handleEnterPlanModeTool(
193
193
  context: ToolHandlerContext,
194
194
  ): Promise<ToolPermissionResult> {
195
- const { session, toolInput, logger } = context;
195
+ const { session, toolInput } = context;
196
196
 
197
197
  session.permissionMode = "plan";
198
198
  await session.query.setPermissionMode("plan");
@@ -152,9 +152,15 @@ function buildSpawnWrapper(
152
152
  });
153
153
  }
154
154
 
155
+ if (!child.stdin || !child.stdout) {
156
+ throw new Error(
157
+ `Failed to get stdio streams for spawned process (pid=${child.pid})`,
158
+ );
159
+ }
160
+
155
161
  return {
156
- stdin: child.stdin!,
157
- stdout: child.stdout!,
162
+ stdin: child.stdin,
163
+ stdout: child.stdout,
158
164
  get killed() {
159
165
  return child.killed;
160
166
  },
@@ -164,12 +170,15 @@ function buildSpawnWrapper(
164
170
  kill(signal: NodeJS.Signals) {
165
171
  return child.kill(signal);
166
172
  },
173
+ // biome-ignore lint/suspicious/noExplicitAny: ChildProcess event listener types require any[]
167
174
  on(event: "exit" | "error", listener: (...args: any[]) => void) {
168
175
  child.on(event, listener);
169
176
  },
177
+ // biome-ignore lint/suspicious/noExplicitAny: ChildProcess event listener types require any[]
170
178
  once(event: "exit" | "error", listener: (...args: any[]) => void) {
171
179
  child.once(event, listener);
172
180
  },
181
+ // biome-ignore lint/suspicious/noExplicitAny: ChildProcess event listener types require any[]
173
182
  off(event: "exit" | "error", listener: (...args: any[]) => void) {
174
183
  child.off(event, listener);
175
184
  },
package/src/agent.ts CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  DEFAULT_GATEWAY_MODEL,
8
8
  fetchArrayModels,
9
9
  } from "./gateway-models.js";
10
- import { PostHogAPIClient } from "./posthog-api.js";
10
+ import { PostHogAPIClient, type TaskRunUpdate } from "./posthog-api.js";
11
11
  import { SessionLogWriter } from "./session-log-writer.js";
12
12
  import type { AgentConfig, TaskExecutionOptions } from "./types.js";
13
13
  import { Logger } from "./utils/logger.js";
@@ -142,7 +142,7 @@ export class Agent {
142
142
  throw error;
143
143
  }
144
144
 
145
- const updates: any = {
145
+ const updates: TaskRunUpdate = {
146
146
  output: { pr_url: prUrl },
147
147
  };
148
148
  if (branchName) {
@@ -33,27 +33,30 @@ export class ApplySnapshotSaga extends Saga<
33
33
  throw new Error("Cannot apply snapshot: no archive URL");
34
34
  }
35
35
 
36
+ const archiveUrl = snapshot.archiveUrl;
37
+
36
38
  await this.step({
37
39
  name: "create_tmp_dir",
38
40
  execute: () => mkdir(tmpDir, { recursive: true }),
39
41
  rollback: async () => {},
40
42
  });
41
43
 
42
- this.archivePath = join(tmpDir, `${snapshot.treeHash}.tar.gz`);
44
+ const archivePath = join(tmpDir, `${snapshot.treeHash}.tar.gz`);
45
+ this.archivePath = archivePath;
43
46
  await this.step({
44
47
  name: "download_archive",
45
48
  execute: async () => {
46
49
  const arrayBuffer = await apiClient.downloadArtifact(
47
50
  taskId,
48
51
  runId,
49
- snapshot.archiveUrl!,
52
+ archiveUrl,
50
53
  );
51
54
  if (!arrayBuffer) {
52
55
  throw new Error("Failed to download archive");
53
56
  }
54
57
  const base64Content = Buffer.from(arrayBuffer).toString("utf-8");
55
58
  const binaryContent = Buffer.from(base64Content, "base64");
56
- await writeFile(this.archivePath!, binaryContent);
59
+ await writeFile(archivePath, binaryContent);
57
60
  },
58
61
  rollback: async () => {
59
62
  if (this.archivePath) {
@@ -583,7 +583,7 @@ describe("CaptureTreeSaga", () => {
583
583
  });
584
584
 
585
585
  it("handles symlinks", async () => {
586
- const { symlink, lstat } = await import("node:fs/promises");
586
+ const { symlink } = await import("node:fs/promises");
587
587
 
588
588
  await repo.writeFile("target.txt", "symlink target content");
589
589
  await symlink("target.txt", join(repo.path, "link.txt"));