@posthog/agent 2.3.256 → 2.3.259

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/dist/types.d.ts CHANGED
@@ -84,6 +84,8 @@ interface TaskExecutionOptions {
84
84
  codexBinaryPath?: string;
85
85
  instructions?: string;
86
86
  processCallbacks?: ProcessSpawnedCallback;
87
+ /** Callback invoked when the agent calls the create_output tool for structured output */
88
+ onStructuredOutput?: (output: Record<string, unknown>) => Promise<void>;
87
89
  }
88
90
  type LogLevel = "debug" | "info" | "warn" | "error";
89
91
  type OnLogCallback = (level: LogLevel, scope: string, message: string, data?: unknown) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@posthog/agent",
3
- "version": "2.3.256",
3
+ "version": "2.3.259",
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": {
@@ -87,6 +87,7 @@
87
87
  },
88
88
  "dependencies": {
89
89
  "@agentclientprotocol/sdk": "0.16.1",
90
+ "ajv": "^8.17.1",
90
91
  "@anthropic-ai/claude-agent-sdk": "0.2.76",
91
92
  "@anthropic-ai/sdk": "^0.78.0",
92
93
  "@hono/node-server": "^1.19.9",
@@ -24,6 +24,8 @@ export type AcpConnectionConfig = {
24
24
  processCallbacks?: ProcessSpawnedCallback;
25
25
  codexOptions?: CodexProcessOptions;
26
26
  allowedModelIds?: Set<string>;
27
+ /** Callback invoked when the agent calls the create_output tool for structured output */
28
+ onStructuredOutput?: (output: Record<string, unknown>) => Promise<void>;
27
29
  };
28
30
 
29
31
  export type AcpConnection = {
@@ -97,7 +99,10 @@ function createClaudeConnection(config: AcpConnectionConfig): AcpConnection {
97
99
 
98
100
  let agent: ClaudeAcpAgent | null = null;
99
101
  const agentConnection = new AgentSideConnection((client) => {
100
- agent = new ClaudeAcpAgent(client, config.processCallbacks);
102
+ agent = new ClaudeAcpAgent(client, {
103
+ ...config.processCallbacks,
104
+ onStructuredOutput: config.onStructuredOutput,
105
+ });
101
106
  logger.info(`Created ${agent.adapterName} agent`);
102
107
  return agent;
103
108
  }, agentStream);
@@ -109,6 +109,7 @@ export interface ClaudeAcpAgentOptions {
109
109
  onProcessSpawned?: (info: ProcessSpawnedInfo) => void;
110
110
  onProcessExited?: (pid: number) => void;
111
111
  onMcpServersReady?: (serverNames: string[]) => void;
112
+ onStructuredOutput?: (output: Record<string, unknown>) => Promise<void>;
112
113
  }
113
114
 
114
115
  export class ClaudeAcpAgent extends BaseAcpAgent {
@@ -483,6 +484,17 @@ export class ClaudeAcpAgent extends BaseAcpAgent {
483
484
  const result = handleResultMessage(message);
484
485
  if (result.error) throw result.error;
485
486
 
487
+ // Deliver structured output from SDK's native outputFormat
488
+ if (
489
+ message.subtype === "success" &&
490
+ message.structured_output != null &&
491
+ this.options?.onStructuredOutput
492
+ ) {
493
+ await this.options.onStructuredOutput(
494
+ message.structured_output as Record<string, unknown>,
495
+ );
496
+ }
497
+
486
498
  // For local-only commands, forward the result text to the client
487
499
  if (
488
500
  isLocalOnlyCommand &&
@@ -825,6 +837,12 @@ export class ClaudeAcpAgent extends BaseAcpAgent {
825
837
  : {};
826
838
  const systemPrompt = buildSystemPrompt(meta?.systemPrompt);
827
839
 
840
+ // Configure structured output via SDK's native outputFormat
841
+ const outputFormat =
842
+ meta?.jsonSchema && this.options?.onStructuredOutput
843
+ ? { type: "json_schema" as const, schema: meta.jsonSchema }
844
+ : undefined;
845
+
828
846
  this.logger.info(isResume ? "Resuming session" : "Creating new session", {
829
847
  sessionId,
830
848
  taskId,
@@ -854,6 +872,7 @@ export class ClaudeAcpAgent extends BaseAcpAgent {
854
872
  ...(meta?.additionalRoots ?? []),
855
873
  ],
856
874
  disableBuiltInTools: meta?.disableBuiltInTools,
875
+ outputFormat,
857
876
  settingsManager,
858
877
  onModeChange: this.createOnModeChange(),
859
878
  onProcessSpawned: this.options?.onProcessSpawned,
@@ -6,6 +6,7 @@ import type {
6
6
  CanUseTool,
7
7
  McpServerConfig,
8
8
  Options,
9
+ OutputFormat,
9
10
  SpawnedProcess,
10
11
  SpawnOptions,
11
12
  } from "@anthropic-ai/claude-agent-sdk";
@@ -42,6 +43,7 @@ export interface BuildOptionsParams {
42
43
  forkSession?: boolean;
43
44
  additionalDirectories?: string[];
44
45
  disableBuiltInTools?: boolean;
46
+ outputFormat?: OutputFormat;
45
47
  settingsManager: SettingsManager;
46
48
  onModeChange?: OnModeChange;
47
49
  onProcessSpawned?: (info: ProcessSpawnedInfo) => void;
@@ -268,6 +270,7 @@ export function buildSessionOptions(params: BuildOptionsParams): Options {
268
270
  params.settingsManager,
269
271
  params.logger,
270
272
  ),
273
+ outputFormat: params.outputFormat,
271
274
  abortController: getAbortController(
272
275
  params.userProvidedOptions?.abortController,
273
276
  ),
@@ -110,6 +110,7 @@ export type NewSessionMeta = {
110
110
  allowedDomains?: string[];
111
111
  /** Model ID to use for this session (e.g. "claude-sonnet-4-6") */
112
112
  model?: string;
113
+ jsonSchema?: Record<string, unknown> | null;
113
114
  claudeCode?: {
114
115
  options?: Options;
115
116
  };
package/src/agent.ts CHANGED
@@ -122,6 +122,7 @@ export class Agent {
122
122
  deviceType: "local",
123
123
  logger: this.logger,
124
124
  processCallbacks: options.processCallbacks,
125
+ onStructuredOutput: options.onStructuredOutput,
125
126
  allowedModelIds,
126
127
  codexOptions:
127
128
  options.adapter === "codex" && gatewayConfig
@@ -158,6 +158,20 @@ export class PostHogAPIClient {
158
158
  );
159
159
  }
160
160
 
161
+ async setTaskRunOutput(
162
+ taskId: string,
163
+ runId: string,
164
+ output: Record<string, unknown>,
165
+ ): Promise<TaskRun> {
166
+ return this.apiRequest(
167
+ `/api/projects/${this.getTeamId()}/tasks/${taskId}/runs/${runId}/set_output/`,
168
+ {
169
+ method: "PATCH",
170
+ body: JSON.stringify(output),
171
+ },
172
+ );
173
+ }
174
+
161
175
  async appendTaskRunLog(
162
176
  taskId: string,
163
177
  runId: string,
@@ -665,6 +665,15 @@ export class AgentServer {
665
665
  taskId: payload.task_id,
666
666
  deviceType: deviceInfo.type,
667
667
  logWriter,
668
+ onStructuredOutput: async (output) => {
669
+ await this.posthogAPI.setTaskRunOutput(
670
+ payload.task_id,
671
+ payload.run_id,
672
+ {
673
+ output,
674
+ },
675
+ );
676
+ },
668
677
  });
669
678
 
670
679
  // Tap both streams to broadcast all ACP messages via SSE (mimics local transport)
@@ -700,18 +709,25 @@ export class AgentServer {
700
709
  clientCapabilities: {},
701
710
  });
702
711
 
703
- let preTaskRun: TaskRun | null = null;
704
- try {
705
- preTaskRun = await this.posthogAPI.getTaskRun(
706
- payload.task_id,
707
- payload.run_id,
708
- );
709
- } catch {
710
- this.logger.warn("Failed to fetch task run for session context", {
711
- taskId: payload.task_id,
712
- runId: payload.run_id,
713
- });
714
- }
712
+ const [preTaskRun, preTask] = await Promise.all([
713
+ this.posthogAPI
714
+ .getTaskRun(payload.task_id, payload.run_id)
715
+ .catch((err) => {
716
+ this.logger.warn("Failed to fetch task run for session context", {
717
+ taskId: payload.task_id,
718
+ runId: payload.run_id,
719
+ error: err,
720
+ });
721
+ return null;
722
+ }),
723
+ this.posthogAPI.getTask(payload.task_id).catch((err) => {
724
+ this.logger.warn("Failed to fetch task for session context", {
725
+ taskId: payload.task_id,
726
+ error: err,
727
+ });
728
+ return null;
729
+ }),
730
+ ]);
715
731
 
716
732
  const prUrl =
717
733
  typeof (preTaskRun?.state as Record<string, unknown>)
@@ -732,6 +748,7 @@ export class AgentServer {
732
748
  taskRunId: payload.run_id,
733
749
  systemPrompt: this.buildSessionSystemPrompt(prUrl),
734
750
  allowedDomains: this.config.allowedDomains,
751
+ jsonSchema: preTask?.json_schema ?? null,
735
752
  ...(this.config.claudeCode?.plugins?.length && {
736
753
  claudeCode: {
737
754
  options: {
package/src/types.ts CHANGED
@@ -114,6 +114,8 @@ export interface TaskExecutionOptions {
114
114
  codexBinaryPath?: string;
115
115
  instructions?: string;
116
116
  processCallbacks?: ProcessSpawnedCallback;
117
+ /** Callback invoked when the agent calls the create_output tool for structured output */
118
+ onStructuredOutput?: (output: Record<string, unknown>) => Promise<void>;
117
119
  }
118
120
 
119
121
  export type LogLevel = "debug" | "info" | "warn" | "error";