Skip to content

Commit 7969a72

Browse files
committed
feat(plan): add idea selection and planning prompts
Add two new prompt generation functions for ideas feature: 1. generateIdeaSelectionPrompt() - Prompts AI to evaluate multiple ideas - Considers complexity, dependencies, and priority - Returns format: SELECTED_IDEA: <n> and REASON: <explanation> - Helps select simplest/quick-win idea 2. generateIdeaPlanningPrompt() - Generates planning prompt for a specific idea - Idea content takes full precedence over user hints - Creates focused plan specifically for selected idea - Requires 3-10 actionable tasks Include comprehensive tests for both prompt functions. Signed-off-by: leocavalcante <[email protected]>
1 parent 1c31bb6 commit 7969a72

File tree

1 file changed

+123
-0
lines changed

1 file changed

+123
-0
lines changed

src/plan.zig

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,106 @@ pub fn generateEvaluationPrompt(allocator: Allocator) ![]const u8 {
305305
;
306306
}
307307

308+
/// Generate prompt for AI to select which idea to work on
309+
/// Considers both simplicity/quick-wins and dependencies between ideas
310+
pub fn generateIdeaSelectionPrompt(ideas_formatted: []const u8, allocator: Allocator) ![]const u8 {
311+
var result = std.array_list.AlignedManaged(u8, null).init(allocator);
312+
errdefer result.deinit();
313+
314+
try result.appendSlice(
315+
\\You are an AI assistant helping prioritize development tasks.
316+
\\
317+
\\Below are several ideas/tasks that need to be implemented. Your job is to:
318+
\\1. Analyze each idea for complexity and effort required
319+
\\2. Identify any DEPENDENCIES between ideas (if idea B requires idea A to be done first)
320+
\\3. Select the SIMPLEST idea that has NO blocking dependencies
321+
\\4. Prioritize: bug fixes > small features > documentation > refactoring > large features
322+
\\
323+
\\IMPORTANT: If ideas have dependencies, you MUST select one that can be implemented
324+
\\independently OR is a prerequisite for other ideas.
325+
\\
326+
\\IDEAS TO EVALUATE:
327+
\\
328+
\\
329+
);
330+
331+
try result.appendSlice(ideas_formatted);
332+
333+
try result.appendSlice(
334+
\\
335+
\\Respond with ONLY the idea number you selected and a brief reason, in this exact format:
336+
\\SELECTED_IDEA: <number>
337+
\\REASON: <one sentence explaining why this is the best quick-win>
338+
\\
339+
\\For example:
340+
\\SELECTED_IDEA: 2
341+
\\REASON: Small bug fix with no dependencies, can be completed quickly.
342+
\\
343+
\\Choose the quickest win that unblocks other work if dependencies exist.
344+
);
345+
346+
return result.toOwnedSlice();
347+
}
348+
349+
/// Generate planning prompt for a specific idea
350+
/// The idea takes full precedence over any user hints
351+
pub fn generateIdeaPlanningPrompt(cycle: u32, idea_content: []const u8, idea_filename: []const u8, allocator: Allocator) ![]const u8 {
352+
var ts_buf: [24]u8 = undefined;
353+
const ts = logger.timestampISO(&ts_buf);
354+
355+
var result = std.array_list.AlignedManaged(u8, null).init(allocator);
356+
errdefer result.deinit();
357+
358+
try result.appendSlice(
359+
\\CRITICAL: You are operating in an AUTONOMOUS CONTINUOUS DEVELOPMENT loop.
360+
\\
361+
\\You have been assigned a SPECIFIC IDEA to implement. Focus ONLY on this idea.
362+
\\
363+
\\STRICT REQUIREMENTS:
364+
\\- You MUST create a plan with AT LEAST 3 actionable tasks for this specific idea
365+
\\- NEVER ask questions or wait for user input
366+
\\- Focus entirely on implementing the idea described below
367+
\\- Break down the idea into concrete, actionable steps
368+
\\
369+
\\IDEA TO IMPLEMENT (from
370+
);
371+
try result.appendSlice(idea_filename);
372+
try result.appendSlice("):\n\n");
373+
try result.appendSlice(idea_content);
374+
try result.appendSlice(
375+
\\
376+
\\
377+
\\Your task: Create a concrete development plan to implement this idea.
378+
\\Save a markdown checklist to .opencoder/current_plan.md with 3-10 actionable tasks.
379+
\\
380+
\\The plan MUST follow this exact format:
381+
\\# Plan: [descriptive title based on the idea]
382+
\\Created:
383+
);
384+
try result.appendSlice(ts);
385+
try result.appendSlice("\nCycle: ");
386+
try result.writer().print("{d}", .{cycle});
387+
try result.appendSlice(
388+
\\
389+
\\
390+
\\## Context
391+
\\[Brief description of the idea and its purpose]
392+
\\
393+
\\## Tasks
394+
\\- [ ] Task 1: Specific, actionable description
395+
\\- [ ] Task 2: Specific, actionable description
396+
\\- [ ] Task 3: Specific, actionable description
397+
\\[Add more tasks as needed]
398+
\\
399+
\\## Notes
400+
\\[Any additional context or dependencies]
401+
\\
402+
\\After creating the plan file, respond with: PLAN_CREATED
403+
);
404+
405+
return result.toOwnedSlice();
406+
}
407+
308408
// ============================================================================
309409
// Tests
310410
// ============================================================================
@@ -422,3 +522,26 @@ test "generateEvaluationPrompt returns valid prompt" {
422522
try std.testing.expect(std.mem.indexOf(u8, prompt, "COMPLETE") != null);
423523
try std.testing.expect(std.mem.indexOf(u8, prompt, "NEEDS_WORK") != null);
424524
}
525+
526+
test "generateIdeaSelectionPrompt includes ideas and format" {
527+
const allocator = std.testing.allocator;
528+
const ideas = "## Idea 1: test.md\nTest content";
529+
const prompt = try generateIdeaSelectionPrompt(ideas, allocator);
530+
defer allocator.free(prompt);
531+
532+
try std.testing.expect(std.mem.indexOf(u8, prompt, "SELECTED_IDEA:") != null);
533+
try std.testing.expect(std.mem.indexOf(u8, prompt, "REASON:") != null);
534+
try std.testing.expect(std.mem.indexOf(u8, prompt, "Test content") != null);
535+
try std.testing.expect(std.mem.indexOf(u8, prompt, "dependencies") != null);
536+
}
537+
538+
test "generateIdeaPlanningPrompt includes idea content and filename" {
539+
const allocator = std.testing.allocator;
540+
const prompt = try generateIdeaPlanningPrompt(5, "Add dark mode support", "dark-mode.md", allocator);
541+
defer allocator.free(prompt);
542+
543+
try std.testing.expect(std.mem.indexOf(u8, prompt, "Add dark mode support") != null);
544+
try std.testing.expect(std.mem.indexOf(u8, prompt, "dark-mode.md") != null);
545+
try std.testing.expect(std.mem.indexOf(u8, prompt, "PLAN_CREATED") != null);
546+
try std.testing.expect(std.mem.indexOf(u8, prompt, "Cycle: 5") != null);
547+
}

0 commit comments

Comments
 (0)