@posthog/agent 1.7.1 → 1.9.0

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.
Files changed (48) hide show
  1. package/dist/index.d.ts +4 -0
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +2 -0
  4. package/dist/index.js.map +1 -1
  5. package/dist/src/adapters/claude/claude-adapter.d.ts +17 -0
  6. package/dist/src/adapters/claude/claude-adapter.d.ts.map +1 -0
  7. package/dist/src/{event-transformer.js → adapters/claude/claude-adapter.js} +34 -10
  8. package/dist/src/adapters/claude/claude-adapter.js.map +1 -0
  9. package/dist/src/adapters/claude/tool-mapper.d.ts +19 -0
  10. package/dist/src/adapters/claude/tool-mapper.d.ts.map +1 -0
  11. package/dist/src/adapters/claude/tool-mapper.js +44 -0
  12. package/dist/src/adapters/claude/tool-mapper.js.map +1 -0
  13. package/dist/src/adapters/types.d.ts +28 -0
  14. package/dist/src/adapters/types.d.ts.map +1 -0
  15. package/dist/src/agent.d.ts +1 -1
  16. package/dist/src/agent.d.ts.map +1 -1
  17. package/dist/src/agent.js +18 -17
  18. package/dist/src/agent.js.map +1 -1
  19. package/dist/src/stage-executor.d.ts +1 -1
  20. package/dist/src/stage-executor.d.ts.map +1 -1
  21. package/dist/src/stage-executor.js +7 -7
  22. package/dist/src/stage-executor.js.map +1 -1
  23. package/dist/src/task-progress-reporter.d.ts +0 -2
  24. package/dist/src/task-progress-reporter.d.ts.map +1 -1
  25. package/dist/src/task-progress-reporter.js +0 -16
  26. package/dist/src/task-progress-reporter.js.map +1 -1
  27. package/dist/src/tools/registry.d.ts +25 -0
  28. package/dist/src/tools/registry.d.ts.map +1 -0
  29. package/dist/src/tools/registry.js +120 -0
  30. package/dist/src/tools/registry.js.map +1 -0
  31. package/dist/src/tools/types.d.ts +80 -0
  32. package/dist/src/tools/types.d.ts.map +1 -0
  33. package/dist/src/types.d.ts +41 -12
  34. package/dist/src/types.d.ts.map +1 -1
  35. package/dist/src/types.js.map +1 -1
  36. package/package.json +1 -1
  37. package/src/{event-transformer.ts → adapters/claude/claude-adapter.ts} +40 -16
  38. package/src/adapters/claude/tool-mapper.ts +46 -0
  39. package/src/adapters/types.ts +31 -0
  40. package/src/agent.ts +19 -17
  41. package/src/stage-executor.ts +11 -11
  42. package/src/task-progress-reporter.ts +0 -19
  43. package/src/tools/registry.ts +129 -0
  44. package/src/tools/types.ts +127 -0
  45. package/src/types.ts +42 -17
  46. package/dist/src/event-transformer.d.ts +0 -10
  47. package/dist/src/event-transformer.d.ts.map +0 -1
  48. package/dist/src/event-transformer.js.map +0 -1
package/src/agent.ts CHANGED
@@ -6,7 +6,8 @@ import { PostHogAPIClient } from './posthog-api.js';
6
6
  import { PostHogFileManager } from './file-manager.js';
7
7
  import { GitManager } from './git-manager.js';
8
8
  import { TemplateManager } from './template-manager.js';
9
- import { EventTransformer } from './event-transformer.js';
9
+ import { ClaudeAdapter } from './adapters/claude/claude-adapter.js';
10
+ import type { ProviderAdapter } from './adapters/types.js';
10
11
  import { PLANNING_SYSTEM_PROMPT } from './agents/planning.js';
11
12
  import { EXECUTION_SYSTEM_PROMPT } from './agents/execution.js';
12
13
  import { Logger } from './utils/logger.js';
