Skip to content

Commit 5574da3

Browse files
committed
feat(agent): implement simple task mode with protected file checks and enhanced prompts #453
1 parent 406bdbe commit 5574da3

File tree

1 file changed

+147
-2
lines changed

1 file changed

+147
-2
lines changed

mpp-ui/src/jsMain/typescript/agents/CodingAgentService.ts

Lines changed: 147 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,49 @@ export interface AgentResult {
5454
edits: AgentEdit[];
5555
}
5656

57+
/**
58+
* Critical infrastructure files that should not be modified by simple tasks
59+
*/
60+
const PROTECTED_FILES = [
61+
'build.gradle.kts',
62+
'build.gradle',
63+
'pom.xml',
64+
'package.json',
65+
'package-lock.json',
66+
'yarn.lock',
67+
'pnpm-lock.yaml',
68+
'requirements.txt',
69+
'Pipfile',
70+
'Cargo.toml',
71+
'Cargo.lock',
72+
'go.mod',
73+
'go.sum',
74+
'CMakeLists.txt',
75+
'Makefile',
76+
'settings.gradle.kts',
77+
'settings.gradle'
78+
];
79+
80+
/**
81+
* Keywords that indicate a simple task
82+
*/
83+
const SIMPLE_TASK_KEYWORDS = [
84+
'hello world',
85+
'create a simple',
86+
'add a simple',
87+
'write a simple',
88+
'simple file',
89+
'add a file',
90+
'write a function',
91+
'add a function',
92+
'simple example',
93+
'basic example',
94+
'quick test',
95+
'create a test',
96+
'add a method',
97+
'simple class'
98+
];
99+
57100
/**
58101
* Coding Agent Service
59102
* Now uses mpp-core for prompt generation and context building
@@ -73,6 +116,7 @@ export class CodingAgentService {
73116
private startTime: number = 0;
74117
private lastRecoveryResult: RecoveryResult | null = null;
75118
private config: LLMConfig;
119+
private isSimpleTaskMode: boolean = false;
76120

77121
constructor(projectPath: string, config: LLMConfig, quiet: boolean = false) {
78122
this.projectPath = path.resolve(projectPath);
@@ -86,6 +130,80 @@ export class CodingAgentService {
86130
this.logSummaryAgent = new LogSummaryAgent(config, 2000); // Summarize if output > 2000 chars
87131
}
88132

133+
/**
134+
* Check if this is a simple task that should have limited scope
135+
*/
136+
private isSimpleTask(taskDescription: string): boolean {
137+
const lowerTask = taskDescription.toLowerCase();
138+
return SIMPLE_TASK_KEYWORDS.some(keyword => lowerTask.includes(keyword));
139+
}
140+
141+
/**
142+
* Check if a file is protected (critical infrastructure)
143+
*/
144+
private isProtectedFile(filePath: string): boolean {
145+
const basename = path.basename(filePath);
146+
return PROTECTED_FILES.includes(basename);
147+
}
148+
149+
/**
150+
* Check if task appears complete based on heuristics
151+
*/
152+
private checkTaskCompletion(task: string, iteration: number): boolean {
153+
// Only for simple tasks after a few iterations
154+
if (!this.isSimpleTaskMode || iteration < 2) {
155+
return false;
156+
}
157+
158+
// Check if we created a core file
159+
const hasCreatedFile = this.edits.some(e => e.operation === 'create');
160+
161+
if (hasCreatedFile) {
162+
// Check if recent steps are mostly failing
163+
const recentSteps = this.steps.slice(-3);
164+
if (recentSteps.length > 0) {
165+
const failureCount = recentSteps.filter(s => !s.success).length;
166+
const mostlyFailing = failureCount >= 2;
167+
168+
if (mostlyFailing) {
169+
this.formatter.info('🎯 Core work completed, subsequent failures appear unrelated');
170+
return true;
171+
}
172+
}
173+
}
174+
175+
return false;
176+
}
177+
178+
/**
179+
* Enhance system prompt for simple tasks
180+
*/
181+
private enhanceSystemPromptForTask(systemPrompt: string, task: string): string {
182+
if (!this.isSimpleTask(task)) {
183+
return systemPrompt;
184+
}
185+
186+
return systemPrompt + `\n\n## 🎯 IMPORTANT: Simple Task Mode
187+
188+
This is a SIMPLE task that requires minimal changes. Follow these STRICT rules:
189+
190+
1. **DO NOT modify build/config files**: ${PROTECTED_FILES.slice(0, 5).join(', ')}, etc.
191+
2. **DO NOT run full project builds or test suites** - focus only on the task
192+
3. **DO NOT try to fix pre-existing project issues** - ignore unrelated errors
193+
4. **CREATE ONLY** the minimal files needed for this specific task
194+
5. **VERIFY** your new code has correct syntax (read it back if needed)
195+
6. **RESPOND** with "TASK_COMPLETE" immediately after creating the requested file
196+
197+
**Expected workflow:**
198+
- Step 1: Understand project structure (quick scan)
199+
- Step 2: Create the requested file
200+
- Step 3: Verify file was created correctly
201+
- Step 4: Respond with "TASK_COMPLETE"
202+
203+
Maximum expected steps: 5-7
204+
If you encounter errors unrelated to your new file, mark the task complete anyway.`;
205+
}
206+
89207
/**
90208
* Execute a development task
91209
*/
@@ -96,14 +214,24 @@ export class CodingAgentService {
96214
this.formatter.info(`Project: ${this.projectPath}`);
97215
this.formatter.info(`Task: ${task.requirement}`);
98216

217+
// Detect if this is a simple task
218+
this.isSimpleTaskMode = this.isSimpleTask(task.requirement);
219+
if (this.isSimpleTaskMode) {
220+
this.formatter.info('📋 Simple task detected - using limited scope mode');
221+
this.formatter.info('⚠️ Build files are protected from modification');
222+
}
223+
99224
try {
100225
// Initialize workspace
101226
this.formatter.section('Initializing Workspace');
102227
await this.initializeWorkspace();
103228

104229
// Build context and system prompt using mpp-core
105230
const context = await this.buildContext(task);
106-
const systemPrompt = this.promptRenderer.render(context, 'EN');
231+
let systemPrompt = this.promptRenderer.render(context, 'EN');
232+
233+
// Enhance prompt for simple tasks
234+
systemPrompt = this.enhanceSystemPromptForTask(systemPrompt, task.requirement);
107235

108236
// Main agent loop
109237
let iteration = 0;
@@ -127,12 +255,18 @@ export class CodingAgentService {
127255
const stepResult = await this.executeAction(action, iteration);
128256
this.steps.push(stepResult);
129257

130-
// Check if task is complete
258+
// Check if task is complete (explicit signal from LLM)
131259
if (action.includes('TASK_COMPLETE') || action.includes('task complete')) {
132260
taskComplete = true;
133261
this.formatter.success('Task marked as complete by agent');
134262
}
135263

264+
// Check completion heuristics for simple tasks
265+
if (!taskComplete && this.checkTaskCompletion(task.requirement, iteration)) {
266+
taskComplete = true;
267+
this.formatter.success('Task appears complete based on success heuristics');
268+
}
269+
136270
// If AI didn't call any tools (just reasoning), end the task
137271
if (stepResult.action === 'reasoning') {
138272
taskComplete = true;
@@ -648,6 +782,17 @@ Please execute these recovery commands first, then continue with the original ta
648782
break;
649783

650784
case 'write-file':
785+
// Protect critical infrastructure files in simple task mode
786+
if (this.isSimpleTaskMode && this.isProtectedFile(params.path)) {
787+
result = {
788+
success: false,
789+
output: '',
790+
errorMessage: `⚠️ Cannot modify protected file: ${params.path}. This file is critical project infrastructure and should not be modified for simple tasks. If you need to add functionality, create new files instead.`
791+
};
792+
this.formatter.warn(`🛡️ Blocked modification of protected file: ${params.path}`);
793+
break;
794+
}
795+
651796
result = await this.toolRegistry.writeFile(
652797
params.path,
653798
params.content || '',

0 commit comments

Comments
 (0)