Release: CI/CD Pipeline & Architecture Updates #177
@@ -0,0 +1,12 @@
|
||||
import { Module } from "@nestjs/common";
|
||||
import { ContinuationPromptsService } from "./continuation-prompts.service";
|
||||
|
||||
/**
|
||||
* Continuation Prompts Module
|
||||
* Generates forced continuation prompts for incomplete AI agent work
|
||||
*/
|
||||
@Module({
|
||||
providers: [ContinuationPromptsService],
|
||||
exports: [ContinuationPromptsService],
|
||||
})
|
||||
export class ContinuationPromptsModule {}
|
||||
@@ -0,0 +1,387 @@
|
||||
import { describe, it, expect, beforeEach } from "vitest";
|
||||
import { ContinuationPromptsService } from "./continuation-prompts.service";
|
||||
import { ContinuationPromptContext, FailureDetail, ContinuationPrompt } from "./interfaces";
|
||||
|
||||
describe("ContinuationPromptsService", () => {
|
||||
let service: ContinuationPromptsService;
|
||||
let baseContext: ContinuationPromptContext;
|
||||
|
||||
beforeEach(() => {
|
||||
service = new ContinuationPromptsService();
|
||||
baseContext = {
|
||||
taskId: "task-1",
|
||||
originalTask: "Implement user authentication",
|
||||
attemptNumber: 1,
|
||||
maxAttempts: 3,
|
||||
failures: [],
|
||||
filesChanged: ["src/auth/auth.service.ts"],
|
||||
};
|
||||
});
|
||||
|
||||
describe("generatePrompt", () => {
|
||||
it("should generate a prompt with system and user sections", () => {
|
||||
const context: ContinuationPromptContext = {
|
||||
...baseContext,
|
||||
failures: [
|
||||
{
|
||||
type: "test-failure",
|
||||
message: "Test failed: should authenticate user",
|
||||
details: "Expected 200, got 401",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const prompt = service.generatePrompt(context);
|
||||
|
||||
expect(prompt).toBeDefined();
|
||||
expect(prompt.systemPrompt).toContain("CRITICAL RULES");
|
||||
expect(prompt.userPrompt).toContain("Implement user authentication");
|
||||
expect(prompt.userPrompt).toContain("Test failed");
|
||||
expect(prompt.constraints).toBeInstanceOf(Array);
|
||||
expect(prompt.priority).toBe("high");
|
||||
});
|
||||
|
||||
it("should include attempt number in prompt", () => {
|
||||
const context: ContinuationPromptContext = {
|
||||
...baseContext,
|
||||
attemptNumber: 2,
|
||||
failures: [
|
||||
{
|
||||
type: "build-error",
|
||||
message: "Type error in auth.service.ts",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const prompt = service.generatePrompt(context);
|
||||
|
||||
expect(prompt.userPrompt).toContain("attempt 2 of 3");
|
||||
});
|
||||
|
||||
it("should escalate priority on final attempt", () => {
|
||||
const context: ContinuationPromptContext = {
|
||||
...baseContext,
|
||||
attemptNumber: 3,
|
||||
maxAttempts: 3,
|
||||
failures: [
|
||||
{
|
||||
type: "test-failure",
|
||||
message: "Tests still failing",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const prompt = service.generatePrompt(context);
|
||||
|
||||
expect(prompt.priority).toBe("critical");
|
||||
expect(prompt.constraints).toContain(
|
||||
"This is your LAST attempt. Failure means manual intervention required."
|
||||
);
|
||||
});
|
||||
|
||||
it("should handle multiple failure types", () => {
|
||||
const context: ContinuationPromptContext = {
|
||||
...baseContext,
|
||||
failures: [
|
||||
{
|
||||
type: "test-failure",
|
||||
message: "Auth test failed",
|
||||
},
|
||||
{
|
||||
type: "build-error",
|
||||
message: "Type error",
|
||||
},
|
||||
{
|
||||
type: "coverage",
|
||||
message: "Coverage below 85%",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const prompt = service.generatePrompt(context);
|
||||
|
||||
expect(prompt.userPrompt).toContain("Auth test failed");
|
||||
expect(prompt.userPrompt).toContain("Type error");
|
||||
expect(prompt.userPrompt).toContain("Coverage below 85%");
|
||||
});
|
||||
});
|
||||
|
||||
describe("generateTestFailurePrompt", () => {
|
||||
it("should format test failures with details", () => {
|
||||
const failures: FailureDetail[] = [
|
||||
{
|
||||
type: "test-failure",
|
||||
message: "should authenticate user",
|
||||
details: "Expected 200, got 401",
|
||||
location: "auth.service.spec.ts:42",
|
||||
},
|
||||
{
|
||||
type: "test-failure",
|
||||
message: "should reject invalid credentials",
|
||||
details: "AssertionError: expected false to be true",
|
||||
location: "auth.service.spec.ts:58",
|
||||
},
|
||||
];
|
||||
|
||||
const prompt = service.generateTestFailurePrompt(failures);
|
||||
|
||||
expect(prompt).toContain("should authenticate user");
|
||||
expect(prompt).toContain("Expected 200, got 401");
|
||||
expect(prompt).toContain("auth.service.spec.ts:42");
|
||||
expect(prompt).toContain("should reject invalid credentials");
|
||||
expect(prompt).toContain("Fix the implementation");
|
||||
});
|
||||
|
||||
it("should include guidance for fixing tests", () => {
|
||||
const failures: FailureDetail[] = [
|
||||
{
|
||||
type: "test-failure",
|
||||
message: "Test failed",
|
||||
},
|
||||
];
|
||||
|
||||
const prompt = service.generateTestFailurePrompt(failures);
|
||||
|
||||
expect(prompt).toContain("Read the test");
|
||||
expect(prompt).toContain("Fix the implementation");
|
||||
expect(prompt).toContain("Run the test");
|
||||
});
|
||||
});
|
||||
|
||||
describe("generateBuildErrorPrompt", () => {
|
||||
it("should format build errors with location", () => {
|
||||
const failures: FailureDetail[] = [
|
||||
{
|
||||
type: "build-error",
|
||||
message: "Type 'string' is not assignable to type 'number'",
|
||||
location: "auth.service.ts:25",
|
||||
},
|
||||
{
|
||||
type: "build-error",
|
||||
message: "Cannot find name 'User'",
|
||||
location: "auth.service.ts:42",
|
||||
suggestion: "Import User from '@/entities'",
|
||||
},
|
||||
];
|
||||
|
||||
const prompt = service.generateBuildErrorPrompt(failures);
|
||||
|
||||
expect(prompt).toContain("Type 'string' is not assignable");
|
||||
expect(prompt).toContain("auth.service.ts:25");
|
||||
expect(prompt).toContain("Cannot find name 'User'");
|
||||
expect(prompt).toContain("Import User from");
|
||||
});
|
||||
|
||||
it("should include build-specific guidance", () => {
|
||||
const failures: FailureDetail[] = [
|
||||
{
|
||||
type: "build-error",
|
||||
message: "Syntax error",
|
||||
},
|
||||
];
|
||||
|
||||
const prompt = service.generateBuildErrorPrompt(failures);
|
||||
|
||||
expect(prompt).toContain("TypeScript");
|
||||
expect(prompt).toContain("Do not proceed until build passes");
|
||||
});
|
||||
});
|
||||
|
||||
describe("generateCoveragePrompt", () => {
|
||||
it("should show coverage gap", () => {
|
||||
const prompt = service.generateCoveragePrompt(72, 85);
|
||||
|
||||
expect(prompt).toContain("72%");
|
||||
expect(prompt).toContain("85%");
|
||||
expect(prompt).toContain("13%"); // gap
|
||||
});
|
||||
|
||||
it("should provide guidance for improving coverage", () => {
|
||||
const prompt = service.generateCoveragePrompt(80, 85);
|
||||
|
||||
expect(prompt).toContain("uncovered code paths");
|
||||
expect(prompt).toContain("edge cases");
|
||||
expect(prompt).toContain("error handling");
|
||||
});
|
||||
});
|
||||
|
||||
describe("generateIncompleteWorkPrompt", () => {
|
||||
it("should list incomplete work items", () => {
|
||||
const issues = [
|
||||
"TODO: Implement password hashing",
|
||||
"FIXME: Add error handling",
|
||||
"Missing validation for email format",
|
||||
];
|
||||
|
||||
const prompt = service.generateIncompleteWorkPrompt(issues);
|
||||
|
||||
expect(prompt).toContain("TODO: Implement password hashing");
|
||||
expect(prompt).toContain("FIXME: Add error handling");
|
||||
expect(prompt).toContain("Missing validation");
|
||||
});
|
||||
|
||||
it("should emphasize completion requirement", () => {
|
||||
const issues = ["Missing feature X"];
|
||||
|
||||
const prompt = service.generateIncompleteWorkPrompt(issues);
|
||||
|
||||
expect(prompt).toContain("MUST complete ALL aspects");
|
||||
expect(prompt).toContain("Do not leave TODO");
|
||||
});
|
||||
});
|
||||
|
||||
describe("getConstraints", () => {
|
||||
it("should return basic constraints for first attempt", () => {
|
||||
const constraints = service.getConstraints(1, 3);
|
||||
|
||||
expect(constraints).toBeInstanceOf(Array);
|
||||
expect(constraints.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it("should escalate constraints on second attempt", () => {
|
||||
const constraints = service.getConstraints(2, 3);
|
||||
|
||||
expect(constraints).toContain("Focus only on failures, no new features");
|
||||
});
|
||||
|
||||
it("should add strict constraints on third attempt", () => {
|
||||
const constraints = service.getConstraints(3, 3);
|
||||
|
||||
expect(constraints).toContain("Minimal changes only, fix exact issues");
|
||||
});
|
||||
|
||||
it("should add final warning on last attempt", () => {
|
||||
const constraints = service.getConstraints(3, 3);
|
||||
|
||||
expect(constraints).toContain(
|
||||
"This is your LAST attempt. Failure means manual intervention required."
|
||||
);
|
||||
});
|
||||
|
||||
it("should handle different max attempts", () => {
|
||||
const constraints = service.getConstraints(5, 5);
|
||||
|
||||
expect(constraints).toContain(
|
||||
"This is your LAST attempt. Failure means manual intervention required."
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("formatFailuresForPrompt", () => {
|
||||
it("should format failures with all details", () => {
|
||||
const failures: FailureDetail[] = [
|
||||
{
|
||||
type: "test-failure",
|
||||
message: "Test failed",
|
||||
details: "Expected true, got false",
|
||||
location: "file.spec.ts:10",
|
||||
suggestion: "Check the implementation",
|
||||
},
|
||||
];
|
||||
|
||||
const formatted = service.formatFailuresForPrompt(failures);
|
||||
|
||||
expect(formatted).toContain("test-failure");
|
||||
expect(formatted).toContain("Test failed");
|
||||
expect(formatted).toContain("Expected true, got false");
|
||||
expect(formatted).toContain("file.spec.ts:10");
|
||||
expect(formatted).toContain("Check the implementation");
|
||||
});
|
||||
|
||||
it("should handle failures without optional fields", () => {
|
||||
const failures: FailureDetail[] = [
|
||||
{
|
||||
type: "lint-error",
|
||||
message: "Unused variable",
|
||||
},
|
||||
];
|
||||
|
||||
const formatted = service.formatFailuresForPrompt(failures);
|
||||
|
||||
expect(formatted).toContain("lint-error");
|
||||
expect(formatted).toContain("Unused variable");
|
||||
});
|
||||
|
||||
it("should format multiple failures", () => {
|
||||
const failures: FailureDetail[] = [
|
||||
{
|
||||
type: "test-failure",
|
||||
message: "Test 1 failed",
|
||||
},
|
||||
{
|
||||
type: "build-error",
|
||||
message: "Build error",
|
||||
},
|
||||
{
|
||||
type: "coverage",
|
||||
message: "Low coverage",
|
||||
},
|
||||
];
|
||||
|
||||
const formatted = service.formatFailuresForPrompt(failures);
|
||||
|
||||
expect(formatted).toContain("Test 1 failed");
|
||||
expect(formatted).toContain("Build error");
|
||||
expect(formatted).toContain("Low coverage");
|
||||
});
|
||||
|
||||
it("should handle empty failures array", () => {
|
||||
const failures: FailureDetail[] = [];
|
||||
|
||||
const formatted = service.formatFailuresForPrompt(failures);
|
||||
|
||||
expect(formatted).toBe("");
|
||||
});
|
||||
});
|
||||
|
||||
describe("priority assignment", () => {
|
||||
it("should set normal priority for first attempt with minor issues", () => {
|
||||
const context: ContinuationPromptContext = {
|
||||
...baseContext,
|
||||
attemptNumber: 1,
|
||||
failures: [
|
||||
{
|
||||
type: "lint-error",
|
||||
message: "Minor lint issue",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const prompt = service.generatePrompt(context);
|
||||
|
||||
expect(prompt.priority).toBe("normal");
|
||||
});
|
||||
|
||||
it("should set high priority for build errors", () => {
|
||||
const context: ContinuationPromptContext = {
|
||||
...baseContext,
|
||||
failures: [
|
||||
{
|
||||
type: "build-error",
|
||||
message: "Build failed",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const prompt = service.generatePrompt(context);
|
||||
|
||||
expect(prompt.priority).toBe("high");
|
||||
});
|
||||
|
||||
it("should set high priority for test failures", () => {
|
||||
const context: ContinuationPromptContext = {
|
||||
...baseContext,
|
||||
failures: [
|
||||
{
|
||||
type: "test-failure",
|
||||
message: "Test failed",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const prompt = service.generatePrompt(context);
|
||||
|
||||
expect(prompt.priority).toBe("high");
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,207 @@
|
||||
import { Injectable } from "@nestjs/common";
|
||||
import { ContinuationPromptContext, FailureDetail, ContinuationPrompt } from "./interfaces";
|
||||
import {
|
||||
BASE_CONTINUATION_SYSTEM,
|
||||
BASE_USER_PROMPT,
|
||||
TEST_FAILURE_TEMPLATE,
|
||||
BUILD_ERROR_TEMPLATE,
|
||||
COVERAGE_TEMPLATE,
|
||||
INCOMPLETE_WORK_TEMPLATE,
|
||||
} from "./templates";
|
||||
|
||||
/**
|
||||
* Service for generating continuation prompts when AI agent work is incomplete
|
||||
*/
|
||||
@Injectable()
|
||||
export class ContinuationPromptsService {
|
||||
/**
|
||||
* Generate a complete continuation prompt from context
|
||||
*/
|
||||
generatePrompt(context: ContinuationPromptContext): ContinuationPrompt {
|
||||
const systemPrompt = BASE_CONTINUATION_SYSTEM;
|
||||
const constraints = this.getConstraints(context.attemptNumber, context.maxAttempts);
|
||||
|
||||
// Format failures based on their types
|
||||
const formattedFailures = this.formatFailuresByType(context.failures);
|
||||
|
||||
// Build user prompt
|
||||
const userPrompt = BASE_USER_PROMPT.replace("{{taskDescription}}", context.originalTask)
|
||||
.replace("{{attemptNumber}}", String(context.attemptNumber))
|
||||
.replace("{{maxAttempts}}", String(context.maxAttempts))
|
||||
.replace("{{failures}}", formattedFailures)
|
||||
.replace("{{constraints}}", this.formatConstraints(constraints));
|
||||
|
||||
// Determine priority
|
||||
const priority = this.determinePriority(context);
|
||||
|
||||
return {
|
||||
systemPrompt,
|
||||
userPrompt,
|
||||
constraints,
|
||||
priority,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate test failure specific prompt
|
||||
*/
|
||||
generateTestFailurePrompt(failures: FailureDetail[]): string {
|
||||
const formattedFailures = this.formatFailuresForPrompt(failures);
|
||||
return TEST_FAILURE_TEMPLATE.replace("{{failures}}", formattedFailures);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate build error specific prompt
|
||||
*/
|
||||
generateBuildErrorPrompt(failures: FailureDetail[]): string {
|
||||
const formattedErrors = this.formatFailuresForPrompt(failures);
|
||||
return BUILD_ERROR_TEMPLATE.replace("{{errors}}", formattedErrors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate coverage improvement prompt
|
||||
*/
|
||||
generateCoveragePrompt(current: number, required: number): string {
|
||||
const gap = required - current;
|
||||
return COVERAGE_TEMPLATE.replace("{{currentCoverage}}", String(current))
|
||||
.replace("{{requiredCoverage}}", String(required))
|
||||
.replace("{{gap}}", String(gap))
|
||||
.replace("{{uncoveredFiles}}", "(See coverage report for details)");
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate incomplete work prompt
|
||||
*/
|
||||
generateIncompleteWorkPrompt(issues: string[]): string {
|
||||
const formattedIssues = issues.map((issue) => `- ${issue}`).join("\n");
|
||||
return INCOMPLETE_WORK_TEMPLATE.replace("{{issues}}", formattedIssues);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get constraints based on attempt number
|
||||
*/
|
||||
getConstraints(attemptNumber: number, maxAttempts: number): string[] {
|
||||
const constraints: string[] = [
|
||||
"Address ALL failures listed above",
|
||||
"Run all quality checks before claiming completion",
|
||||
];
|
||||
|
||||
if (attemptNumber >= 2) {
|
||||
constraints.push("Focus only on failures, no new features");
|
||||
}
|
||||
|
||||
if (attemptNumber >= 3) {
|
||||
constraints.push("Minimal changes only, fix exact issues");
|
||||
}
|
||||
|
||||
if (attemptNumber >= maxAttempts) {
|
||||
constraints.push("This is your LAST attempt. Failure means manual intervention required.");
|
||||
}
|
||||
|
||||
return constraints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format failures for inclusion in prompt
|
||||
*/
|
||||
formatFailuresForPrompt(failures: FailureDetail[]): string {
|
||||
if (failures.length === 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return failures
|
||||
.map((failure, index) => {
|
||||
const parts: string[] = [`${String(index + 1)}. [${failure.type}] ${failure.message}`];
|
||||
|
||||
if (failure.location) {
|
||||
parts.push(` Location: ${failure.location}`);
|
||||
}
|
||||
|
||||
if (failure.details) {
|
||||
parts.push(` Details: ${failure.details}`);
|
||||
}
|
||||
|
||||
if (failure.suggestion) {
|
||||
parts.push(` Suggestion: ${failure.suggestion}`);
|
||||
}
|
||||
|
||||
return parts.join("\n");
|
||||
})
|
||||
.join("\n\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Format failures by type using appropriate templates
|
||||
*/
|
||||
private formatFailuresByType(failures: FailureDetail[]): string {
|
||||
const sections: string[] = [];
|
||||
|
||||
// Group failures by type
|
||||
const testFailures = failures.filter((f) => f.type === "test-failure");
|
||||
const buildErrors = failures.filter((f) => f.type === "build-error");
|
||||
const coverageIssues = failures.filter((f) => f.type === "coverage");
|
||||
const incompleteWork = failures.filter((f) => f.type === "incomplete-work");
|
||||
const lintErrors = failures.filter((f) => f.type === "lint-error");
|
||||
|
||||
if (testFailures.length > 0) {
|
||||
sections.push(this.generateTestFailurePrompt(testFailures));
|
||||
}
|
||||
|
||||
if (buildErrors.length > 0) {
|
||||
sections.push(this.generateBuildErrorPrompt(buildErrors));
|
||||
}
|
||||
|
||||
if (coverageIssues.length > 0) {
|
||||
// Extract coverage numbers from message if available
|
||||
const coverageFailure = coverageIssues[0];
|
||||
if (coverageFailure) {
|
||||
const match = /(\d+)%.*?(\d+)%/.exec(coverageFailure.message);
|
||||
if (match?.[1] && match[2]) {
|
||||
sections.push(this.generateCoveragePrompt(parseInt(match[1]), parseInt(match[2])));
|
||||
} else {
|
||||
sections.push(this.formatFailuresForPrompt(coverageIssues));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (incompleteWork.length > 0) {
|
||||
const issues = incompleteWork.map((f) => f.message);
|
||||
sections.push(this.generateIncompleteWorkPrompt(issues));
|
||||
}
|
||||
|
||||
if (lintErrors.length > 0) {
|
||||
sections.push("Lint Errors:\n" + this.formatFailuresForPrompt(lintErrors));
|
||||
}
|
||||
|
||||
return sections.join("\n\n---\n\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Format constraints as a bulleted list
|
||||
*/
|
||||
private formatConstraints(constraints: string[]): string {
|
||||
return "CONSTRAINTS:\n" + constraints.map((c) => `- ${c}`).join("\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine priority based on context
|
||||
*/
|
||||
private determinePriority(context: ContinuationPromptContext): "critical" | "high" | "normal" {
|
||||
// Final attempt is always critical
|
||||
if (context.attemptNumber >= context.maxAttempts) {
|
||||
return "critical";
|
||||
}
|
||||
|
||||
// Build errors and test failures are high priority
|
||||
const hasCriticalFailures = context.failures.some(
|
||||
(f) => f.type === "build-error" || f.type === "test-failure"
|
||||
);
|
||||
|
||||
if (hasCriticalFailures) {
|
||||
return "high";
|
||||
}
|
||||
|
||||
// Everything else is normal
|
||||
return "normal";
|
||||
}
|
||||
}
|
||||
3
apps/api/src/continuation-prompts/index.ts
Normal file
3
apps/api/src/continuation-prompts/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export * from "./continuation-prompts.module";
|
||||
export * from "./continuation-prompts.service";
|
||||
export * from "./interfaces";
|
||||
@@ -0,0 +1,24 @@
|
||||
export interface ContinuationPromptContext {
|
||||
taskId: string;
|
||||
originalTask: string;
|
||||
attemptNumber: number;
|
||||
maxAttempts: number;
|
||||
failures: FailureDetail[];
|
||||
previousOutput?: string;
|
||||
filesChanged: string[];
|
||||
}
|
||||
|
||||
export interface FailureDetail {
|
||||
type: "test-failure" | "build-error" | "lint-error" | "coverage" | "incomplete-work";
|
||||
message: string;
|
||||
details?: string;
|
||||
location?: string; // file:line
|
||||
suggestion?: string;
|
||||
}
|
||||
|
||||
export interface ContinuationPrompt {
|
||||
systemPrompt: string;
|
||||
userPrompt: string;
|
||||
constraints: string[];
|
||||
priority: "critical" | "high" | "normal";
|
||||
}
|
||||
1
apps/api/src/continuation-prompts/interfaces/index.ts
Normal file
1
apps/api/src/continuation-prompts/interfaces/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from "./continuation-prompt.interface";
|
||||
18
apps/api/src/continuation-prompts/templates/base.template.ts
Normal file
18
apps/api/src/continuation-prompts/templates/base.template.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
export const BASE_CONTINUATION_SYSTEM = `You are continuing work on a task that was not completed successfully.
|
||||
Your previous attempt did not pass quality gates. You MUST fix the issues below.
|
||||
|
||||
CRITICAL RULES:
|
||||
1. You MUST address EVERY failure listed
|
||||
2. Do NOT defer work to future tasks
|
||||
3. Do NOT claim done until all gates pass
|
||||
4. Run tests before claiming completion
|
||||
`;
|
||||
|
||||
export const BASE_USER_PROMPT = `Task: {{taskDescription}}
|
||||
|
||||
Previous attempt {{attemptNumber}} of {{maxAttempts}} did not pass quality gates.
|
||||
|
||||
{{failures}}
|
||||
|
||||
{{constraints}}
|
||||
`;
|
||||
@@ -0,0 +1,10 @@
|
||||
export const BUILD_ERROR_TEMPLATE = `Build errors detected:
|
||||
{{errors}}
|
||||
|
||||
Fix these TypeScript/compilation errors. Do not proceed until build passes.
|
||||
|
||||
Steps:
|
||||
1. Read the error messages carefully
|
||||
2. Fix type mismatches, missing imports, or syntax errors
|
||||
3. Run build to verify it passes
|
||||
`;
|
||||
@@ -0,0 +1,15 @@
|
||||
export const COVERAGE_TEMPLATE = `Test coverage is below required threshold.
|
||||
|
||||
Current coverage: {{currentCoverage}}%
|
||||
Required coverage: {{requiredCoverage}}%
|
||||
Gap: {{gap}}%
|
||||
|
||||
Files with insufficient coverage:
|
||||
{{uncoveredFiles}}
|
||||
|
||||
Steps to improve coverage:
|
||||
1. Identify uncovered code paths
|
||||
2. Write tests for uncovered scenarios
|
||||
3. Focus on edge cases and error handling
|
||||
4. Run coverage report to verify improvement
|
||||
`;
|
||||
@@ -0,0 +1,13 @@
|
||||
export const INCOMPLETE_WORK_TEMPLATE = `The task implementation is incomplete.
|
||||
|
||||
Issues detected:
|
||||
{{issues}}
|
||||
|
||||
You MUST complete ALL aspects of the task. Do not leave TODO comments or deferred work.
|
||||
|
||||
Steps:
|
||||
1. Review each incomplete item
|
||||
2. Implement the missing functionality
|
||||
3. Write tests for the new code
|
||||
4. Verify all requirements are met
|
||||
`;
|
||||
5
apps/api/src/continuation-prompts/templates/index.ts
Normal file
5
apps/api/src/continuation-prompts/templates/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export * from "./base.template";
|
||||
export * from "./test-failure.template";
|
||||
export * from "./build-error.template";
|
||||
export * from "./coverage.template";
|
||||
export * from "./incomplete-work.template";
|
||||
@@ -0,0 +1,9 @@
|
||||
export const TEST_FAILURE_TEMPLATE = `The following tests are failing:
|
||||
{{failures}}
|
||||
|
||||
For each failing test:
|
||||
1. Read the test to understand what is expected
|
||||
2. Fix the implementation to pass the test
|
||||
3. Run the test to verify it passes
|
||||
4. Do NOT skip or modify tests - fix the implementation
|
||||
`;
|
||||
Reference in New Issue
Block a user