@posthog/agent 2.3.74 → 2.3.81

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.3.74",
3
+ "version": "2.3.81",
4
4
  "repository": "https://github.com/PostHog/code",
5
5
  "description": "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
6
6
  "exports": {
@@ -66,6 +66,7 @@ import {
66
66
  DEFAULT_MODEL,
67
67
  getEffortOptions,
68
68
  resolveModelPreference,
69
+ supports1MContext,
69
70
  toSdkModelId,
70
71
  } from "./session/models";
71
72
  import {
@@ -817,7 +818,7 @@ export class ClaudeAcpAgent extends BaseAcpAgent {
817
818
  cwd,
818
819
  mcpServers,
819
820
  permissionMode,
820
- canUseTool: this.createCanUseTool(sessionId),
821
+ canUseTool: this.createCanUseTool(sessionId, meta?.allowedDomains),
821
822
  logger: this.logger,
822
823
  systemPrompt,
823
824
  userProvidedOptions: meta?.claudeCode?.options,
@@ -932,6 +933,10 @@ export class ClaudeAcpAgent extends BaseAcpAgent {
932
933
  await this.session.query.setModel(resolvedSdkModel);
933
934
  }
934
935
 
936
+ if (supports1MContext(resolvedModelId)) {
937
+ options.betas = ["context-1m-2025-08-07"];
938
+ }
939
+
935
940
  const availableModes = getAvailableModes();
936
941
  const modes: SessionModeState = {
937
942
  currentModeId: permissionMode,
@@ -978,7 +983,10 @@ export class ClaudeAcpAgent extends BaseAcpAgent {
978
983
  return { sessionId, modes, models, configOptions };
979
984
  }
980
985
 
981
- private createCanUseTool(sessionId: string): CanUseTool {
986
+ private createCanUseTool(
987
+ sessionId: string,
988
+ allowedDomains?: string[],
989
+ ): CanUseTool {
982
990
  return async (toolName, toolInput, { suggestions, toolUseID, signal }) =>
983
991
  canUseTool({
984
992
  session: this.session,
@@ -993,6 +1001,7 @@ export class ClaudeAcpAgent extends BaseAcpAgent {
993
1001
  logger: this.logger,
994
1002
  updateConfigOption: (configId: string, value: string) =>
995
1003
  this.updateConfigOption(configId, value),
1004
+ allowedDomains,
996
1005
  });
997
1006
  }
998
1007
 
@@ -49,6 +49,7 @@ interface ToolHandlerContext {
49
49
  fileContentCache: { [key: string]: string };
50
50
  logger: Logger;
51
51
  updateConfigOption: (configId: string, value: string) => Promise<void>;
52
+ allowedDomains?: string[];
52
53
  }
53
54
 
54
55
  async function emitToolDenial(
@@ -422,10 +423,43 @@ function handlePlanFileException(
422
423
  };
423
424
  }
424
425
 
426
+ function extractDomainFromUrl(url: string): string | null {
427
+ try {
428
+ return new URL(url).hostname;
429
+ } catch {
430
+ return null;
431
+ }
432
+ }
433
+
434
+ function isDomainAllowed(hostname: string, allowedDomains: string[]): boolean {
435
+ return allowedDomains.some((pattern) => {
436
+ if (pattern.startsWith("*.")) {
437
+ const suffix = pattern.slice(1); // ".example.com"
438
+ return hostname === pattern.slice(2) || hostname.endsWith(suffix);
439
+ }
440
+ return hostname === pattern;
441
+ });
442
+ }
443
+
425
444
  export async function canUseTool(
426
445
  context: ToolHandlerContext,
427
446
  ): Promise<ToolPermissionResult> {
428
- const { toolName, toolInput, session } = context;
447
+ const { toolName, toolInput, session, allowedDomains } = context;
448
+
449
+ // Enforce domain allowlist for web tools
450
+ if (allowedDomains && allowedDomains.length > 0) {
451
+ if (toolName === "WebFetch" || toolName === "WebSearch") {
452
+ const url = toolInput.url as string | undefined;
453
+ if (url) {
454
+ const hostname = extractDomainFromUrl(url);
455
+ if (hostname && !isDomainAllowed(hostname, allowedDomains)) {
456
+ const message = `Domain "${hostname}" is not in the allowed list: ${allowedDomains.join(", ")}`;
457
+ await emitToolDenial(context, message);
458
+ return { behavior: "deny", message, interrupt: false };
459
+ }
460
+ }
461
+ }
462
+ }
429
463
 
430
464
  if (isToolAllowedForMode(toolName, session.permissionMode)) {
431
465
  return {
@@ -107,6 +107,7 @@ export type NewSessionMeta = {
107
107
  permissionMode?: string;
108
108
  persistence?: { taskId?: string; runId?: string; logUrl?: string };
109
109
  additionalRoots?: string[];
110
+ allowedDomains?: string[];
110
111
  claudeCode?: {
111
112
  options?: Options;
112
113
  };
@@ -707,6 +707,7 @@ export class AgentServer {
707
707
  sessionId: payload.run_id,
708
708
  taskRunId: payload.run_id,
709
709
  systemPrompt: this.buildSessionSystemPrompt(prUrl),
710
+ allowedDomains: this.config.allowedDomains,
710
711
  ...(this.config.claudeCode?.plugins?.length && {
711
712
  claudeCode: {
712
713
  options: {
package/src/server/bin.ts CHANGED
@@ -79,6 +79,10 @@ program
79
79
  "--claudeCodeConfig <json>",
80
80
  "Claude Code config as JSON (systemPrompt, systemPromptAppend, plugins)",
81
81
  )
82
+ .option(
83
+ "--allowedDomains <domains>",
84
+ "Comma-separated list of domains allowed for web tools (WebFetch, WebSearch)",
85
+ )
82
86
  .action(async (options) => {
83
87
  const envResult = envSchema.safeParse(process.env);
84
88
 
@@ -105,6 +109,13 @@ program
105
109
  "--claudeCodeConfig",
106
110
  );
107
111
 
112
+ const allowedDomains = options.allowedDomains
113
+ ? options.allowedDomains
114
+ .split(",")
115
+ .map((d: string) => d.trim())
116
+ .filter(Boolean)
117
+ : undefined;
118
+
108
119
  const server = new AgentServer({
109
120
  port: parseInt(options.port, 10),
110
121
  jwtPublicKey: env.JWT_PUBLIC_KEY,
@@ -118,6 +129,7 @@ program
118
129
  mcpServers,
119
130
  baseBranch: options.baseBranch,
120
131
  claudeCode,
132
+ allowedDomains,
121
133
  });
122
134
 
123
135
  process.on("SIGINT", async () => {
@@ -22,4 +22,5 @@ export interface AgentServerConfig {
22
22
  mcpServers?: RemoteMcpServer[];
23
23
  baseBranch?: string;
24
24
  claudeCode?: ClaudeCodeConfig;
25
+ allowedDomains?: string[];
25
26
  }