@posthog/agent 1.13.0 → 1.15.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.
- package/README.md +110 -0
- package/dist/src/agent.d.ts +3 -1
- package/dist/src/agent.d.ts.map +1 -1
- package/dist/src/agent.js +7 -0
- package/dist/src/agent.js.map +1 -1
- package/dist/src/agents/execution.d.ts +1 -1
- package/dist/src/agents/execution.d.ts.map +1 -1
- package/dist/src/agents/execution.js +27 -43
- package/dist/src/agents/execution.js.map +1 -1
- package/dist/src/agents/planning.d.ts +1 -1
- package/dist/src/agents/planning.d.ts.map +1 -1
- package/dist/src/agents/planning.js +60 -66
- package/dist/src/agents/planning.js.map +1 -1
- package/dist/src/agents/research.d.ts +1 -1
- package/dist/src/agents/research.d.ts.map +1 -1
- package/dist/src/agents/research.js +68 -88
- package/dist/src/agents/research.js.map +1 -1
- package/dist/src/prompt-builder.d.ts.map +1 -1
- package/dist/src/prompt-builder.js +68 -35
- package/dist/src/prompt-builder.js.map +1 -1
- package/dist/src/types.d.ts +4 -1
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js.map +1 -1
- package/dist/src/workflow/steps/build.d.ts.map +1 -1
- package/dist/src/workflow/steps/build.js +22 -0
- package/dist/src/workflow/steps/build.js.map +1 -1
- package/dist/src/workflow/steps/plan.d.ts.map +1 -1
- package/dist/src/workflow/steps/plan.js +13 -0
- package/dist/src/workflow/steps/plan.js.map +1 -1
- package/dist/src/workflow/steps/research.d.ts.map +1 -1
- package/dist/src/workflow/steps/research.js +12 -0
- package/dist/src/workflow/steps/research.js.map +1 -1
- package/package.json +1 -1
- package/src/agent.ts +10 -2
- package/src/agents/execution.ts +27 -43
- package/src/agents/planning.ts +60 -66
- package/src/agents/research.ts +68 -88
- package/src/prompt-builder.ts +71 -35
- package/src/types.ts +12 -0
- package/src/workflow/steps/build.ts +23 -0
- package/src/workflow/steps/plan.ts +13 -0
- package/src/workflow/steps/research.ts +12 -0
package/src/agents/planning.ts
CHANGED
|
@@ -1,66 +1,60 @@
|
|
|
1
|
-
export const PLANNING_SYSTEM_PROMPT =
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
-
|
|
57
|
-
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
If supporting files are provided, incorporate them into your analysis:
|
|
62
|
-
- **Context files**: Additional requirements or constraints
|
|
63
|
-
- **Reference files**: Examples or documentation to follow
|
|
64
|
-
- **Previous plans**: Build upon or refine existing planning work
|
|
65
|
-
|
|
66
|
-
Your planning should be thorough enough that another agent in execution mode can implement the changes successfully.`;
|
|
1
|
+
export const PLANNING_SYSTEM_PROMPT = `<role>
|
|
2
|
+
PostHog AI Planning Agent — analyze codebases and create actionable implementation plans.
|
|
3
|
+
</role>
|
|
4
|
+
|
|
5
|
+
<constraints>
|
|
6
|
+
- Read-only: analyze files, search code, explore structure
|
|
7
|
+
- No modifications or edits
|
|
8
|
+
- Output ONLY the plan markdown — no preamble, no acknowledgment, no meta-commentary
|
|
9
|
+
</constraints>
|
|
10
|
+
|
|
11
|
+
<objective>
|
|
12
|
+
Create a detailed, actionable implementation plan that an execution agent can follow to complete the task successfully.
|
|
13
|
+
</objective>
|
|
14
|
+
|
|
15
|
+
<process>
|
|
16
|
+
1. Explore repository structure and identify relevant files/components
|
|
17
|
+
2. Understand existing patterns, conventions, and dependencies
|
|
18
|
+
3. Break down task requirements and identify technical constraints
|
|
19
|
+
4. Define step-by-step implementation approach
|
|
20
|
+
5. Specify files to modify/create with exact paths
|
|
21
|
+
6. Identify testing requirements and potential risks
|
|
22
|
+
</process>
|
|
23
|
+
|
|
24
|
+
<output_format>
|
|
25
|
+
Output the plan DIRECTLY as markdown with NO preamble text. Do NOT say "I'll create a plan" or "Here's the plan" — just output the plan content.
|
|
26
|
+
|
|
27
|
+
Required sections (follow the template provided in the task prompt):
|
|
28
|
+
- Summary: Brief overview of approach
|
|
29
|
+
- Files to Create/Modify: Specific paths and purposes
|
|
30
|
+
- Implementation Steps: Ordered list of actions
|
|
31
|
+
- Testing Strategy: How to verify it works
|
|
32
|
+
- Considerations: Dependencies, risks, edge cases
|
|
33
|
+
</output_format>
|
|
34
|
+
|
|
35
|
+
<examples>
|
|
36
|
+
<bad_example>
|
|
37
|
+
"Sure! I'll create a detailed implementation plan for you to add authentication. Here's what we'll do..."
|
|
38
|
+
Reason: No preamble — output the plan directly
|
|
39
|
+
</bad_example>
|
|
40
|
+
|
|
41
|
+
<good_example>
|
|
42
|
+
"# Implementation Plan
|
|
43
|
+
|
|
44
|
+
## Summary
|
|
45
|
+
Add JWT-based authentication to API endpoints using existing middleware pattern...
|
|
46
|
+
|
|
47
|
+
## Files to Modify
|
|
48
|
+
- src/middleware/auth.ts: Add JWT verification
|
|
49
|
+
..."
|
|
50
|
+
Reason: Direct plan output with no meta-commentary
|
|
51
|
+
</good_example>
|
|
52
|
+
</examples>
|
|
53
|
+
|
|
54
|
+
<context_integration>
|
|
55
|
+
If research findings, context files, or reference materials are provided:
|
|
56
|
+
- Incorporate research findings into your analysis
|
|
57
|
+
- Follow patterns and approaches identified in research
|
|
58
|
+
- Build upon or refine any existing planning work
|
|
59
|
+
- Reference specific files and components mentioned in context
|
|
60
|
+
</context_integration>`;
|
package/src/agents/research.ts
CHANGED
|
@@ -1,100 +1,80 @@
|
|
|
1
|
-
export const RESEARCH_SYSTEM_PROMPT =
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
2. **Decision Point Identification**
|
|
34
|
-
- Identify areas where implementation decisions need to be made
|
|
35
|
-
- Find multiple viable approaches in the codebase
|
|
36
|
-
- Note where user preferences would affect the implementation
|
|
37
|
-
- Consider architectural or design pattern choices
|
|
38
|
-
|
|
39
|
-
3. **Question Generation**
|
|
40
|
-
- Generate 3-5 clarifying questions
|
|
41
|
-
- Each question should offer 2-3 concrete options based on codebase analysis
|
|
42
|
-
- Options should reference actual patterns/approaches found in the code
|
|
43
|
-
- Always include option c) as "Something else (please specify)" for flexibility
|
|
44
|
-
- Focus on high-impact decisions that affect the implementation approach
|
|
45
|
-
|
|
46
|
-
## Output Format
|
|
47
|
-
|
|
48
|
-
The artifact MUST follow this EXACT markdown format (this is critical for parsing):
|
|
1
|
+
export const RESEARCH_SYSTEM_PROMPT = `<role>
|
|
2
|
+
PostHog AI Research Agent — analyze codebases to understand implementation context and identify areas of focus for development tasks.
|
|
3
|
+
</role>
|
|
4
|
+
|
|
5
|
+
<constraints>
|
|
6
|
+
- Read-only: analyze files, search code, explore structure
|
|
7
|
+
- No modifications or code changes
|
|
8
|
+
</constraints>
|
|
9
|
+
|
|
10
|
+
<objective>
|
|
11
|
+
Your PRIMARY goal is to understand the codebase thoroughly and provide context for the planning phase.
|
|
12
|
+
|
|
13
|
+
ONLY generate clarifying questions if:
|
|
14
|
+
- The task description is genuinely vague or ambiguous
|
|
15
|
+
- There are multiple valid architectural approaches with significant tradeoffs
|
|
16
|
+
- Critical information is missing that cannot be inferred from the codebase
|
|
17
|
+
|
|
18
|
+
DO NOT ask questions like "how should I fix this" or "what approach do you prefer" — that defeats the purpose of autonomous task execution. The user has already specified what they want done.
|
|
19
|
+
</objective>
|
|
20
|
+
|
|
21
|
+
<process>
|
|
22
|
+
1. Explore repository structure and identify relevant files/components
|
|
23
|
+
2. Understand existing patterns, conventions, and dependencies
|
|
24
|
+
3. Locate similar implementations or related code
|
|
25
|
+
4. Identify the key areas of the codebase that will be affected
|
|
26
|
+
5. Document your findings to provide context for planning
|
|
27
|
+
6. ONLY if genuinely needed: generate 2-3 specific clarification questions
|
|
28
|
+
</process>
|
|
29
|
+
|
|
30
|
+
<output_format>
|
|
31
|
+
Output ONLY the markdown artifact with no preamble:
|
|
49
32
|
|
|
50
33
|
\`\`\`markdown
|
|
51
|
-
# Research
|
|
52
|
-
|
|
53
|
-
Based on my analysis of the codebase, here are the key questions to guide implementation:
|
|
54
|
-
|
|
55
|
-
## Question 1: [Question text - be specific and clear]
|
|
34
|
+
# Research Findings
|
|
56
35
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
- b) [Alternative approach based on another pattern - reference specific files/components]
|
|
60
|
-
- c) Something else (please specify)
|
|
36
|
+
## Codebase Analysis
|
|
37
|
+
[Brief summary of relevant code structure, patterns, and files]
|
|
61
38
|
|
|
62
|
-
##
|
|
39
|
+
## Key Areas of Focus
|
|
40
|
+
[List specific files/components that need modification]
|
|
63
41
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
- b) [Alternative with specific code references]
|
|
67
|
-
- c) Something else (please specify)
|
|
42
|
+
## Implementation Context
|
|
43
|
+
[Important patterns, dependencies, or constraints found in the code]
|
|
68
44
|
|
|
69
|
-
##
|
|
45
|
+
## Clarifying Questions
|
|
46
|
+
[ONLY include this section if it will increase the quality of the plan]
|
|
70
47
|
|
|
48
|
+
## Question 1: [Specific architectural decision]
|
|
71
49
|
**Options:**
|
|
72
|
-
- a) [
|
|
73
|
-
- b) [Alternative]
|
|
50
|
+
- a) [Concrete option with file references]
|
|
51
|
+
- b) [Alternative with file references]
|
|
74
52
|
- c) Something else (please specify)
|
|
75
53
|
\`\`\`
|
|
76
54
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
-
|
|
80
|
-
-
|
|
81
|
-
-
|
|
82
|
-
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
55
|
+
Format requirements:
|
|
56
|
+
- Use "## Question N:" for question headers (h2)
|
|
57
|
+
- Follow with "**Options:**" on its own line
|
|
58
|
+
- Start options with "- a)", "- b)", "- c)"
|
|
59
|
+
- Always include "c) Something else (please specify)"
|
|
60
|
+
- Max 4 questions total
|
|
61
|
+
</output_format>
|
|
62
|
+
|
|
63
|
+
<examples>
|
|
64
|
+
<good_example>
|
|
65
|
+
Task: "Fix authentication bug in login flow"
|
|
66
|
+
Output: Research findings showing auth flow files, patterns used, NO questions needed
|
|
67
|
+
</good_example>
|
|
68
|
+
|
|
69
|
+
<bad_example>
|
|
70
|
+
Task: "Fix authentication bug"
|
|
71
|
+
Output: "How should I fix the authentication? a) Fix it one way b) Fix it another way"
|
|
72
|
+
Reason: Don't ask HOW to do the task — that's what the agent is for
|
|
73
|
+
</bad_example>
|
|
74
|
+
|
|
75
|
+
<good_example>
|
|
76
|
+
Task: "Add caching to API endpoints"
|
|
77
|
+
Output: Research showing existing cache implementations, question about cache backend choice IF multiple production systems are already in use
|
|
78
|
+
</good_example>
|
|
79
|
+
</examples>`;
|
|
100
80
|
|
package/src/prompt-builder.ts
CHANGED
|
@@ -213,42 +213,50 @@ export class PromptBuilder {
|
|
|
213
213
|
repositoryPath
|
|
214
214
|
);
|
|
215
215
|
|
|
216
|
-
// Process URL references in description
|
|
216
|
+
// Process URL references in description
|
|
217
217
|
const { description: processedDescription, referencedResources } = await this.processUrlReferences(
|
|
218
218
|
descriptionAfterFiles
|
|
219
219
|
);
|
|
220
220
|
|
|
221
|
-
let prompt = '';
|
|
222
|
-
prompt +=
|
|
221
|
+
let prompt = '<task>\n';
|
|
222
|
+
prompt += `<title>${task.title}</title>\n`;
|
|
223
|
+
prompt += `<description>${processedDescription}</description>\n`;
|
|
223
224
|
|
|
224
225
|
if ((task as any).primary_repository) {
|
|
225
|
-
prompt +=
|
|
226
|
+
prompt += `<repository>${(task as any).primary_repository}</repository>\n`;
|
|
226
227
|
}
|
|
228
|
+
prompt += '</task>\n';
|
|
227
229
|
|
|
228
230
|
// Add referenced files from @ mentions
|
|
229
231
|
if (referencedFiles.length > 0) {
|
|
230
|
-
prompt +=
|
|
232
|
+
prompt += '\n<referenced_files>\n';
|
|
231
233
|
for (const file of referencedFiles) {
|
|
232
|
-
prompt +=
|
|
234
|
+
prompt += `<file path="${file.path}">\n\`\`\`\n${file.content}\n\`\`\`\n</file>\n`;
|
|
233
235
|
}
|
|
236
|
+
prompt += '</referenced_files>\n';
|
|
234
237
|
}
|
|
235
238
|
|
|
236
239
|
// Add referenced resources from URL mentions
|
|
237
240
|
if (referencedResources.length > 0) {
|
|
238
|
-
prompt +=
|
|
241
|
+
prompt += '\n<referenced_resources>\n';
|
|
239
242
|
for (const resource of referencedResources) {
|
|
240
|
-
prompt +=
|
|
243
|
+
prompt += `<resource type="${resource.type}" url="${resource.url}">\n`;
|
|
244
|
+
prompt += `<title>${resource.title}</title>\n`;
|
|
245
|
+
prompt += `<content>${resource.content}</content>\n`;
|
|
246
|
+
prompt += '</resource>\n';
|
|
241
247
|
}
|
|
248
|
+
prompt += '</referenced_resources>\n';
|
|
242
249
|
}
|
|
243
250
|
|
|
244
251
|
try {
|
|
245
252
|
const taskFiles = await this.getTaskFiles(task.id);
|
|
246
253
|
const contextFiles = taskFiles.filter((f: any) => f.type === 'context' || f.type === 'reference');
|
|
247
254
|
if (contextFiles.length > 0) {
|
|
248
|
-
prompt +=
|
|
255
|
+
prompt += '\n<supporting_files>\n';
|
|
249
256
|
for (const file of contextFiles) {
|
|
250
|
-
prompt +=
|
|
257
|
+
prompt += `<file name="${file.name}" type="${file.type}">\n${file.content}\n</file>\n`;
|
|
251
258
|
}
|
|
259
|
+
prompt += '</supporting_files>\n';
|
|
252
260
|
}
|
|
253
261
|
} catch (error) {
|
|
254
262
|
this.logger.debug('No existing task files found for research', { taskId: task.id });
|
|
@@ -264,42 +272,50 @@ export class PromptBuilder {
|
|
|
264
272
|
repositoryPath
|
|
265
273
|
);
|
|
266
274
|
|
|
267
|
-
// Process URL references in description
|
|
275
|
+
// Process URL references in description
|
|
268
276
|
const { description: processedDescription, referencedResources } = await this.processUrlReferences(
|
|
269
277
|
descriptionAfterFiles
|
|
270
278
|
);
|
|
271
279
|
|
|
272
|
-
let prompt = '';
|
|
273
|
-
prompt +=
|
|
280
|
+
let prompt = '<task>\n';
|
|
281
|
+
prompt += `<title>${task.title}</title>\n`;
|
|
282
|
+
prompt += `<description>${processedDescription}</description>\n`;
|
|
274
283
|
|
|
275
284
|
if ((task as any).primary_repository) {
|
|
276
|
-
prompt +=
|
|
285
|
+
prompt += `<repository>${(task as any).primary_repository}</repository>\n`;
|
|
277
286
|
}
|
|
287
|
+
prompt += '</task>\n';
|
|
278
288
|
|
|
279
289
|
// Add referenced files from @ mentions
|
|
280
290
|
if (referencedFiles.length > 0) {
|
|
281
|
-
prompt +=
|
|
291
|
+
prompt += '\n<referenced_files>\n';
|
|
282
292
|
for (const file of referencedFiles) {
|
|
283
|
-
prompt +=
|
|
293
|
+
prompt += `<file path="${file.path}">\n\`\`\`\n${file.content}\n\`\`\`\n</file>\n`;
|
|
284
294
|
}
|
|
295
|
+
prompt += '</referenced_files>\n';
|
|
285
296
|
}
|
|
286
297
|
|
|
287
298
|
// Add referenced resources from URL mentions
|
|
288
299
|
if (referencedResources.length > 0) {
|
|
289
|
-
prompt +=
|
|
300
|
+
prompt += '\n<referenced_resources>\n';
|
|
290
301
|
for (const resource of referencedResources) {
|
|
291
|
-
prompt +=
|
|
302
|
+
prompt += `<resource type="${resource.type}" url="${resource.url}">\n`;
|
|
303
|
+
prompt += `<title>${resource.title}</title>\n`;
|
|
304
|
+
prompt += `<content>${resource.content}</content>\n`;
|
|
305
|
+
prompt += '</resource>\n';
|
|
292
306
|
}
|
|
307
|
+
prompt += '</referenced_resources>\n';
|
|
293
308
|
}
|
|
294
309
|
|
|
295
310
|
try {
|
|
296
311
|
const taskFiles = await this.getTaskFiles(task.id);
|
|
297
312
|
const contextFiles = taskFiles.filter((f: any) => f.type === 'context' || f.type === 'reference');
|
|
298
313
|
if (contextFiles.length > 0) {
|
|
299
|
-
prompt +=
|
|
314
|
+
prompt += '\n<supporting_files>\n';
|
|
300
315
|
for (const file of contextFiles) {
|
|
301
|
-
prompt +=
|
|
316
|
+
prompt += `<file name="${file.name}" type="${file.type}">\n${file.content}\n</file>\n`;
|
|
302
317
|
}
|
|
318
|
+
prompt += '</supporting_files>\n';
|
|
303
319
|
}
|
|
304
320
|
} catch (error) {
|
|
305
321
|
this.logger.debug('No existing task files found for planning', { taskId: task.id });
|
|
@@ -315,7 +331,12 @@ export class PromptBuilder {
|
|
|
315
331
|
|
|
316
332
|
const planTemplate = await this.generatePlanTemplate(templateVariables);
|
|
317
333
|
|
|
318
|
-
prompt +=
|
|
334
|
+
prompt += '\n<instructions>\n';
|
|
335
|
+
prompt += 'Analyze the codebase and create a detailed implementation plan. Use the template structure below, filling each section with specific, actionable information.\n';
|
|
336
|
+
prompt += '</instructions>\n\n';
|
|
337
|
+
prompt += '<plan_template>\n';
|
|
338
|
+
prompt += planTemplate;
|
|
339
|
+
prompt += '\n</plan_template>';
|
|
319
340
|
|
|
320
341
|
return prompt;
|
|
321
342
|
}
|
|
@@ -327,56 +348,71 @@ export class PromptBuilder {
|
|
|
327
348
|
repositoryPath
|
|
328
349
|
);
|
|
329
350
|
|
|
330
|
-
// Process URL references in description
|
|
351
|
+
// Process URL references in description
|
|
331
352
|
const { description: processedDescription, referencedResources } = await this.processUrlReferences(
|
|
332
353
|
descriptionAfterFiles
|
|
333
354
|
);
|
|
334
355
|
|
|
335
|
-
let prompt = '';
|
|
336
|
-
prompt +=
|
|
356
|
+
let prompt = '<task>\n';
|
|
357
|
+
prompt += `<title>${task.title}</title>\n`;
|
|
358
|
+
prompt += `<description>${processedDescription}</description>\n`;
|
|
337
359
|
|
|
338
360
|
if ((task as any).primary_repository) {
|
|
339
|
-
prompt +=
|
|
361
|
+
prompt += `<repository>${(task as any).primary_repository}</repository>\n`;
|
|
340
362
|
}
|
|
363
|
+
prompt += '</task>\n';
|
|
341
364
|
|
|
342
365
|
// Add referenced files from @ mentions
|
|
343
366
|
if (referencedFiles.length > 0) {
|
|
344
|
-
prompt +=
|
|
367
|
+
prompt += '\n<referenced_files>\n';
|
|
345
368
|
for (const file of referencedFiles) {
|
|
346
|
-
prompt +=
|
|
369
|
+
prompt += `<file path="${file.path}">\n\`\`\`\n${file.content}\n\`\`\`\n</file>\n`;
|
|
347
370
|
}
|
|
371
|
+
prompt += '</referenced_files>\n';
|
|
348
372
|
}
|
|
349
373
|
|
|
350
374
|
// Add referenced resources from URL mentions
|
|
351
375
|
if (referencedResources.length > 0) {
|
|
352
|
-
prompt +=
|
|
376
|
+
prompt += '\n<referenced_resources>\n';
|
|
353
377
|
for (const resource of referencedResources) {
|
|
354
|
-
prompt +=
|
|
378
|
+
prompt += `<resource type="${resource.type}" url="${resource.url}">\n`;
|
|
379
|
+
prompt += `<title>${resource.title}</title>\n`;
|
|
380
|
+
prompt += `<content>${resource.content}</content>\n`;
|
|
381
|
+
prompt += '</resource>\n';
|
|
355
382
|
}
|
|
383
|
+
prompt += '</referenced_resources>\n';
|
|
356
384
|
}
|
|
357
385
|
|
|
358
386
|
try {
|
|
359
387
|
const taskFiles = await this.getTaskFiles(task.id);
|
|
360
388
|
const hasPlan = taskFiles.some((f: any) => f.type === 'plan');
|
|
389
|
+
|
|
361
390
|
if (taskFiles.length > 0) {
|
|
362
|
-
prompt +=
|
|
391
|
+
prompt += '\n<context>\n';
|
|
363
392
|
for (const file of taskFiles) {
|
|
364
393
|
if (file.type === 'plan') {
|
|
365
|
-
prompt +=
|
|
394
|
+
prompt += `<plan>\n${file.content}\n</plan>\n`;
|
|
366
395
|
} else {
|
|
367
|
-
prompt +=
|
|
396
|
+
prompt += `<file name="${file.name}" type="${file.type}">\n${file.content}\n</file>\n`;
|
|
368
397
|
}
|
|
369
398
|
}
|
|
399
|
+
prompt += '</context>\n';
|
|
370
400
|
}
|
|
401
|
+
|
|
402
|
+
prompt += '\n<instructions>\n';
|
|
371
403
|
if (hasPlan) {
|
|
372
|
-
prompt +=
|
|
404
|
+
prompt += 'Implement the changes described in the execution plan. Follow the plan step-by-step and make the necessary file modifications.\n';
|
|
373
405
|
} else {
|
|
374
|
-
prompt +=
|
|
406
|
+
prompt += 'Implement the changes described in the task. Make the necessary file modifications to complete the task.\n';
|
|
375
407
|
}
|
|
408
|
+
prompt += '</instructions>';
|
|
376
409
|
} catch (error) {
|
|
377
410
|
this.logger.debug('No supporting files found for execution', { taskId: task.id });
|
|
378
|
-
prompt +=
|
|
411
|
+
prompt += '\n<instructions>\n';
|
|
412
|
+
prompt += 'Implement the changes described in the task.\n';
|
|
413
|
+
prompt += '</instructions>';
|
|
379
414
|
}
|
|
415
|
+
|
|
380
416
|
return prompt;
|
|
381
417
|
}
|
|
382
418
|
}
|
package/src/types.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
|
|
2
|
+
// import and export to keep a single type file
|
|
3
|
+
import type { CanUseTool, PermissionResult } from '@anthropic-ai/claude-agent-sdk/sdkTypes.js';
|
|
4
|
+
export type { CanUseTool, PermissionResult };
|
|
5
|
+
|
|
1
6
|
// PostHog Task model (matches Array's OpenAPI schema)
|
|
2
7
|
export interface Task {
|
|
3
8
|
id: string;
|
|
@@ -68,6 +73,9 @@ export interface TaskExecutionOptions {
|
|
|
68
73
|
isCloudMode?: boolean; // Determines local vs cloud behavior (local pauses after each phase)
|
|
69
74
|
autoProgress?: boolean;
|
|
70
75
|
queryOverrides?: Record<string, any>;
|
|
76
|
+
// Fine-grained permission control (only applied to build phase)
|
|
77
|
+
// See: https://docs.claude.com/en/api/agent-sdk/permissions
|
|
78
|
+
canUseTool?: CanUseTool;
|
|
71
79
|
}
|
|
72
80
|
|
|
73
81
|
// Base event with timestamp
|
|
@@ -305,6 +313,10 @@ export interface AgentConfig {
|
|
|
305
313
|
|
|
306
314
|
// Logging configuration
|
|
307
315
|
debug?: boolean;
|
|
316
|
+
|
|
317
|
+
// Fine-grained permission control for direct run() calls
|
|
318
|
+
// See: https://docs.claude.com/en/api/agent-sdk/permissions
|
|
319
|
+
canUseTool?: CanUseTool;
|
|
308
320
|
}
|
|
309
321
|
|
|
310
322
|
export interface PostHogAPIConfig {
|
|
@@ -49,8 +49,31 @@ export const buildStep: WorkflowStepRunner = async ({ step, context }) => {
|
|
|
49
49
|
permissionMode: configuredPermissionMode,
|
|
50
50
|
settingSources: ['local'],
|
|
51
51
|
mcpServers,
|
|
52
|
+
// Allow all tools for build phase - full read/write access needed for implementation
|
|
53
|
+
allowedTools: [
|
|
54
|
+
'Task',
|
|
55
|
+
'Bash',
|
|
56
|
+
'BashOutput',
|
|
57
|
+
'KillBash',
|
|
58
|
+
'Edit',
|
|
59
|
+
'Read',
|
|
60
|
+
'Write',
|
|
61
|
+
'Glob',
|
|
62
|
+
'Grep',
|
|
63
|
+
'NotebookEdit',
|
|
64
|
+
'WebFetch',
|
|
65
|
+
'WebSearch',
|
|
66
|
+
'ListMcpResources',
|
|
67
|
+
'ReadMcpResource',
|
|
68
|
+
'TodoWrite',
|
|
69
|
+
],
|
|
52
70
|
};
|
|
53
71
|
|
|
72
|
+
// Add fine-grained permission hook if provided
|
|
73
|
+
if (options.canUseTool) {
|
|
74
|
+
baseOptions.canUseTool = options.canUseTool;
|
|
75
|
+
}
|
|
76
|
+
|
|
54
77
|
const response = query({
|
|
55
78
|
prompt: fullPrompt,
|
|
56
79
|
options: { ...baseOptions, ...(options.queryOverrides || {}) },
|
|
@@ -69,6 +69,19 @@ export const planStep: WorkflowStepRunner = async ({ step, context }) => {
|
|
|
69
69
|
permissionMode: 'plan',
|
|
70
70
|
settingSources: ['local'],
|
|
71
71
|
mcpServers,
|
|
72
|
+
// Allow research tools: read-only operations, web search, MCP resources, and ExitPlanMode
|
|
73
|
+
allowedTools: [
|
|
74
|
+
'Read',
|
|
75
|
+
'Glob',
|
|
76
|
+
'Grep',
|
|
77
|
+
'WebFetch',
|
|
78
|
+
'WebSearch',
|
|
79
|
+
'ListMcpResources',
|
|
80
|
+
'ReadMcpResource',
|
|
81
|
+
'ExitPlanMode',
|
|
82
|
+
'TodoWrite',
|
|
83
|
+
'BashOutput',
|
|
84
|
+
],
|
|
72
85
|
};
|
|
73
86
|
|
|
74
87
|
const response = query({
|
|
@@ -40,6 +40,18 @@ export const researchStep: WorkflowStepRunner = async ({ step, context }) => {
|
|
|
40
40
|
permissionMode: 'plan',
|
|
41
41
|
settingSources: ['local'],
|
|
42
42
|
mcpServers,
|
|
43
|
+
// Allow research tools: read-only operations, web search, and MCP resources
|
|
44
|
+
allowedTools: [
|
|
45
|
+
'Read',
|
|
46
|
+
'Glob',
|
|
47
|
+
'Grep',
|
|
48
|
+
'WebFetch',
|
|
49
|
+
'WebSearch',
|
|
50
|
+
'ListMcpResources',
|
|
51
|
+
'ReadMcpResource',
|
|
52
|
+
'TodoWrite',
|
|
53
|
+
'BashOutput',
|
|
54
|
+
],
|
|
43
55
|
};
|
|
44
56
|
|
|
45
57
|
const response = query({
|