@@ -24,7 +25,7 @@ export class Agent {
24
25
  private fileManager: PostHogFileManager;
25
26
  private gitManager: GitManager;
26
27
  private templateManager: TemplateManager;
27
- private eventTransformer: EventTransformer;
28
+ private adapter: ProviderAdapter;
28
29
  private logger: Logger;
29
30
  private agentRegistry: AgentRegistry;
30
31
  private workflowRegistry: WorkflowRegistry;
@@ -64,7 +65,8 @@ export class Agent {
64
65
  };
65
66
  this.logger = new Logger({ debug: this.debug, prefix: '[PostHog Agent]' });
66
67
  this.taskManager = new TaskManager();
67
- this.eventTransformer = new EventTransformer();
68
+ // Hardcode Claude adapter for now - extensible for other providers later
69
+ this.adapter = new ClaudeAdapter();
68
70
 
69
71
  this.fileManager = new PostHogFileManager(
70
72
  this.workingDirectory,
@@ -185,7 +187,7 @@ export class Agent {
185
187
  const atLastStage = currIdx >= 0 && currIdx === orderedStages.length - 1;
186
188
  if (atLastStage) {
187
189
  const finalStageKey = orderedStages[currIdx]?.key;
188
- this.emitEvent(this.eventTransformer.createStatusEvent('no_next_stage', { stage: finalStageKey }));
190
+ this.emitEvent(this.adapter.createStatusEvent('no_next_stage', { stage: finalStageKey }));
189
191
  await this.progressReporter.noNextStage(finalStageKey);
190
192
  await this.progressReporter.complete();
191
193
  this.taskManager.completeExecution(executionId, { task, workflow });
@@ -229,7 +231,7 @@ export class Agent {
229
231
  }
230
232
 
231
233
  async executeStage(task: Task, stage: WorkflowStage, options: WorkflowExecutionOptions = {}): Promise<void> {
232
- this.emitEvent(this.eventTransformer.createStatusEvent('stage_start', { stage: stage.key }));
234
+ this.emitEvent(this.adapter.createStatusEvent('stage_start', { stage: stage.key }));
233
235
  const overrides = options.stageOverrides?.[stage.key];
234
236
  const agentName = stage.agent_name || 'code_generation';
235
237
  const agentDef = this.agentRegistry.getAgent(agentName);
@@ -243,12 +245,12 @@ export class Agent {
243
245
  if (isPlanning && shouldCreatePlanningBranch) {
244
246
  const planningBranch = await this.createPlanningBranch(task.id);
245
247
  await this.updateTaskBranch(task.id, planningBranch);
246
- this.emitEvent(this.eventTransformer.createStatusEvent('branch_created', { stage: stage.key, branch: planningBranch }));
248
+ this.emitEvent(this.adapter.createStatusEvent('branch_created', { stage: stage.key, branch: planningBranch }));
247
249
  await this.progressReporter.branchCreated(stage.key, planningBranch);
248
250
  } else if (!isPlanning && !isManual && shouldCreateImplBranch) {
249
251
  const implBranch = await this.createImplementationBranch(task.id);
250
252
  await this.updateTaskBranch(task.id, implBranch);
251
- this.emitEvent(this.eventTransformer.createStatusEvent('branch_created', { stage: stage.key, branch: implBranch }));
253
+ this.emitEvent(this.adapter.createStatusEvent('branch_created', { stage: stage.key, branch: implBranch }));
252
254
  await this.progressReporter.branchCreated(stage.key, implBranch);
253
255
  }
254
256
 
@@ -257,7 +259,7 @@ export class Agent {
257
259
  if (result.plan) {
258
260
  await this.writePlan(task.id, result.plan);
259
261
  await this.commitPlan(task.id, task.title);
260
- this.emitEvent(this.eventTransformer.createStatusEvent('commit_made', { stage: stage.key, kind: 'plan' }));
262
+ this.emitEvent(this.adapter.createStatusEvent('commit_made', { stage: stage.key, kind: 'plan' }));
261
263
  await this.progressReporter.commitMade(stage.key, 'plan');
262
264
  }
263
265
 
@@ -272,19 +274,19 @@ export class Agent {
272
274
  const implBranch = await this.createImplementationBranch(task.id);
273
275
  await this.updateTaskBranch(task.id, implBranch);
274
276
  branchName = implBranch;
275
- this.emitEvent(this.eventTransformer.createStatusEvent('branch_created', { stage: stage.key, branch: implBranch }));
277
+ this.emitEvent(this.adapter.createStatusEvent('branch_created', { stage: stage.key, branch: implBranch }));
276
278
  await this.progressReporter.branchCreated(stage.key, implBranch);
277
279
  }
278
280
  try {
279
281
  const prUrl = await this.createPullRequest(task.id, branchName, task.title, task.description);
280
282
  await this.updateTaskBranch(task.id, branchName);
281
283
  await this.attachPullRequestToTask(task.id, prUrl, branchName);
282
- this.emitEvent(this.eventTransformer.createStatusEvent('pr_created', { stage: stage.key, prUrl }));
284
+ this.emitEvent(this.adapter.createStatusEvent('pr_created', { stage: stage.key, prUrl }));
283
285
  await this.progressReporter.pullRequestCreated(stage.key, prUrl);
284
286
  } catch {}
285
287
  }
286
288
  // Do not auto-progress on manual stages
287
- this.emitEvent(this.eventTransformer.createStatusEvent('stage_complete', { stage: stage.key }));
289
+ this.emitEvent(this.adapter.createStatusEvent('stage_complete', { stage: stage.key }));
288
290
  return;
289
291
  }
290
292
 
@@ -292,7 +294,7 @@ export class Agent {
292
294
  const existingPlan = await this.readPlan(task.id);
293
295
  const planSummary = existingPlan ? existingPlan.split('\n')[0] : undefined;
294
296
  await this.commitImplementation(task.id, task.title, planSummary);
295
- this.emitEvent(this.eventTransformer.createStatusEvent('commit_made', { stage: stage.key, kind: 'implementation' }));
297
+ this.emitEvent(this.adapter.createStatusEvent('commit_made', { stage: stage.key, kind: 'implementation' }));
296
298
  await this.progressReporter.commitMade(stage.key, 'implementation');
297
299
  }
298
300
 
@@ -306,13 +308,13 @@ export class Agent {
306
308
  const prUrl = await this.createPullRequest(task.id, branchName, task.title, task.description);
307
309
  await this.updateTaskBranch(task.id, branchName);
308
310
  await this.attachPullRequestToTask(task.id, prUrl, branchName);
309
- this.emitEvent(this.eventTransformer.createStatusEvent('pr_created', { stage: stage.key, prUrl }));
311
+ this.emitEvent(this.adapter.createStatusEvent('pr_created', { stage: stage.key, prUrl }));
310
312
  await this.progressReporter.pullRequestCreated(stage.key, prUrl);
311
313
  } catch {}
312
314
  }
313
315
  }
314
316
 
315
- this.emitEvent(this.eventTransformer.createStatusEvent('stage_complete', { stage: stage.key }));
317
+ this.emitEvent(this.adapter.createStatusEvent('stage_complete', { stage: stage.key }));
316
318
  }
317
319
 
318
320
  async progressToNextStage(taskId: string, currentStageKey?: string): Promise<void> {
@@ -326,7 +328,7 @@ export class Agent {
326
328
  stage: currentStageKey,
327
329
  error: error.message,
328
330
  });
329
- this.emitEvent(this.eventTransformer.createStatusEvent('no_next_stage', { stage: currentStageKey }));
331
+ this.emitEvent(this.adapter.createStatusEvent('no_next_stage', { stage: currentStageKey }));
330
332
  await this.progressReporter.noNextStage(currentStageKey);
331
333
  return;
332
334
  }
@@ -354,9 +356,9 @@ export class Agent {
354
356
  for await (const message of response) {
355
357
  this.logger.debug('Received message in direct run', message);
356
358
  // Emit raw SDK event
357
- this.emitEvent(this.eventTransformer.createRawSDKEvent(message));
359
+ this.emitEvent(this.adapter.createRawSDKEvent(message));
358
360
  // Emit transformed event
359
- const transformedEvent = this.eventTransformer.transform(message);
361
+ const transformedEvent = this.adapter.transform(message);
360
362
  if (transformedEvent) {
361
363
  this.emitEvent(transformedEvent);
362
364
  }
@@ -1,6 +1,6 @@
1
1
  import { query } from '@anthropic-ai/claude-agent-sdk';
2
2
  import { Logger } from './utils/logger.js';
3
- import { EventTransformer } from './event-transformer.js';
3
+ import { ClaudeAdapter } from './adapters/claude/claude-adapter.js';
4
4
  import { AgentRegistry } from './agent-registry.js';
5
5
  import type { AgentEvent, Task, McpServerConfig } from './types.js';
6
6
  import type { WorkflowStage, WorkflowStageExecutionResult, WorkflowExecutionOptions } from './workflow-types.js';
@@ -11,7 +11,7 @@ import { PromptBuilder } from './prompt-builder.js';
11
11
  export class StageExecutor {
12
12
  private registry: AgentRegistry;
13
13
  private logger: Logger;
14
- private eventTransformer: EventTransformer;
14
+ private adapter: ClaudeAdapter;
15
15
  private promptBuilder: PromptBuilder;
16
16
  private eventHandler?: (event: AgentEvent) => void;
17
17
  private mcpServers?: Record<string, McpServerConfig>;
@@ -25,7 +25,7 @@ export class StageExecutor {
25
25
  ) {
26
26
  this.registry = registry;
27
27
  this.logger = logger.child('StageExecutor');
28
- this.eventTransformer = new EventTransformer();
28
+ this.adapter = new ClaudeAdapter();
29
29
  this.promptBuilder = promptBuilder || new PromptBuilder({
30
30
  getTaskFiles: async () => [],
31
31
  generatePlanTemplate: async () => '',
@@ -96,17 +96,17 @@ export class StageExecutor {
96
96
  let plan = '';
97
97
  for await (const message of response) {
98
98
  // Emit raw SDK event first
99
- this.eventHandler?.(this.eventTransformer.createRawSDKEvent(message));
100
-
99
+ this.eventHandler?.(this.adapter.createRawSDKEvent(message));
100
+
101
101
  // Then emit transformed event
102
- const transformed = this.eventTransformer.transform(message);
102
+ const transformed = this.adapter.transform(message);
103
103
  if (transformed) {
104
104
  if (transformed.type !== 'token') {
105
105
  this.logger.debug('Planning event', { type: transformed.type });
106
106
  }
107
107
  this.eventHandler?.(transformed);
108
108
  }
109
-
109
+
110
110
  if (message.type === 'assistant' && message.message?.content) {
111
111
  for (const c of message.message.content) {
112
112
  if (c.type === 'text' && c.text) plan += c.text + '\n';
@@ -142,17 +142,17 @@ export class StageExecutor {
142
142
  const results: any[] = [];
143
143
  for await (const message of response) {
144
144
  // Emit raw SDK event first
145
- this.eventHandler?.(this.eventTransformer.createRawSDKEvent(message));
146
-
145
+ this.eventHandler?.(this.adapter.createRawSDKEvent(message));
146
+
147
147
  // Then emit transformed event
148
- const transformed = this.eventTransformer.transform(message);
148
+ const transformed = this.adapter.transform(message);
149
149
  if (transformed) {
150
150
  if (transformed.type !== 'token') {
151
151
  this.logger.debug('Execution event', { type: transformed.type });
152
152
  }
153
153
  this.eventHandler?.(transformed);
154
154
  }
155
-
155
+
156
156
  results.push(message);
157
157
  }
158
158
  return { results };
@@ -144,14 +144,6 @@ export class TaskProgressReporter {
144
144
  return;
145
145
  }
146
146
 
147
- case 'file_write':
148
- await this.appendLog(this.formatFileWriteEvent(event));
149
- return;
150
-
151
- case 'diff':
152
- await this.appendLog(this.formatDiffEvent(event));
153
- return;
154
-
155
147
  case 'status':
156
148
  // Status events are covered by dedicated progress updates
157
149
  return;
@@ -280,17 +272,6 @@ export class TaskProgressReporter {
280
272
  return `[user] ${preview}`;
281
273
  }
282
274
 
283
- private formatFileWriteEvent(event: Extract<AgentEvent, { type: 'file_write' }>): string {
284
- const size = event.bytes !== undefined ? ` (${event.bytes} bytes)` : '';
285
- return `[file] wrote ${event.path}${size}`;
286
- }
287
-
288
- private formatDiffEvent(event: Extract<AgentEvent, { type: 'diff' }>): string {
289
- const summary = event.summary
290
- ? event.summary.trim()
291
- : this.truncateMultiline(event.patch ?? '', 160);
292
- return `[diff] ${event.file}${summary ? ` | ${summary}` : ''}`;
293
- }
294
275
 
295
276
  private truncateMultiline(text: string, max = 160): string {
296
277
  if (!text) {
@@ -0,0 +1,129 @@
1
+ import type { Tool } from './types.js';
2
+
3
+ /**
4
+ * Registry of all known tools with their metadata.
5
+ * Maps tool names to their definitions.
6
+ */
7
+ const TOOL_DEFINITIONS: Record<string, Tool> = {
8
+ // Filesystem tools
9
+ 'Read': {
10
+ name: 'Read',
11
+ category: 'filesystem',
12
+ description: 'Read file contents from the filesystem',
13
+ },
14
+ 'Write': {
15
+ name: 'Write',
16
+ category: 'filesystem',
17
+ description: 'Write content to a file',
18
+ },
19
+ 'Edit': {
20
+ name: 'Edit',
21
+ category: 'filesystem',
22
+ description: 'Edit file with find and replace operations',
23
+ },
24
+ 'Glob': {
25
+ name: 'Glob',
26
+ category: 'filesystem',
27
+ description: 'Find files matching a pattern',
28
+ },
29
+ 'NotebookEdit': {
30
+ name: 'NotebookEdit',
31
+ category: 'filesystem',
32
+ description: 'Edit Jupyter notebook cells',
33
+ },
34
+
35
+ // Shell tools
36
+ 'Bash': {
37
+ name: 'Bash',
38
+ category: 'shell',
39
+ description: 'Execute bash commands',
40
+ },
41
+ 'BashOutput': {
42
+ name: 'BashOutput',
43
+ category: 'shell',
44
+ description: 'Read output from a background bash process',
45
+ },
46
+ 'KillShell': {
47
+ name: 'KillShell',
48
+ category: 'shell',
49
+ description: 'Terminate a background bash process',
50
+ },
51
+
52
+ // Web tools
53
+ 'WebFetch': {
54
+ name: 'WebFetch',
55
+ category: 'web',
56
+ description: 'Fetch content from a URL',
57
+ },
58
+ 'WebSearch': {
59
+ name: 'WebSearch',
60
+ category: 'web',
61
+ description: 'Search the web',
62
+ },
63
+
64
+ // Search tools
65
+ 'Grep': {
66
+ name: 'Grep',
67
+ category: 'search',
68
+ description: 'Search file contents using patterns',
69
+ },
70
+
71
+ // Assistant tools
72
+ 'Task': {
73
+ name: 'Task',
74
+ category: 'assistant',
75
+ description: 'Launch a specialized agent for a sub-task',
76
+ },
77
+ 'TodoWrite': {
78
+ name: 'TodoWrite',
79
+ category: 'assistant',
80
+ description: 'Manage task list and track progress',
81
+ },
82
+ 'ExitPlanMode': {
83
+ name: 'ExitPlanMode',
84
+ category: 'assistant',
85
+ description: 'Exit plan mode and present plan to user',
86
+ },
87
+ 'SlashCommand': {
88
+ name: 'SlashCommand',
89
+ category: 'assistant',
90
+ description: 'Execute a slash command',
91
+ },
92
+ };
93
+
94
+ /**
95
+ * Tool registry for looking up tool definitions by name.
96
+ * Provides metadata about tools for UI consumption.
97
+ */
98
+ export class ToolRegistry {
99
+ /**
100
+ * Get tool definition by name.
101
+ * Returns undefined if tool is not recognized.
102
+ */
103
+ get(name: string): Tool | undefined {
104
+ return TOOL_DEFINITIONS[name];
105
+ }
106
+
107
+ /**
108
+ * Get all registered tools.
109
+ */
110
+ getAll(): Tool[] {
111
+ return Object.values(TOOL_DEFINITIONS);
112
+ }
113
+
114
+ /**
115
+ * Check if a tool name is registered.
116
+ */
117
+ has(name: string): boolean {
118
+ return name in TOOL_DEFINITIONS;
119
+ }
120
+
121
+ /**
122
+ * Get all tools in a specific category.
123
+ */
124
+ getByCategory(category: string): Tool[] {
125
+ return Object.values(TOOL_DEFINITIONS).filter(
126
+ (tool) => tool.category === category
127
+ );
128
+ }
129
+ }
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Tool category classification for grouping related tools.
3
+ * Makes it easier for UIs to filter and display tools by function.
4
+ */
5
+ export type ToolCategory =
6
+ | 'filesystem' // File operations: Read, Write, Edit, Glob, NotebookEdit
7
+ | 'shell' // Shell operations: Bash, BashOutput, KillShell
8
+ | 'web' // Web operations: WebFetch, WebSearch
9
+ | 'assistant' // Assistant operations: Task, TodoWrite, ExitPlanMode
10
+ | 'search' // Search operations: Grep
11
+ | 'unknown'; // Unknown or unrecognized tools
12
+
13
+ /**
14
+ * Base tool interface representing a tool that can be called by the agent.
15
+ * Each tool has a name, category, and human-readable description.
16
+ */
17
+ export interface Tool {
18
+ name: string;
19
+ category: ToolCategory;
20
+ description: string;
21
+ }
22
+
23
+ // Filesystem tools
24
+
25
+ export interface ReadTool extends Tool {
26
+ name: 'Read';
27
+ category: 'filesystem';
28
+ }
29
+
30
+ export interface WriteTool extends Tool {
31
+ name: 'Write';
32
+ category: 'filesystem';
33
+ }
34
+
35
+ export interface EditTool extends Tool {
36
+ name: 'Edit';
37
+ category: 'filesystem';
38
+ }
39
+
40
+ export interface GlobTool extends Tool {
41
+ name: 'Glob';
42
+ category: 'filesystem';
43
+ }
44
+
45
+ export interface NotebookEditTool extends Tool {
46
+ name: 'NotebookEdit';
47
+ category: 'filesystem';
48
+ }
49
+
50
+ // Shell tools
51
+
52
+ export interface BashTool extends Tool {
53
+ name: 'Bash';
54
+ category: 'shell';
55
+ }
56
+
57
+ export interface BashOutputTool extends Tool {
58
+ name: 'BashOutput';
59
+ category: 'shell';
60
+ }
61
+
62
+ export interface KillShellTool extends Tool {
63
+ name: 'KillShell';
64
+ category: 'shell';
65
+ }
66
+
67
+ // Web tools
68
+
69
+ export interface WebFetchTool extends Tool {
70
+ name: 'WebFetch';
71
+ category: 'web';
72
+ }
73
+
74
+ export interface WebSearchTool extends Tool {
75
+ name: 'WebSearch';
76
+ category: 'web';
77
+ }
78
+
79
+ // Search tools
80
+
81
+ export interface GrepTool extends Tool {
82
+ name: 'Grep';
83
+ category: 'search';
84
+ }
85
+
86
+ // Assistant tools
87
+
88
+ export interface TaskTool extends Tool {
89
+ name: 'Task';
90
+ category: 'assistant';
91
+ }
92
+
93
+ export interface TodoWriteTool extends Tool {
94
+ name: 'TodoWrite';
95
+ category: 'assistant';
96
+ }
97
+
98
+ export interface ExitPlanModeTool extends Tool {
99
+ name: 'ExitPlanMode';
100
+ category: 'assistant';
101
+ }
102
+
103
+ export interface SlashCommandTool extends Tool {
104
+ name: 'SlashCommand';
105
+ category: 'assistant';
106
+ }
107
+
108
+ /**
109
+ * Union type of all known tool types.
110
+ * Useful for discriminated unions and type narrowing.
111
+ */
112
+ export type KnownTool =
113
+ | ReadTool
114
+ | WriteTool
115
+ | EditTool
116
+ | GlobTool
117
+ | NotebookEditTool
118
+ | BashTool
119
+ | BashOutputTool
120
+ | KillShellTool
121
+ | WebFetchTool
122
+ | WebSearchTool
123
+ | GrepTool
124
+ | TaskTool
125
+ | TodoWriteTool
126
+ | ExitPlanModeTool
127
+ | SlashCommandTool;
package/src/types.ts CHANGED
@@ -69,6 +69,10 @@ export interface ToolCallEvent extends BaseEvent {
69
69
  toolName: string;
70
70
  callId: string;
71
71
  args: Record<string, any>;
72
+ parentToolUseId?: string | null; // For nested tool calls (subagents)
73
+ // Tool metadata (enriched by adapter for UI consumption)
74
+ tool?: import('./tools/types.js').Tool;
75
+ category?: import('./tools/types.js').ToolCategory;
72
76
  }
73
77
 
74
78
  export interface ToolResultEvent extends BaseEvent {
@@ -76,6 +80,11 @@ export interface ToolResultEvent extends BaseEvent {
76
80
  toolName: string;
77
81
  callId: string;
78
82
  result: any;
83
+ isError?: boolean; // Whether the tool execution failed
84
+ parentToolUseId?: string | null; // For nested tool calls (subagents)
85
+ // Tool metadata (enriched by adapter for UI consumption)
86
+ tool?: import('./tools/types.js').Tool;
87
+ category?: import('./tools/types.js').ToolCategory;
79
88
  }
80
89
 
81
90
  // Message lifecycle events
@@ -109,7 +118,16 @@ export interface UserMessageEvent extends BaseEvent {
109
118
  export interface StatusEvent extends BaseEvent {
110
119
  type: 'status';
111
120
  phase: string;
112
- [key: string]: any;
121
+ // Common optional fields (varies by phase):
122
+ stage?: string; // Workflow stage (plan, code, complete)
123
+ kind?: string; // Kind of status (plan, implementation)
124
+ branch?: string; // Git branch name
125
+ prUrl?: string; // Pull request URL
126
+ workflowId?: string; // Workflow identifier
127
+ taskId?: string; // Task identifier
128
+ messageId?: string; // Claude message ID
129
+ model?: string; // Model name
130
+ [key: string]: any; // Allow additional fields
113
131
  }
114
132
 
115
133
  export interface InitEvent extends BaseEvent {
@@ -119,6 +137,10 @@ export interface InitEvent extends BaseEvent {
119
137
  permissionMode: string;
120
138
  cwd: string;
121
139
  apiKeySource: string;
140
+ agents?: string[];
141
+ slashCommands?: string[];
142
+ outputStyle?: string;
143
+ mcpServers?: Array<{ name: string; status: string }>;
122
144
  }
123
145
 
124
146
  export interface CompactBoundaryEvent extends BaseEvent {
@@ -130,10 +152,28 @@ export interface CompactBoundaryEvent extends BaseEvent {
130
152
  // Result events
131
153
  export interface DoneEvent extends BaseEvent {
132
154
  type: 'done';
155
+ result?: string; // Final summary text from Claude
133
156
  durationMs?: number;
157
+ durationApiMs?: number; // API-only duration (excluding local processing)
134
158
  numTurns?: number;
135
159
  totalCostUsd?: number;
136
160
  usage?: any;
161
+ modelUsage?: { // Per-model usage breakdown
162
+ [modelName: string]: {
163
+ inputTokens: number;
164
+ outputTokens: number;
165
+ cacheReadInputTokens: number;
166
+ cacheCreationInputTokens: number;
167
+ webSearchRequests: number;
168
+ costUSD: number;
169
+ contextWindow: number;
170
+ };
171
+ };
172
+ permissionDenials?: Array<{ // Tools that were denied by permissions
173
+ tool_name: string;
174
+ tool_use_id: string;
175
+ tool_input: Record<string, unknown>;
176
+ }>;
137
177
  }
138
178
 
139
179
  export interface ErrorEvent extends BaseEvent {
@@ -145,20 +185,7 @@ export interface ErrorEvent extends BaseEvent {
145
185
  sdkError?: any; // Original SDK error object
146
186
  }
147
187
 
148
- // Legacy events (keeping for backwards compatibility)
149
- export interface DiffEvent extends BaseEvent {
150
- type: 'diff';
151
- file: string;
152
- patch: string;
153
- summary?: string;
154
- }
155
-
156
- export interface FileWriteEvent extends BaseEvent {
157
- type: 'file_write';
158
- path: string;
159
- bytes: number;
160
- }
161
-
188
+ // Metric and artifact events (general purpose, not tool-specific)
162
189
  export interface MetricEvent extends BaseEvent {
163
190
  type: 'metric';
164
191
  key: string;
@@ -192,8 +219,6 @@ export type AgentEvent =
192
219
  | CompactBoundaryEvent
193
220
  | DoneEvent
194
221
  | ErrorEvent
195
- | DiffEvent
196
- | FileWriteEvent
197
222
  | MetricEvent
198
223
  | ArtifactEvent
199
224
  | RawSDKEvent;
@@ -1,10 +0,0 @@
1
- import type { AgentEvent } from './types.js';
2
- import type { SDKMessage } from '@anthropic-ai/claude-agent-sdk';
3
- export declare class EventTransformer {
4
- createRawSDKEvent(sdkMessage: any): AgentEvent;
5
- transform(sdkMessage: SDKMessage): AgentEvent | null;
6
- createStatusEvent(phase: string, additionalData?: any): AgentEvent;
7
- private extractUserContent;
8
- private extractFromObject;
9
- }
10
- //# sourceMappingURL=event-transformer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"event-transformer.d.ts","sourceRoot":"","sources":["../../src/event-transformer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAEjE,qBAAa,gBAAgB;IAC3B,iBAAiB,CAAC,UAAU,EAAE,GAAG,GAAG,UAAU;IAQ9C,SAAS,CAAC,UAAU,EAAE,UAAU,GAAG,UAAU,GAAG,IAAI;IA2NpD,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,GAAG,GAAG,UAAU;IASlE,OAAO,CAAC,kBAAkB;IAkC1B,OAAO,CAAC,iBAAiB;CAoB1B"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"event-transformer.js","sources":["../../src/event-transformer.ts"],"sourcesContent":["import type { AgentEvent } from './types.js';\nimport type { SDKMessage } from '@anthropic-ai/claude-agent-sdk';\n\nexport class EventTransformer {\n createRawSDKEvent(sdkMessage: any): AgentEvent {\n return {\n type: 'raw_sdk_event',\n ts: Date.now(),\n sdkMessage\n };\n }\n\n transform(sdkMessage: SDKMessage): AgentEvent | null {\n const baseEvent = { ts: Date.now() };\n\n // Handle stream events\n if (sdkMessage.type === 'stream_event') {\n const event = sdkMessage.event;\n\n switch (event.type) {\n case 'message_start':\n return {\n ...baseEvent,\n type: 'message_start',\n messageId: event.message?.id,\n model: event.message?.model\n };\n\n case 'content_block_start':\n const contentBlock = event.content_block;\n if (!contentBlock) return null;\n\n return {\n ...baseEvent,\n type: 'content_block_start',\n index: event.index,\n contentType: contentBlock.type as 'text' | 'tool_use' | 'thinking',\n toolName: contentBlock.type === 'tool_use' ? contentBlock.name : undefined,\n toolId: contentBlock.type === 'tool_use' ? contentBlock.id : undefined\n };\n\n case 'content_block_delta':\n const delta = event.delta;\n if (!delta) return null;\n\n if (delta.type === 'text_delta') {\n return {\n ...baseEvent,\n type: 'token',\n content: delta.text,\n contentType: 'text'\n };\n } else if (delta.type === 'input_json_delta') {\n return {\n ...baseEvent,\n type: 'token',\n content: delta.partial_json,\n contentType: 'tool_input'\n };\n } else if (delta.type === 'thinking_delta') {\n return {\n ...baseEvent,\n type: 'token',\n content: delta.thinking,\n contentType: 'thinking'\n };\n }\n return null;\n\n case 'content_block_stop':\n return {\n ...baseEvent,\n type: 'content_block_stop',\n index: event.index\n };\n\n case 'message_delta':\n return {\n ...baseEvent,\n type: 'message_delta',\n stopReason: event.delta?.stop_reason,\n stopSequence: event.delta?.stop_sequence,\n usage: event.usage ? {\n outputTokens: event.usage.output_tokens\n } : undefined\n };\n\n case 'message_stop':\n return {\n ...baseEvent,\n type: 'message_stop'\n };\n\n case 'ping':\n // Ignore ping events\n return null;\n\n case 'error':\n return {\n ...baseEvent,\n type: 'error',\n message: event.error?.message || 'Unknown error',\n error: event.error,\n errorType: event.error?.type || 'stream_error',\n context: event.error ? {\n type: event.error.type,\n code: event.error.code,\n } : undefined,\n sdkError: event.error\n };\n\n default:\n return null;\n }\n }\n\n // Handle assistant messages (full message, not streaming)\n if (sdkMessage.type === 'assistant') {\n const message = sdkMessage.message;\n \n // Extract tool calls from content blocks\n if (message.content && Array.isArray(message.content)) {\n for (const block of message.content) {\n if (block.type === 'tool_use') {\n // Return first tool_call event found\n return {\n ...baseEvent,\n type: 'tool_call',\n toolName: block.name,\n callId: block.id,\n args: block.input || {}\n };\n }\n }\n }\n \n // If no tool calls, emit status event\n return {\n ...baseEvent,\n type: 'status',\n phase: 'assistant_message',\n messageId: message.id,\n model: message.model\n };\n }\n\n // Handle user messages\n if (sdkMessage.type === 'user') {\n const message = sdkMessage.message;\n \n // Check for tool results in content blocks\n if (message?.content && Array.isArray(message.content)) {\n for (const block of message.content) {\n if (block.type === 'tool_result') {\n return {\n ...baseEvent,\n type: 'tool_result',\n toolName: block.tool_name || 'unknown',\n callId: block.tool_use_id || '',\n result: block.content\n };\n }\n }\n }\n \n // Otherwise extract text content\n const textContent = this.extractUserContent(message?.content);\n if (!textContent) {\n return null;\n }\n return {\n ...baseEvent,\n type: 'user_message',\n content: textContent,\n isSynthetic: sdkMessage.isSynthetic\n };\n }\n\n // Handle result messages\n if (sdkMessage.type === 'result') {\n if (sdkMessage.subtype === 'success') {\n return {\n ...baseEvent,\n type: 'done',\n durationMs: sdkMessage.duration_ms,\n numTurns: sdkMessage.num_turns,\n totalCostUsd: sdkMessage.total_cost_usd,\n usage: sdkMessage.usage\n };\n } else {\n return {\n ...baseEvent,\n type: 'error',\n message: `Execution failed: ${sdkMessage.subtype}`,\n error: { subtype: sdkMessage.subtype },\n errorType: sdkMessage.subtype || 'result_error',\n context: {\n subtype: sdkMessage.subtype,\n duration_ms: sdkMessage.duration_ms,\n num_turns: sdkMessage.num_turns\n },\n sdkError: sdkMessage\n };\n }\n }\n\n // Handle system messages\n if (sdkMessage.type === 'system') {\n if (sdkMessage.subtype === 'init') {\n return {\n ...baseEvent,\n type: 'init',\n model: sdkMessage.model,\n tools: sdkMessage.tools,\n permissionMode: sdkMessage.permissionMode,\n cwd: sdkMessage.cwd,\n apiKeySource: sdkMessage.apiKeySource\n };\n } else if (sdkMessage.subtype === 'compact_boundary') {\n return {\n ...baseEvent,\n type: 'compact_boundary',\n trigger: sdkMessage.compact_metadata.trigger,\n preTokens: sdkMessage.compact_metadata.pre_tokens\n };\n }\n }\n\n return null;\n }\n \n createStatusEvent(phase: string, additionalData?: any): AgentEvent {\n return {\n type: 'status',\n ts: Date.now(),\n phase,\n ...additionalData\n };\n }\n\n private extractUserContent(content: unknown): string | null {\n if (!content) {\n return null;\n }\n\n if (typeof content === 'string') {\n const trimmed = content.trim();\n return trimmed.length > 0 ? trimmed : null;\n }\n\n if (Array.isArray(content)) {\n const parts: string[] = [];\n for (const block of content) {\n const extracted = this.extractUserContent(block);\n if (extracted) {\n parts.push(extracted);\n } else if (block && typeof block === 'object') {\n const candidate = this.extractFromObject(block as Record<string, unknown>);\n if (candidate) {\n parts.push(candidate);\n }\n }\n }\n const text = parts.join('\\n').trim();\n return text.length > 0 ? text : null;\n }\n\n if (typeof content === 'object') {\n return this.extractFromObject(content as Record<string, unknown>);\n }\n\n return null;\n }\n\n private extractFromObject(value: Record<string, unknown>): string | null {\n const preferredKeys = ['text', 'input_text', 'input', 'markdown', 'content', 'message'];\n for (const key of preferredKeys) {\n if (typeof value[key] === 'string') {\n const trimmed = (value[key] as string).trim();\n if (trimmed.length > 0) {\n return trimmed;\n }\n }\n }\n\n for (const entry of Object.values(value)) {\n const extracted = this.extractUserContent(entry);\n if (extracted) {\n return extracted;\n }\n }\n\n return null;\n }\n}\n"],"names":[],"mappings":"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"}