@posthog/agent 1.24.0 → 1.24.2
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/LICENSE +33 -0
- package/dist/index.d.ts +11 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/src/adapters/claude/claude-adapter.d.ts +3 -3
- package/dist/src/adapters/claude/claude-adapter.d.ts.map +1 -1
- package/dist/src/adapters/claude/claude-adapter.js +111 -156
- package/dist/src/adapters/claude/claude-adapter.js.map +1 -1
- package/dist/src/adapters/claude/tool-mapper.d.ts +1 -1
- package/dist/src/adapters/claude/tool-mapper.d.ts.map +1 -1
- package/dist/src/adapters/claude/tool-mapper.js.map +1 -1
- package/dist/src/adapters/types.d.ts +1 -1
- package/dist/src/adapters/types.d.ts.map +1 -1
- package/dist/src/agent.d.ts +7 -7
- package/dist/src/agent.d.ts.map +1 -1
- package/dist/src/agent.js +85 -143
- package/dist/src/agent.js.map +1 -1
- package/dist/src/agents/execution.js.map +1 -1
- package/dist/src/agents/planning.js.map +1 -1
- package/dist/src/agents/research.js.map +1 -1
- package/dist/src/file-manager.d.ts +4 -4
- package/dist/src/file-manager.d.ts.map +1 -1
- package/dist/src/file-manager.js +58 -59
- package/dist/src/file-manager.js.map +1 -1
- package/dist/src/git-manager.d.ts +1 -1
- package/dist/src/git-manager.d.ts.map +1 -1
- package/dist/src/git-manager.js +70 -87
- package/dist/src/git-manager.js.map +1 -1
- package/dist/src/posthog-api.d.ts +3 -2
- package/dist/src/posthog-api.d.ts.map +1 -1
- package/dist/src/posthog-api.js +22 -22
- package/dist/src/posthog-api.js.map +1 -1
- package/dist/src/prompt-builder.d.ts +3 -3
- package/dist/src/prompt-builder.d.ts.map +1 -1
- package/dist/src/prompt-builder.js +93 -123
- package/dist/src/prompt-builder.js.map +1 -1
- package/dist/src/task-manager.d.ts +4 -4
- package/dist/src/task-manager.d.ts.map +1 -1
- package/dist/src/task-manager.js +18 -19
- package/dist/src/task-manager.js.map +1 -1
- package/dist/src/task-progress-reporter.d.ts +4 -3
- package/dist/src/task-progress-reporter.d.ts.map +1 -1
- package/dist/src/task-progress-reporter.js +54 -59
- package/dist/src/task-progress-reporter.js.map +1 -1
- package/dist/src/template-manager.d.ts +1 -1
- package/dist/src/template-manager.d.ts.map +1 -1
- package/dist/src/template-manager.js +28 -30
- package/dist/src/template-manager.js.map +1 -1
- package/dist/src/todo-manager.d.ts +3 -3
- package/dist/src/todo-manager.d.ts.map +1 -1
- package/dist/src/todo-manager.js +24 -29
- package/dist/src/todo-manager.js.map +1 -1
- package/dist/src/tools/registry.d.ts +1 -1
- package/dist/src/tools/registry.js +60 -60
- package/dist/src/tools/registry.js.map +1 -1
- package/dist/src/tools/types.d.ts +31 -31
- package/dist/src/types.d.ts +33 -33
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js.map +1 -1
- package/dist/src/utils/logger.d.ts +4 -4
- package/dist/src/utils/logger.d.ts.map +1 -1
- package/dist/src/utils/logger.js +8 -8
- package/dist/src/utils/logger.js.map +1 -1
- package/dist/src/workflow/config.d.ts +1 -1
- package/dist/src/workflow/config.d.ts.map +1 -1
- package/dist/src/workflow/config.js +18 -18
- package/dist/src/workflow/config.js.map +1 -1
- package/dist/src/workflow/steps/build.d.ts +1 -1
- package/dist/src/workflow/steps/build.d.ts.map +1 -1
- package/dist/src/workflow/steps/build.js +38 -46
- package/dist/src/workflow/steps/build.js.map +1 -1
- package/dist/src/workflow/steps/finalize.d.ts +1 -1
- package/dist/src/workflow/steps/finalize.d.ts.map +1 -1
- package/dist/src/workflow/steps/finalize.js +48 -54
- package/dist/src/workflow/steps/finalize.js.map +1 -1
- package/dist/src/workflow/steps/plan.d.ts +1 -1
- package/dist/src/workflow/steps/plan.d.ts.map +1 -1
- package/dist/src/workflow/steps/plan.js +46 -58
- package/dist/src/workflow/steps/plan.js.map +1 -1
- package/dist/src/workflow/steps/research.d.ts +1 -1
- package/dist/src/workflow/steps/research.d.ts.map +1 -1
- package/dist/src/workflow/steps/research.js +56 -68
- package/dist/src/workflow/steps/research.js.map +1 -1
- package/dist/src/workflow/types.d.ts +12 -12
- package/dist/src/workflow/types.d.ts.map +1 -1
- package/dist/src/workflow/utils.d.ts +1 -1
- package/dist/src/workflow/utils.d.ts.map +1 -1
- package/dist/src/workflow/utils.js +4 -7
- package/dist/src/workflow/utils.js.map +1 -1
- package/package.json +6 -6
- package/src/adapters/claude/claude-adapter.ts +168 -220
- package/src/adapters/claude/tool-mapper.ts +2 -2
- package/src/adapters/types.ts +1 -1
- package/src/agent.ts +444 -579
- package/src/agents/execution.ts +1 -1
- package/src/agents/planning.ts +1 -1
- package/src/agents/research.ts +1 -0
- package/src/file-manager.ts +63 -64
- package/src/git-manager.ts +88 -144
- package/src/posthog-api.ts +82 -122
- package/src/prompt-builder.ts +135 -180
- package/src/task-manager.ts +30 -38
- package/src/task-progress-reporter.ts +59 -70
- package/src/template-manager.ts +45 -98
- package/src/todo-manager.ts +30 -35
- package/src/tools/registry.ts +62 -62
- package/src/tools/types.ts +36 -36
- package/src/types.ts +71 -93
- package/src/utils/logger.ts +56 -62
- package/src/workflow/config.ts +48 -48
- package/src/workflow/steps/build.ts +113 -122
- package/src/workflow/steps/finalize.ts +182 -214
- package/src/workflow/steps/plan.ts +131 -151
- package/src/workflow/steps/research.ts +186 -205
- package/src/workflow/types.ts +36 -38
- package/src/workflow/utils.ts +34 -37
|
@@ -1,41 +1,35 @@
|
|
|
1
1
|
import { query } from '@anthropic-ai/claude-agent-sdk';
|
|
2
2
|
import { PLANNING_SYSTEM_PROMPT } from '../../agents/planning.js';
|
|
3
|
-
import { TodoManager } from '../../todo-manager.js';
|
|
4
3
|
import { finalizeStepGitActions } from '../utils.js';
|
|
4
|
+
import { TodoManager } from '../../todo-manager.js';
|
|
5
5
|
|
|
6
6
|
const planStep = async ({ step, context }) => {
|
|
7
7
|
const { task, cwd, isCloudMode, options, logger, fileManager, gitManager, promptBuilder, adapter, mcpServers, emitEvent, } = context;
|
|
8
|
-
const stepLogger = logger.child(
|
|
8
|
+
const stepLogger = logger.child('PlanStep');
|
|
9
9
|
const existingPlan = await fileManager.readPlan(task.id);
|
|
10
10
|
if (existingPlan) {
|
|
11
|
-
stepLogger.info(
|
|
12
|
-
return { status:
|
|
11
|
+
stepLogger.info('Plan already exists, skipping step', { taskId: task.id });
|
|
12
|
+
return { status: 'skipped' };
|
|
13
13
|
}
|
|
14
14
|
const researchData = await fileManager.readResearch(task.id);
|
|
15
15
|
if (researchData?.questions && !researchData.answered) {
|
|
16
|
-
stepLogger.info(
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
emitEvent(adapter.createStatusEvent("phase_complete", {
|
|
20
|
-
phase: "research_questions",
|
|
21
|
-
}));
|
|
22
|
-
return { status: "skipped", halt: true };
|
|
16
|
+
stepLogger.info('Waiting for answered research questions', { taskId: task.id });
|
|
17
|
+
emitEvent(adapter.createStatusEvent('phase_complete', { phase: 'research_questions' }));
|
|
18
|
+
return { status: 'skipped', halt: true };
|
|
23
19
|
}
|
|
24
|
-
stepLogger.info(
|
|
25
|
-
emitEvent(adapter.createStatusEvent(
|
|
26
|
-
let researchContext =
|
|
20
|
+
stepLogger.info('Starting planning phase', { taskId: task.id });
|
|
21
|
+
emitEvent(adapter.createStatusEvent('phase_start', { phase: 'planning' }));
|
|
22
|
+
let researchContext = '';
|
|
27
23
|
if (researchData) {
|
|
28
24
|
researchContext += `## Research Context\n\n${researchData.context}\n\n`;
|
|
29
25
|
if (researchData.keyFiles.length > 0) {
|
|
30
|
-
researchContext += `**Key Files:**\n${researchData.keyFiles.map(
|
|
26
|
+
researchContext += `**Key Files:**\n${researchData.keyFiles.map(f => `- ${f}`).join('\n')}\n\n`;
|
|
31
27
|
}
|
|
32
28
|
if (researchData.blockers && researchData.blockers.length > 0) {
|
|
33
|
-
researchContext += `**Considerations:**\n${researchData.blockers.map(
|
|
29
|
+
researchContext += `**Considerations:**\n${researchData.blockers.map(b => `- ${b}`).join('\n')}\n\n`;
|
|
34
30
|
}
|
|
35
31
|
// Add answered questions if they exist
|
|
36
|
-
if (researchData.questions &&
|
|
37
|
-
researchData.answers &&
|
|
38
|
-
researchData.answered) {
|
|
32
|
+
if (researchData.questions && researchData.answers && researchData.answered) {
|
|
39
33
|
researchContext += `## Implementation Decisions\n\n`;
|
|
40
34
|
for (const question of researchData.questions) {
|
|
41
35
|
const answer = researchData.answers.find((a) => a.questionId === question.id);
|
|
@@ -58,21 +52,21 @@ const planStep = async ({ step, context }) => {
|
|
|
58
52
|
const baseOptions = {
|
|
59
53
|
model: step.model,
|
|
60
54
|
cwd,
|
|
61
|
-
permissionMode:
|
|
62
|
-
settingSources: [
|
|
55
|
+
permissionMode: 'plan',
|
|
56
|
+
settingSources: ['local'],
|
|
63
57
|
mcpServers,
|
|
64
58
|
// Allow research tools: read-only operations, web search, MCP resources, and ExitPlanMode
|
|
65
59
|
allowedTools: [
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
60
|
+
'Read',
|
|
61
|
+
'Glob',
|
|
62
|
+
'Grep',
|
|
63
|
+
'WebFetch',
|
|
64
|
+
'WebSearch',
|
|
65
|
+
'ListMcpResources',
|
|
66
|
+
'ReadMcpResource',
|
|
67
|
+
'ExitPlanMode',
|
|
68
|
+
'TodoWrite',
|
|
69
|
+
'BashOutput',
|
|
76
70
|
],
|
|
77
71
|
};
|
|
78
72
|
const response = query({
|
|
@@ -80,46 +74,40 @@ const planStep = async ({ step, context }) => {
|
|
|
80
74
|
options: { ...baseOptions, ...(options.queryOverrides || {}) },
|
|
81
75
|
});
|
|
82
76
|
const todoManager = new TodoManager(fileManager, stepLogger);
|
|
83
|
-
let planContent =
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
planContent += `${block.text}\n`;
|
|
100
|
-
}
|
|
77
|
+
let planContent = '';
|
|
78
|
+
for await (const message of response) {
|
|
79
|
+
emitEvent(adapter.createRawSDKEvent(message));
|
|
80
|
+
const transformedEvents = adapter.transform(message);
|
|
81
|
+
for (const event of transformedEvents) {
|
|
82
|
+
emitEvent(event);
|
|
83
|
+
}
|
|
84
|
+
const todoList = await todoManager.checkAndPersistFromMessage(message, task.id);
|
|
85
|
+
if (todoList) {
|
|
86
|
+
emitEvent(adapter.createArtifactEvent('todos', todoList));
|
|
87
|
+
}
|
|
88
|
+
// Extract text content for plan
|
|
89
|
+
if (message.type === 'assistant' && message.message?.content) {
|
|
90
|
+
for (const block of message.message.content) {
|
|
91
|
+
if (block.type === 'text' && block.text) {
|
|
92
|
+
planContent += `${block.text}\n`;
|
|
101
93
|
}
|
|
102
94
|
}
|
|
103
95
|
}
|
|
104
96
|
}
|
|
105
|
-
catch (error) {
|
|
106
|
-
stepLogger.error("Error during plan step query", error);
|
|
107
|
-
throw error;
|
|
108
|
-
}
|
|
109
97
|
if (planContent.trim()) {
|
|
110
98
|
await fileManager.writePlan(task.id, planContent.trim());
|
|
111
|
-
stepLogger.info(
|
|
99
|
+
stepLogger.info('Plan completed', { taskId: task.id });
|
|
112
100
|
}
|
|
113
101
|
await gitManager.addAllPostHogFiles();
|
|
114
102
|
await finalizeStepGitActions(context, step, {
|
|
115
103
|
commitMessage: `Planning phase for ${task.title}`,
|
|
116
104
|
});
|
|
117
105
|
if (!isCloudMode) {
|
|
118
|
-
emitEvent(adapter.createStatusEvent(
|
|
119
|
-
return { status:
|
|
106
|
+
emitEvent(adapter.createStatusEvent('phase_complete', { phase: 'planning' }));
|
|
107
|
+
return { status: 'completed', halt: true };
|
|
120
108
|
}
|
|
121
|
-
emitEvent(adapter.createStatusEvent(
|
|
122
|
-
return { status:
|
|
109
|
+
emitEvent(adapter.createStatusEvent('phase_complete', { phase: 'planning' }));
|
|
110
|
+
return { status: 'completed' };
|
|
123
111
|
};
|
|
124
112
|
|
|
125
113
|
export { planStep };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plan.js","sources":["../../../../src/workflow/steps/plan.ts"],"sourcesContent":["import { query } from
|
|
1
|
+
{"version":3,"file":"plan.js","sources":["../../../../src/workflow/steps/plan.ts"],"sourcesContent":["import { query } from '@anthropic-ai/claude-agent-sdk';\nimport { PLANNING_SYSTEM_PROMPT } from '../../agents/planning.js';\nimport type { WorkflowStepRunner } from '../types.js';\nimport { finalizeStepGitActions } from '../utils.js';\nimport { TodoManager } from '../../todo-manager.js';\n\nexport const planStep: WorkflowStepRunner = async ({ step, context }) => {\n const {\n task,\n cwd,\n isCloudMode,\n options,\n logger,\n fileManager,\n gitManager,\n promptBuilder,\n adapter,\n mcpServers,\n emitEvent,\n } = context;\n\n const stepLogger = logger.child('PlanStep');\n\n const existingPlan = await fileManager.readPlan(task.id);\n if (existingPlan) {\n stepLogger.info('Plan already exists, skipping step', { taskId: task.id });\n return { status: 'skipped' };\n }\n\n const researchData = await fileManager.readResearch(task.id);\n if (researchData?.questions && !researchData.answered) {\n stepLogger.info('Waiting for answered research questions', { taskId: task.id });\n emitEvent(adapter.createStatusEvent('phase_complete', { phase: 'research_questions' }));\n return { status: 'skipped', halt: true };\n }\n\n stepLogger.info('Starting planning phase', { taskId: task.id });\n emitEvent(adapter.createStatusEvent('phase_start', { phase: 'planning' }));\n let researchContext = '';\n if (researchData) {\n researchContext += `## Research Context\\n\\n${researchData.context}\\n\\n`;\n if (researchData.keyFiles.length > 0) {\n researchContext += `**Key Files:**\\n${researchData.keyFiles.map(f => `- ${f}`).join('\\n')}\\n\\n`;\n }\n if (researchData.blockers && researchData.blockers.length > 0) {\n researchContext += `**Considerations:**\\n${researchData.blockers.map(b => `- ${b}`).join('\\n')}\\n\\n`;\n }\n\n // Add answered questions if they exist\n if (researchData.questions && researchData.answers && researchData.answered) {\n researchContext += `## Implementation Decisions\\n\\n`;\n for (const question of researchData.questions) {\n const answer = researchData.answers.find(\n (a) => a.questionId === question.id\n );\n\n researchContext += `### ${question.question}\\n\\n`;\n if (answer) {\n researchContext += `**Selected:** ${answer.selectedOption}\\n`;\n if (answer.customInput) {\n researchContext += `**Details:** ${answer.customInput}\\n`;\n }\n } else {\n researchContext += `**Selected:** Not answered\\n`;\n }\n researchContext += `\\n`;\n }\n }\n }\n\n const planningPrompt = await promptBuilder.buildPlanningPrompt(task, cwd);\n const fullPrompt = `${PLANNING_SYSTEM_PROMPT}\\n\\n${planningPrompt}\\n\\n${researchContext}`;\n\n const baseOptions: Record<string, any> = {\n model: step.model,\n cwd,\n permissionMode: 'plan',\n settingSources: ['local'],\n mcpServers,\n // Allow research tools: read-only operations, web search, MCP resources, and ExitPlanMode\n allowedTools: [\n 'Read',\n 'Glob',\n 'Grep',\n 'WebFetch',\n 'WebSearch',\n 'ListMcpResources',\n 'ReadMcpResource',\n 'ExitPlanMode',\n 'TodoWrite',\n 'BashOutput',\n ],\n };\n\n const response = query({\n prompt: fullPrompt,\n options: { ...baseOptions, ...(options.queryOverrides || {}) },\n });\n\n const todoManager = new TodoManager(fileManager, stepLogger);\n\n let planContent = '';\n for await (const message of response) {\n emitEvent(adapter.createRawSDKEvent(message));\n const transformedEvents = adapter.transform(message);\n for (const event of transformedEvents) {\n emitEvent(event);\n }\n\n const todoList = await todoManager.checkAndPersistFromMessage(message, task.id);\n if (todoList) {\n emitEvent(adapter.createArtifactEvent('todos', todoList));\n }\n\n // Extract text content for plan\n if (message.type === 'assistant' && message.message?.content) {\n for (const block of message.message.content) {\n if (block.type === 'text' && block.text) {\n planContent += `${block.text}\\n`;\n }\n }\n }\n }\n\n if (planContent.trim()) {\n await fileManager.writePlan(task.id, planContent.trim());\n stepLogger.info('Plan completed', { taskId: task.id });\n }\n\n await gitManager.addAllPostHogFiles();\n await finalizeStepGitActions(context, step, {\n commitMessage: `Planning phase for ${task.title}`,\n });\n\n if (!isCloudMode) {\n emitEvent(adapter.createStatusEvent('phase_complete', { phase: 'planning' }));\n return { status: 'completed', halt: true };\n }\n\n emitEvent(adapter.createStatusEvent('phase_complete', { phase: 'planning' }));\n return { status: 'completed' };\n};\n"],"names":[],"mappings":";;;;;AAMO,MAAM,QAAQ,GAAuB,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAI;IACpE,MAAM,EACF,IAAI,EACJ,GAAG,EACH,WAAW,EACX,OAAO,EACP,MAAM,EACN,WAAW,EACX,UAAU,EACV,aAAa,EACb,OAAO,EACP,UAAU,EACV,SAAS,GACZ,GAAG,OAAO;IAEX,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC;IAE3C,MAAM,YAAY,GAAG,MAAM,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;IACxD,IAAI,YAAY,EAAE;AACd,QAAA,UAAU,CAAC,IAAI,CAAC,oCAAoC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;AAC1E,QAAA,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE;IAChC;IAEA,MAAM,YAAY,GAAG,MAAM,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;IAC5D,IAAI,YAAY,EAAE,SAAS,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE;AACnD,QAAA,UAAU,CAAC,IAAI,CAAC,yCAAyC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;AAC/E,QAAA,SAAS,CAAC,OAAO,CAAC,iBAAiB,CAAC,gBAAgB,EAAE,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC,CAAC;QACvF,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE;IAC5C;AAEA,IAAA,UAAU,CAAC,IAAI,CAAC,yBAAyB,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;AAC/D,IAAA,SAAS,CAAC,OAAO,CAAC,iBAAiB,CAAC,aAAa,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;IAC1E,IAAI,eAAe,GAAG,EAAE;IACxB,IAAI,YAAY,EAAE;AACd,QAAA,eAAe,IAAI,CAAA,uBAAA,EAA0B,YAAY,CAAC,OAAO,MAAM;QACvE,IAAI,YAAY,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE;YAClC,eAAe,IAAI,mBAAmB,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,CAAA,EAAA,EAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA,IAAA,CAAM;QACnG;AACA,QAAA,IAAI,YAAY,CAAC,QAAQ,IAAI,YAAY,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE;YAC3D,eAAe,IAAI,wBAAwB,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,CAAA,EAAA,EAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA,IAAA,CAAM;QACxG;;AAGA,QAAA,IAAI,YAAY,CAAC,SAAS,IAAI,YAAY,CAAC,OAAO,IAAI,YAAY,CAAC,QAAQ,EAAE;YACzE,eAAe,IAAI,iCAAiC;AACpD,YAAA,KAAK,MAAM,QAAQ,IAAI,YAAY,CAAC,SAAS,EAAE;gBAC3C,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CACpC,CAAC,CAAC,KAAK,CAAC,CAAC,UAAU,KAAK,QAAQ,CAAC,EAAE,CACtC;AAED,gBAAA,eAAe,IAAI,CAAA,IAAA,EAAO,QAAQ,CAAC,QAAQ,MAAM;gBACjD,IAAI,MAAM,EAAE;AACR,oBAAA,eAAe,IAAI,CAAA,cAAA,EAAiB,MAAM,CAAC,cAAc,IAAI;AAC7D,oBAAA,IAAI,MAAM,CAAC,WAAW,EAAE;AACpB,wBAAA,eAAe,IAAI,CAAA,aAAA,EAAgB,MAAM,CAAC,WAAW,IAAI;oBAC7D;gBACJ;qBAAO;oBACH,eAAe,IAAI,8BAA8B;gBACrD;gBACA,eAAe,IAAI,IAAI;YAC3B;QACJ;IACJ;IAEA,MAAM,cAAc,GAAG,MAAM,aAAa,CAAC,mBAAmB,CAAC,IAAI,EAAE,GAAG,CAAC;IACzE,MAAM,UAAU,GAAG,CAAA,EAAG,sBAAsB,OAAO,cAAc,CAAA,IAAA,EAAO,eAAe,CAAA,CAAE;AAEzF,IAAA,MAAM,WAAW,GAAwB;QACrC,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,GAAG;AACH,QAAA,cAAc,EAAE,MAAM;QACtB,cAAc,EAAE,CAAC,OAAO,CAAC;QACzB,UAAU;;AAEV,QAAA,YAAY,EAAE;YACV,MAAM;YACN,MAAM;YACN,MAAM;YACN,UAAU;YACV,WAAW;YACX,kBAAkB;YAClB,iBAAiB;YACjB,cAAc;YACd,WAAW;YACX,YAAY;AACf,SAAA;KACJ;IAED,MAAM,QAAQ,GAAG,KAAK,CAAC;AACnB,QAAA,MAAM,EAAE,UAAU;AAClB,QAAA,OAAO,EAAE,EAAE,GAAG,WAAW,EAAE,IAAI,OAAO,CAAC,cAAc,IAAI,EAAE,CAAC,EAAE;AACjE,KAAA,CAAC;IAEF,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,WAAW,EAAE,UAAU,CAAC;IAE5D,IAAI,WAAW,GAAG,EAAE;AACpB,IAAA,WAAW,MAAM,OAAO,IAAI,QAAQ,EAAE;QAClC,SAAS,CAAC,OAAO,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAC7C,MAAM,iBAAiB,GAAG,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC;AACpD,QAAA,KAAK,MAAM,KAAK,IAAI,iBAAiB,EAAE;YACnC,SAAS,CAAC,KAAK,CAAC;QACpB;AAEA,QAAA,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,0BAA0B,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC;QAC/E,IAAI,QAAQ,EAAE;YACV,SAAS,CAAC,OAAO,CAAC,mBAAmB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC7D;;AAGA,QAAA,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,IAAI,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE;YAC1D,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE;gBACzC,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,IAAI,EAAE;AACrC,oBAAA,WAAW,IAAI,CAAA,EAAG,KAAK,CAAC,IAAI,IAAI;gBACpC;YACJ;QACJ;IACJ;AAEA,IAAA,IAAI,WAAW,CAAC,IAAI,EAAE,EAAE;AACpB,QAAA,MAAM,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,WAAW,CAAC,IAAI,EAAE,CAAC;AACxD,QAAA,UAAU,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;IAC1D;AAEA,IAAA,MAAM,UAAU,CAAC,kBAAkB,EAAE;AACrC,IAAA,MAAM,sBAAsB,CAAC,OAAO,EAAE,IAAI,EAAE;AACxC,QAAA,aAAa,EAAE,CAAA,mBAAA,EAAsB,IAAI,CAAC,KAAK,CAAA,CAAE;AACpD,KAAA,CAAC;IAEF,IAAI,CAAC,WAAW,EAAE;AACd,QAAA,SAAS,CAAC,OAAO,CAAC,iBAAiB,CAAC,gBAAgB,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;QAC7E,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE;IAC9C;AAEA,IAAA,SAAS,CAAC,OAAO,CAAC,iBAAiB,CAAC,gBAAgB,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;AAC7E,IAAA,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE;AAClC;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"research.d.ts","sourceRoot":"","sources":["../../../../src/workflow/steps/research.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"research.d.ts","sourceRoot":"","sources":["../../../../src/workflow/steps/research.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAItD,eAAO,MAAM,YAAY,EAAE,kBAoM1B,CAAC"}
|
|
@@ -4,90 +4,80 @@ import { finalizeStepGitActions } from '../utils.js';
|
|
|
4
4
|
|
|
5
5
|
const researchStep = async ({ step, context }) => {
|
|
6
6
|
const { task, cwd, isCloudMode, options, logger, fileManager, gitManager, promptBuilder, adapter, mcpServers, emitEvent, } = context;
|
|
7
|
-
const stepLogger = logger.child(
|
|
7
|
+
const stepLogger = logger.child('ResearchStep');
|
|
8
8
|
const existingResearch = await fileManager.readResearch(task.id);
|
|
9
9
|
if (existingResearch) {
|
|
10
|
-
stepLogger.info(
|
|
11
|
-
taskId: task.id,
|
|
12
|
-
hasQuestions: !!existingResearch.questions,
|
|
13
|
-
answered: existingResearch.answered,
|
|
14
|
-
});
|
|
10
|
+
stepLogger.info('Research already exists', { taskId: task.id, hasQuestions: !!existingResearch.questions, answered: existingResearch.answered });
|
|
15
11
|
// If there are unanswered questions, re-emit them so UI can prompt user
|
|
16
12
|
if (existingResearch.questions && !existingResearch.answered) {
|
|
17
|
-
stepLogger.info(
|
|
13
|
+
stepLogger.info('Re-emitting unanswered research questions', {
|
|
18
14
|
taskId: task.id,
|
|
19
|
-
questionCount: existingResearch.questions.length
|
|
15
|
+
questionCount: existingResearch.questions.length
|
|
20
16
|
});
|
|
21
17
|
emitEvent({
|
|
22
|
-
type:
|
|
18
|
+
type: 'artifact',
|
|
23
19
|
ts: Date.now(),
|
|
24
|
-
kind:
|
|
20
|
+
kind: 'research_questions',
|
|
25
21
|
content: existingResearch.questions,
|
|
26
22
|
});
|
|
27
23
|
// In local mode, halt to allow user to answer
|
|
28
24
|
if (!isCloudMode) {
|
|
29
|
-
emitEvent(adapter.createStatusEvent(
|
|
30
|
-
return { status:
|
|
25
|
+
emitEvent(adapter.createStatusEvent('phase_complete', { phase: 'research' }));
|
|
26
|
+
return { status: 'skipped', halt: true };
|
|
31
27
|
}
|
|
32
28
|
}
|
|
33
|
-
return { status:
|
|
29
|
+
return { status: 'skipped' };
|
|
34
30
|
}
|
|
35
|
-
stepLogger.info(
|
|
36
|
-
emitEvent(adapter.createStatusEvent(
|
|
31
|
+
stepLogger.info('Starting research phase', { taskId: task.id });
|
|
32
|
+
emitEvent(adapter.createStatusEvent('phase_start', { phase: 'research' }));
|
|
37
33
|
const researchPrompt = await promptBuilder.buildResearchPrompt(task, cwd);
|
|
38
34
|
const fullPrompt = `${RESEARCH_SYSTEM_PROMPT}\n\n${researchPrompt}`;
|
|
39
35
|
const baseOptions = {
|
|
40
36
|
model: step.model,
|
|
41
37
|
cwd,
|
|
42
|
-
permissionMode:
|
|
43
|
-
settingSources: [
|
|
38
|
+
permissionMode: 'plan',
|
|
39
|
+
settingSources: ['local'],
|
|
44
40
|
mcpServers,
|
|
45
41
|
// Allow research tools: read-only operations, web search, and MCP resources
|
|
46
42
|
allowedTools: [
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
43
|
+
'Read',
|
|
44
|
+
'Glob',
|
|
45
|
+
'Grep',
|
|
46
|
+
'WebFetch',
|
|
47
|
+
'WebSearch',
|
|
48
|
+
'ListMcpResources',
|
|
49
|
+
'ReadMcpResource',
|
|
50
|
+
'TodoWrite',
|
|
51
|
+
'BashOutput',
|
|
56
52
|
],
|
|
57
53
|
};
|
|
58
54
|
const response = query({
|
|
59
55
|
prompt: fullPrompt,
|
|
60
56
|
options: { ...baseOptions, ...(options.queryOverrides || {}) },
|
|
61
57
|
});
|
|
62
|
-
let jsonContent =
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
jsonContent += c.text;
|
|
74
|
-
}
|
|
58
|
+
let jsonContent = '';
|
|
59
|
+
for await (const message of response) {
|
|
60
|
+
emitEvent(adapter.createRawSDKEvent(message));
|
|
61
|
+
const transformedEvents = adapter.transform(message);
|
|
62
|
+
for (const event of transformedEvents) {
|
|
63
|
+
emitEvent(event);
|
|
64
|
+
}
|
|
65
|
+
if (message.type === 'assistant' && message.message?.content) {
|
|
66
|
+
for (const c of message.message.content) {
|
|
67
|
+
if (c.type === 'text' && c.text) {
|
|
68
|
+
jsonContent += c.text;
|
|
75
69
|
}
|
|
76
70
|
}
|
|
77
71
|
}
|
|
78
72
|
}
|
|
79
|
-
catch (error) {
|
|
80
|
-
stepLogger.error("Error during research step query", error);
|
|
81
|
-
throw error;
|
|
82
|
-
}
|
|
83
73
|
if (!jsonContent.trim()) {
|
|
84
|
-
stepLogger.error(
|
|
74
|
+
stepLogger.error('No JSON output from research agent', { taskId: task.id });
|
|
85
75
|
emitEvent({
|
|
86
|
-
type:
|
|
76
|
+
type: 'error',
|
|
87
77
|
ts: Date.now(),
|
|
88
|
-
message:
|
|
78
|
+
message: 'Research agent returned no output',
|
|
89
79
|
});
|
|
90
|
-
return { status:
|
|
80
|
+
return { status: 'completed', halt: true };
|
|
91
81
|
}
|
|
92
82
|
// Parse JSON response
|
|
93
83
|
let evaluation;
|
|
@@ -95,27 +85,27 @@ const researchStep = async ({ step, context }) => {
|
|
|
95
85
|
// Extract JSON from potential markdown code blocks or other wrapping
|
|
96
86
|
const jsonMatch = jsonContent.match(/\{[\s\S]*\}/);
|
|
97
87
|
if (!jsonMatch) {
|
|
98
|
-
throw new Error(
|
|
88
|
+
throw new Error('No JSON object found in response');
|
|
99
89
|
}
|
|
100
90
|
evaluation = JSON.parse(jsonMatch[0]);
|
|
101
|
-
stepLogger.info(
|
|
91
|
+
stepLogger.info('Parsed research evaluation', {
|
|
102
92
|
taskId: task.id,
|
|
103
93
|
score: evaluation.actionabilityScore,
|
|
104
94
|
hasQuestions: !!evaluation.questions,
|
|
105
95
|
});
|
|
106
96
|
}
|
|
107
97
|
catch (error) {
|
|
108
|
-
stepLogger.error(
|
|
98
|
+
stepLogger.error('Failed to parse research JSON', {
|
|
109
99
|
taskId: task.id,
|
|
110
100
|
error: error instanceof Error ? error.message : String(error),
|
|
111
101
|
content: jsonContent.substring(0, 500),
|
|
112
102
|
});
|
|
113
103
|
emitEvent({
|
|
114
|
-
type:
|
|
104
|
+
type: 'error',
|
|
115
105
|
ts: Date.now(),
|
|
116
106
|
message: `Failed to parse research JSON: ${error instanceof Error ? error.message : String(error)}`,
|
|
117
107
|
});
|
|
118
|
-
return { status:
|
|
108
|
+
return { status: 'completed', halt: true };
|
|
119
109
|
}
|
|
120
110
|
// Add answered/answers fields to evaluation
|
|
121
111
|
if (evaluation.questions && evaluation.questions.length > 0) {
|
|
@@ -124,15 +114,15 @@ const researchStep = async ({ step, context }) => {
|
|
|
124
114
|
}
|
|
125
115
|
// Always write research.json
|
|
126
116
|
await fileManager.writeResearch(task.id, evaluation);
|
|
127
|
-
stepLogger.info(
|
|
117
|
+
stepLogger.info('Research evaluation written', {
|
|
128
118
|
taskId: task.id,
|
|
129
119
|
score: evaluation.actionabilityScore,
|
|
130
120
|
hasQuestions: !!evaluation.questions,
|
|
131
121
|
});
|
|
132
122
|
emitEvent({
|
|
133
|
-
type:
|
|
123
|
+
type: 'artifact',
|
|
134
124
|
ts: Date.now(),
|
|
135
|
-
kind:
|
|
125
|
+
kind: 'research_evaluation',
|
|
136
126
|
content: evaluation,
|
|
137
127
|
});
|
|
138
128
|
await gitManager.addAllPostHogFiles();
|
|
@@ -140,42 +130,40 @@ const researchStep = async ({ step, context }) => {
|
|
|
140
130
|
commitMessage: `Research phase for ${task.title}`,
|
|
141
131
|
});
|
|
142
132
|
// Log whether questions need answering
|
|
143
|
-
if (evaluation.actionabilityScore < 0.7 &&
|
|
144
|
-
|
|
145
|
-
evaluation.questions.length > 0) {
|
|
146
|
-
stepLogger.info("Actionability score below threshold, questions needed", {
|
|
133
|
+
if (evaluation.actionabilityScore < 0.7 && evaluation.questions && evaluation.questions.length > 0) {
|
|
134
|
+
stepLogger.info('Actionability score below threshold, questions needed', {
|
|
147
135
|
taskId: task.id,
|
|
148
136
|
score: evaluation.actionabilityScore,
|
|
149
137
|
questionCount: evaluation.questions.length,
|
|
150
138
|
});
|
|
151
139
|
emitEvent({
|
|
152
|
-
type:
|
|
140
|
+
type: 'artifact',
|
|
153
141
|
ts: Date.now(),
|
|
154
|
-
kind:
|
|
142
|
+
kind: 'research_questions',
|
|
155
143
|
content: evaluation.questions,
|
|
156
144
|
});
|
|
157
145
|
}
|
|
158
146
|
else {
|
|
159
|
-
stepLogger.info(
|
|
147
|
+
stepLogger.info('Actionability score acceptable, proceeding to planning', {
|
|
160
148
|
taskId: task.id,
|
|
161
149
|
score: evaluation.actionabilityScore,
|
|
162
150
|
});
|
|
163
151
|
}
|
|
164
152
|
// In local mode, always halt after research for user review
|
|
165
153
|
if (!isCloudMode) {
|
|
166
|
-
emitEvent(adapter.createStatusEvent(
|
|
167
|
-
return { status:
|
|
154
|
+
emitEvent(adapter.createStatusEvent('phase_complete', { phase: 'research' }));
|
|
155
|
+
return { status: 'completed', halt: true };
|
|
168
156
|
}
|
|
169
157
|
// In cloud mode, check if questions need answering
|
|
170
158
|
const researchData = await fileManager.readResearch(task.id);
|
|
171
159
|
if (researchData?.questions && !researchData.answered) {
|
|
172
160
|
// Questions need answering - halt for user input in cloud mode too
|
|
173
|
-
emitEvent(adapter.createStatusEvent(
|
|
174
|
-
return { status:
|
|
161
|
+
emitEvent(adapter.createStatusEvent('phase_complete', { phase: 'research' }));
|
|
162
|
+
return { status: 'completed', halt: true };
|
|
175
163
|
}
|
|
176
164
|
// No questions or questions already answered - proceed to planning
|
|
177
|
-
emitEvent(adapter.createStatusEvent(
|
|
178
|
-
return { status:
|
|
165
|
+
emitEvent(adapter.createStatusEvent('phase_complete', { phase: 'research' }));
|
|
166
|
+
return { status: 'completed' };
|
|
179
167
|
};
|
|
180
168
|
|
|
181
169
|
export { researchStep };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"research.js","sources":["../../../../src/workflow/steps/research.ts"],"sourcesContent":["import { query } from \"@anthropic-ai/claude-agent-sdk\";\nimport { RESEARCH_SYSTEM_PROMPT } from \"../../agents/research.js\";\nimport type { ResearchEvaluation } from \"../../types.js\";\nimport type { WorkflowStepRunner } from \"../types.js\";\nimport { finalizeStepGitActions } from \"../utils.js\";\n\nexport const researchStep: WorkflowStepRunner = async ({ step, context }) => {\n const {\n task,\n cwd,\n isCloudMode,\n options,\n logger,\n fileManager,\n gitManager,\n promptBuilder,\n adapter,\n mcpServers,\n emitEvent,\n } = context;\n\n const stepLogger = logger.child(\"ResearchStep\");\n\n const existingResearch = await fileManager.readResearch(task.id);\n if (existingResearch) {\n stepLogger.info(\"Research already exists\", {\n taskId: task.id,\n hasQuestions: !!existingResearch.questions,\n answered: existingResearch.answered,\n });\n\n // If there are unanswered questions, re-emit them so UI can prompt user\n if (existingResearch.questions && !existingResearch.answered) {\n stepLogger.info(\"Re-emitting unanswered research questions\", {\n taskId: task.id,\n questionCount: existingResearch.questions.length,\n });\n\n emitEvent({\n type: \"artifact\",\n ts: Date.now(),\n kind: \"research_questions\",\n content: existingResearch.questions,\n });\n\n // In local mode, halt to allow user to answer\n if (!isCloudMode) {\n emitEvent(\n adapter.createStatusEvent(\"phase_complete\", { phase: \"research\" }),\n );\n return { status: \"skipped\", halt: true };\n }\n }\n\n return { status: \"skipped\" };\n }\n\n stepLogger.info(\"Starting research phase\", { taskId: task.id });\n emitEvent(adapter.createStatusEvent(\"phase_start\", { phase: \"research\" }));\n\n const researchPrompt = await promptBuilder.buildResearchPrompt(task, cwd);\n const fullPrompt = `${RESEARCH_SYSTEM_PROMPT}\\n\\n${researchPrompt}`;\n\n const baseOptions: Record<string, unknown> = {\n model: step.model,\n cwd,\n permissionMode: \"plan\",\n settingSources: [\"local\"],\n mcpServers,\n // Allow research tools: read-only operations, web search, and MCP resources\n allowedTools: [\n \"Read\",\n \"Glob\",\n \"Grep\",\n \"WebFetch\",\n \"WebSearch\",\n \"ListMcpResources\",\n \"ReadMcpResource\",\n \"TodoWrite\",\n \"BashOutput\",\n ],\n };\n\n const response = query({\n prompt: fullPrompt,\n options: { ...baseOptions, ...(options.queryOverrides || {}) },\n });\n\n let jsonContent = \"\";\n try {\n for await (const message of response) {\n emitEvent(adapter.createRawSDKEvent(message));\n const transformedEvents = adapter.transform(message);\n for (const event of transformedEvents) {\n emitEvent(event);\n }\n if (message.type === \"assistant\" && message.message?.content) {\n for (const c of message.message.content) {\n if (c.type === \"text\" && c.text) {\n jsonContent += c.text;\n }\n }\n }\n }\n } catch (error) {\n stepLogger.error(\"Error during research step query\", error);\n throw error;\n }\n\n if (!jsonContent.trim()) {\n stepLogger.error(\"No JSON output from research agent\", { taskId: task.id });\n emitEvent({\n type: \"error\",\n ts: Date.now(),\n message: \"Research agent returned no output\",\n });\n return { status: \"completed\", halt: true };\n }\n\n // Parse JSON response\n let evaluation: ResearchEvaluation;\n try {\n // Extract JSON from potential markdown code blocks or other wrapping\n const jsonMatch = jsonContent.match(/\\{[\\s\\S]*\\}/);\n if (!jsonMatch) {\n throw new Error(\"No JSON object found in response\");\n }\n evaluation = JSON.parse(jsonMatch[0]);\n stepLogger.info(\"Parsed research evaluation\", {\n taskId: task.id,\n score: evaluation.actionabilityScore,\n hasQuestions: !!evaluation.questions,\n });\n } catch (error) {\n stepLogger.error(\"Failed to parse research JSON\", {\n taskId: task.id,\n error: error instanceof Error ? error.message : String(error),\n content: jsonContent.substring(0, 500),\n });\n emitEvent({\n type: \"error\",\n ts: Date.now(),\n message: `Failed to parse research JSON: ${\n error instanceof Error ? error.message : String(error)\n }`,\n });\n return { status: \"completed\", halt: true };\n }\n\n // Add answered/answers fields to evaluation\n if (evaluation.questions && evaluation.questions.length > 0) {\n evaluation.answered = false;\n evaluation.answers = undefined;\n }\n\n // Always write research.json\n await fileManager.writeResearch(task.id, evaluation);\n stepLogger.info(\"Research evaluation written\", {\n taskId: task.id,\n score: evaluation.actionabilityScore,\n hasQuestions: !!evaluation.questions,\n });\n\n emitEvent({\n type: \"artifact\",\n ts: Date.now(),\n kind: \"research_evaluation\",\n content: evaluation,\n });\n\n await gitManager.addAllPostHogFiles();\n await finalizeStepGitActions(context, step, {\n commitMessage: `Research phase for ${task.title}`,\n });\n\n // Log whether questions need answering\n if (\n evaluation.actionabilityScore < 0.7 &&\n evaluation.questions &&\n evaluation.questions.length > 0\n ) {\n stepLogger.info(\"Actionability score below threshold, questions needed\", {\n taskId: task.id,\n score: evaluation.actionabilityScore,\n questionCount: evaluation.questions.length,\n });\n\n emitEvent({\n type: \"artifact\",\n ts: Date.now(),\n kind: \"research_questions\",\n content: evaluation.questions,\n });\n } else {\n stepLogger.info(\"Actionability score acceptable, proceeding to planning\", {\n taskId: task.id,\n score: evaluation.actionabilityScore,\n });\n }\n\n // In local mode, always halt after research for user review\n if (!isCloudMode) {\n emitEvent(\n adapter.createStatusEvent(\"phase_complete\", { phase: \"research\" }),\n );\n return { status: \"completed\", halt: true };\n }\n\n // In cloud mode, check if questions need answering\n const researchData = await fileManager.readResearch(task.id);\n if (researchData?.questions && !researchData.answered) {\n // Questions need answering - halt for user input in cloud mode too\n emitEvent(\n adapter.createStatusEvent(\"phase_complete\", { phase: \"research\" }),\n );\n return { status: \"completed\", halt: true };\n }\n\n // No questions or questions already answered - proceed to planning\n emitEvent(adapter.createStatusEvent(\"phase_complete\", { phase: \"research\" }));\n return { status: \"completed\" };\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"research.js","sources":["../../../../src/workflow/steps/research.ts"],"sourcesContent":["import { query } from '@anthropic-ai/claude-agent-sdk';\nimport { RESEARCH_SYSTEM_PROMPT } from '../../agents/research.js';\nimport type { WorkflowStepRunner } from '../types.js';\nimport type { ResearchEvaluation } from '../../types.js';\nimport { finalizeStepGitActions } from '../utils.js';\n\nexport const researchStep: WorkflowStepRunner = async ({ step, context }) => {\n const {\n task,\n cwd,\n isCloudMode,\n options,\n logger,\n fileManager,\n gitManager,\n promptBuilder,\n adapter,\n mcpServers,\n emitEvent,\n } = context;\n\n const stepLogger = logger.child('ResearchStep');\n\n const existingResearch = await fileManager.readResearch(task.id);\n if (existingResearch) {\n stepLogger.info('Research already exists', { taskId: task.id, hasQuestions: !!existingResearch.questions, answered: existingResearch.answered });\n \n // If there are unanswered questions, re-emit them so UI can prompt user\n if (existingResearch.questions && !existingResearch.answered) {\n stepLogger.info('Re-emitting unanswered research questions', { \n taskId: task.id,\n questionCount: existingResearch.questions.length \n });\n \n emitEvent({\n type: 'artifact',\n ts: Date.now(),\n kind: 'research_questions',\n content: existingResearch.questions,\n });\n \n // In local mode, halt to allow user to answer\n if (!isCloudMode) {\n emitEvent(adapter.createStatusEvent('phase_complete', { phase: 'research' }));\n return { status: 'skipped', halt: true };\n }\n }\n \n return { status: 'skipped' };\n }\n\n stepLogger.info('Starting research phase', { taskId: task.id });\n emitEvent(adapter.createStatusEvent('phase_start', { phase: 'research' }));\n\n const researchPrompt = await promptBuilder.buildResearchPrompt(task, cwd);\n const fullPrompt = `${RESEARCH_SYSTEM_PROMPT}\\n\\n${researchPrompt}`;\n\n const baseOptions: Record<string, any> = {\n model: step.model,\n cwd,\n permissionMode: 'plan',\n settingSources: ['local'],\n mcpServers,\n // Allow research tools: read-only operations, web search, and MCP resources\n allowedTools: [\n 'Read',\n 'Glob',\n 'Grep',\n 'WebFetch',\n 'WebSearch',\n 'ListMcpResources',\n 'ReadMcpResource',\n 'TodoWrite',\n 'BashOutput',\n ],\n };\n\n const response = query({\n prompt: fullPrompt,\n options: { ...baseOptions, ...(options.queryOverrides || {}) },\n });\n\n let jsonContent = '';\n for await (const message of response) {\n emitEvent(adapter.createRawSDKEvent(message));\n const transformedEvents = adapter.transform(message);\n for (const event of transformedEvents) {\n emitEvent(event);\n }\n if (message.type === 'assistant' && message.message?.content) {\n for (const c of message.message.content) {\n if (c.type === 'text' && c.text) {\n jsonContent += c.text;\n }\n }\n }\n }\n\n if (!jsonContent.trim()) {\n stepLogger.error('No JSON output from research agent', { taskId: task.id });\n emitEvent({\n type: 'error',\n ts: Date.now(),\n message: 'Research agent returned no output',\n });\n return { status: 'completed', halt: true };\n }\n\n // Parse JSON response\n let evaluation: ResearchEvaluation;\n try {\n // Extract JSON from potential markdown code blocks or other wrapping\n const jsonMatch = jsonContent.match(/\\{[\\s\\S]*\\}/);\n if (!jsonMatch) {\n throw new Error('No JSON object found in response');\n }\n evaluation = JSON.parse(jsonMatch[0]);\n stepLogger.info('Parsed research evaluation', {\n taskId: task.id,\n score: evaluation.actionabilityScore,\n hasQuestions: !!evaluation.questions,\n });\n } catch (error) {\n stepLogger.error('Failed to parse research JSON', {\n taskId: task.id,\n error: error instanceof Error ? error.message : String(error),\n content: jsonContent.substring(0, 500),\n });\n emitEvent({\n type: 'error',\n ts: Date.now(),\n message: `Failed to parse research JSON: ${\n error instanceof Error ? error.message : String(error)\n }`,\n });\n return { status: 'completed', halt: true };\n }\n\n // Add answered/answers fields to evaluation\n if (evaluation.questions && evaluation.questions.length > 0) {\n evaluation.answered = false;\n evaluation.answers = undefined;\n }\n\n // Always write research.json\n await fileManager.writeResearch(task.id, evaluation);\n stepLogger.info('Research evaluation written', {\n taskId: task.id,\n score: evaluation.actionabilityScore,\n hasQuestions: !!evaluation.questions,\n });\n\n emitEvent({\n type: 'artifact',\n ts: Date.now(),\n kind: 'research_evaluation',\n content: evaluation,\n });\n\n await gitManager.addAllPostHogFiles();\n await finalizeStepGitActions(context, step, {\n commitMessage: `Research phase for ${task.title}`,\n });\n\n // Log whether questions need answering\n if (evaluation.actionabilityScore < 0.7 && evaluation.questions && evaluation.questions.length > 0) {\n stepLogger.info('Actionability score below threshold, questions needed', {\n taskId: task.id,\n score: evaluation.actionabilityScore,\n questionCount: evaluation.questions.length,\n });\n \n emitEvent({\n type: 'artifact',\n ts: Date.now(),\n kind: 'research_questions',\n content: evaluation.questions,\n });\n } else {\n stepLogger.info('Actionability score acceptable, proceeding to planning', {\n taskId: task.id,\n score: evaluation.actionabilityScore,\n });\n }\n\n // In local mode, always halt after research for user review\n if (!isCloudMode) {\n emitEvent(adapter.createStatusEvent('phase_complete', { phase: 'research' }));\n return { status: 'completed', halt: true };\n }\n\n // In cloud mode, check if questions need answering\n const researchData = await fileManager.readResearch(task.id);\n if (researchData?.questions && !researchData.answered) {\n // Questions need answering - halt for user input in cloud mode too\n emitEvent(adapter.createStatusEvent('phase_complete', { phase: 'research' }));\n return { status: 'completed', halt: true };\n }\n\n // No questions or questions already answered - proceed to planning\n emitEvent(adapter.createStatusEvent('phase_complete', { phase: 'research' }));\n return { status: 'completed' };\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
4
|
-
import type {
|
|
5
|
-
import type { PromptBuilder } from
|
|
6
|
-
import type { TaskProgressReporter } from
|
|
7
|
-
import type {
|
|
8
|
-
import type {
|
|
1
|
+
import type { Task, TaskExecutionOptions, PermissionMode } from '../types.js';
|
|
2
|
+
import type { Logger } from '../utils/logger.js';
|
|
3
|
+
import type { PostHogFileManager } from '../file-manager.js';
|
|
4
|
+
import type { GitManager } from '../git-manager.js';
|
|
5
|
+
import type { PromptBuilder } from '../prompt-builder.js';
|
|
6
|
+
import type { TaskProgressReporter } from '../task-progress-reporter.js';
|
|
7
|
+
import type { ProviderAdapter } from '../adapters/types.js';
|
|
8
|
+
import type { PostHogAPIClient } from '../posthog-api.js';
|
|
9
9
|
export interface WorkflowRuntime {
|
|
10
10
|
task: Task;
|
|
11
11
|
taskSlug: string;
|
|
@@ -18,10 +18,10 @@ export interface WorkflowRuntime {
|
|
|
18
18
|
promptBuilder: PromptBuilder;
|
|
19
19
|
progressReporter: TaskProgressReporter;
|
|
20
20
|
adapter: ProviderAdapter;
|
|
21
|
-
mcpServers?: Record<string,
|
|
21
|
+
mcpServers?: Record<string, any>;
|
|
22
22
|
posthogAPI?: PostHogAPIClient;
|
|
23
|
-
emitEvent: (event:
|
|
24
|
-
stepResults: Record<string,
|
|
23
|
+
emitEvent: (event: any) => void;
|
|
24
|
+
stepResults: Record<string, any>;
|
|
25
25
|
}
|
|
26
26
|
export interface WorkflowStepDefinition {
|
|
27
27
|
id: string;
|
|
@@ -38,7 +38,7 @@ export interface WorkflowStepRuntime {
|
|
|
38
38
|
context: WorkflowRuntime;
|
|
39
39
|
}
|
|
40
40
|
export interface WorkflowStepResult {
|
|
41
|
-
status:
|
|
41
|
+
status: 'completed' | 'skipped';
|
|
42
42
|
halt?: boolean;
|
|
43
43
|
}
|
|
44
44
|
export type WorkflowStepRunner = (runtime: WorkflowStepRuntime) => Promise<WorkflowStepResult>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/workflow/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/workflow/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,MAAM,WAAW,eAAe;IAC5B,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,oBAAoB,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,kBAAkB,CAAC;IAChC,UAAU,EAAE,UAAU,CAAC;IACvB,aAAa,EAAE,aAAa,CAAC;IAC7B,gBAAgB,EAAE,oBAAoB,CAAC;IACvC,OAAO,EAAE,eAAe,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACjC,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,SAAS,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,sBAAsB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,cAAc,GAAG,MAAM,CAAC;IACzC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,kBAAkB,CAAC;CAC3B;AAED,MAAM,WAAW,mBAAmB;IAChC,IAAI,EAAE,sBAAsB,CAAC;IAC7B,OAAO,EAAE,eAAe,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IAC/B,MAAM,EAAE,WAAW,GAAG,SAAS,CAAC;IAChC,IAAI,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,EAAE,mBAAmB,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAAC;AAE/F,MAAM,MAAM,kBAAkB,GAAG,sBAAsB,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/workflow/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAE1E,UAAU,kBAAkB;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/workflow/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAE1E,UAAU,kBAAkB;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CACxC,OAAO,EAAE,eAAe,EACxB,IAAI,EAAE,sBAAsB,EAC5B,OAAO,EAAE,kBAAkB,GAC5B,OAAO,CAAC,OAAO,CAAC,CAkClB"}
|