mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-04 21:23:07 +00:00
feat: Introduce @automaker/prompts package for AI prompt templates
Changes: - Added a new package, @automaker/prompts, containing AI prompt templates for enhancing user-written task descriptions. - Implemented four enhancement modes: improve, technical, simplify, and acceptance, each with corresponding system prompts and examples. - Updated relevant packages to utilize the new prompts package, ensuring backward compatibility with existing imports. - Enhanced documentation to include usage examples and integration details for the new prompts. Benefits: ✅ Streamlined AI prompt management across the codebase ✅ Improved clarity and usability for AI-powered features ✅ Comprehensive documentation for developers All tests passing.
This commit is contained in:
526
libs/prompts/tests/enhancement.test.ts
Normal file
526
libs/prompts/tests/enhancement.test.ts
Normal file
@@ -0,0 +1,526 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import {
|
||||
getEnhancementPrompt,
|
||||
getSystemPrompt,
|
||||
getExamples,
|
||||
buildUserPrompt,
|
||||
isValidEnhancementMode,
|
||||
getAvailableEnhancementModes,
|
||||
IMPROVE_SYSTEM_PROMPT,
|
||||
TECHNICAL_SYSTEM_PROMPT,
|
||||
SIMPLIFY_SYSTEM_PROMPT,
|
||||
ACCEPTANCE_SYSTEM_PROMPT,
|
||||
IMPROVE_EXAMPLES,
|
||||
TECHNICAL_EXAMPLES,
|
||||
SIMPLIFY_EXAMPLES,
|
||||
ACCEPTANCE_EXAMPLES,
|
||||
} from "../src/enhancement.js";
|
||||
|
||||
describe("enhancement.ts", () => {
|
||||
describe("System Prompt Constants", () => {
|
||||
it("should export IMPROVE_SYSTEM_PROMPT", () => {
|
||||
expect(IMPROVE_SYSTEM_PROMPT).toBeDefined();
|
||||
expect(typeof IMPROVE_SYSTEM_PROMPT).toBe("string");
|
||||
expect(IMPROVE_SYSTEM_PROMPT).toContain("vague, unclear");
|
||||
expect(IMPROVE_SYSTEM_PROMPT).toContain("actionable");
|
||||
});
|
||||
|
||||
it("should export TECHNICAL_SYSTEM_PROMPT", () => {
|
||||
expect(TECHNICAL_SYSTEM_PROMPT).toBeDefined();
|
||||
expect(typeof TECHNICAL_SYSTEM_PROMPT).toBe("string");
|
||||
expect(TECHNICAL_SYSTEM_PROMPT).toContain("technical");
|
||||
expect(TECHNICAL_SYSTEM_PROMPT).toContain("implementation");
|
||||
});
|
||||
|
||||
it("should export SIMPLIFY_SYSTEM_PROMPT", () => {
|
||||
expect(SIMPLIFY_SYSTEM_PROMPT).toBeDefined();
|
||||
expect(typeof SIMPLIFY_SYSTEM_PROMPT).toBe("string");
|
||||
expect(SIMPLIFY_SYSTEM_PROMPT).toContain("verbose");
|
||||
expect(SIMPLIFY_SYSTEM_PROMPT).toContain("concise");
|
||||
});
|
||||
|
||||
it("should export ACCEPTANCE_SYSTEM_PROMPT", () => {
|
||||
expect(ACCEPTANCE_SYSTEM_PROMPT).toBeDefined();
|
||||
expect(typeof ACCEPTANCE_SYSTEM_PROMPT).toBe("string");
|
||||
expect(ACCEPTANCE_SYSTEM_PROMPT).toContain("acceptance criteria");
|
||||
expect(ACCEPTANCE_SYSTEM_PROMPT).toContain("testable");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Examples Constants", () => {
|
||||
it("should export IMPROVE_EXAMPLES with valid structure", () => {
|
||||
expect(IMPROVE_EXAMPLES).toBeDefined();
|
||||
expect(Array.isArray(IMPROVE_EXAMPLES)).toBe(true);
|
||||
expect(IMPROVE_EXAMPLES.length).toBeGreaterThan(0);
|
||||
|
||||
IMPROVE_EXAMPLES.forEach((example) => {
|
||||
expect(example).toHaveProperty("input");
|
||||
expect(example).toHaveProperty("output");
|
||||
expect(typeof example.input).toBe("string");
|
||||
expect(typeof example.output).toBe("string");
|
||||
});
|
||||
});
|
||||
|
||||
it("should export TECHNICAL_EXAMPLES with valid structure", () => {
|
||||
expect(TECHNICAL_EXAMPLES).toBeDefined();
|
||||
expect(Array.isArray(TECHNICAL_EXAMPLES)).toBe(true);
|
||||
expect(TECHNICAL_EXAMPLES.length).toBeGreaterThan(0);
|
||||
|
||||
TECHNICAL_EXAMPLES.forEach((example) => {
|
||||
expect(example).toHaveProperty("input");
|
||||
expect(example).toHaveProperty("output");
|
||||
expect(typeof example.input).toBe("string");
|
||||
expect(typeof example.output).toBe("string");
|
||||
});
|
||||
});
|
||||
|
||||
it("should export SIMPLIFY_EXAMPLES with valid structure", () => {
|
||||
expect(SIMPLIFY_EXAMPLES).toBeDefined();
|
||||
expect(Array.isArray(SIMPLIFY_EXAMPLES)).toBe(true);
|
||||
expect(SIMPLIFY_EXAMPLES.length).toBeGreaterThan(0);
|
||||
|
||||
SIMPLIFY_EXAMPLES.forEach((example) => {
|
||||
expect(example).toHaveProperty("input");
|
||||
expect(example).toHaveProperty("output");
|
||||
expect(typeof example.input).toBe("string");
|
||||
expect(typeof example.output).toBe("string");
|
||||
});
|
||||
});
|
||||
|
||||
it("should export ACCEPTANCE_EXAMPLES with valid structure", () => {
|
||||
expect(ACCEPTANCE_EXAMPLES).toBeDefined();
|
||||
expect(Array.isArray(ACCEPTANCE_EXAMPLES)).toBe(true);
|
||||
expect(ACCEPTANCE_EXAMPLES.length).toBeGreaterThan(0);
|
||||
|
||||
ACCEPTANCE_EXAMPLES.forEach((example) => {
|
||||
expect(example).toHaveProperty("input");
|
||||
expect(example).toHaveProperty("output");
|
||||
expect(typeof example.input).toBe("string");
|
||||
expect(typeof example.output).toBe("string");
|
||||
});
|
||||
});
|
||||
|
||||
it("should have shorter outputs in SIMPLIFY_EXAMPLES", () => {
|
||||
SIMPLIFY_EXAMPLES.forEach((example) => {
|
||||
// Simplify examples should have shorter output than input
|
||||
// (though not always strictly enforced, it's the general pattern)
|
||||
expect(example.output).toBeDefined();
|
||||
expect(example.output.length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("getEnhancementPrompt", () => {
|
||||
it("should return prompt config for 'improve' mode", () => {
|
||||
const result = getEnhancementPrompt("improve");
|
||||
|
||||
expect(result).toHaveProperty("systemPrompt");
|
||||
expect(result).toHaveProperty("description");
|
||||
expect(result.systemPrompt).toBe(IMPROVE_SYSTEM_PROMPT);
|
||||
expect(result.description).toContain("vague");
|
||||
expect(result.description).toContain("actionable");
|
||||
});
|
||||
|
||||
it("should return prompt config for 'technical' mode", () => {
|
||||
const result = getEnhancementPrompt("technical");
|
||||
|
||||
expect(result).toHaveProperty("systemPrompt");
|
||||
expect(result).toHaveProperty("description");
|
||||
expect(result.systemPrompt).toBe(TECHNICAL_SYSTEM_PROMPT);
|
||||
expect(result.description).toContain("implementation");
|
||||
});
|
||||
|
||||
it("should return prompt config for 'simplify' mode", () => {
|
||||
const result = getEnhancementPrompt("simplify");
|
||||
|
||||
expect(result).toHaveProperty("systemPrompt");
|
||||
expect(result).toHaveProperty("description");
|
||||
expect(result.systemPrompt).toBe(SIMPLIFY_SYSTEM_PROMPT);
|
||||
expect(result.description).toContain("verbose");
|
||||
});
|
||||
|
||||
it("should return prompt config for 'acceptance' mode", () => {
|
||||
const result = getEnhancementPrompt("acceptance");
|
||||
|
||||
expect(result).toHaveProperty("systemPrompt");
|
||||
expect(result).toHaveProperty("description");
|
||||
expect(result.systemPrompt).toBe(ACCEPTANCE_SYSTEM_PROMPT);
|
||||
expect(result.description).toContain("acceptance");
|
||||
});
|
||||
|
||||
it("should handle uppercase mode", () => {
|
||||
const result = getEnhancementPrompt("IMPROVE");
|
||||
|
||||
expect(result.systemPrompt).toBe(IMPROVE_SYSTEM_PROMPT);
|
||||
});
|
||||
|
||||
it("should handle mixed case mode", () => {
|
||||
const result = getEnhancementPrompt("TeChnIcaL");
|
||||
|
||||
expect(result.systemPrompt).toBe(TECHNICAL_SYSTEM_PROMPT);
|
||||
});
|
||||
|
||||
it("should fall back to 'improve' for invalid mode", () => {
|
||||
const result = getEnhancementPrompt("invalid-mode");
|
||||
|
||||
expect(result.systemPrompt).toBe(IMPROVE_SYSTEM_PROMPT);
|
||||
expect(result.description).toContain("vague");
|
||||
});
|
||||
|
||||
it("should fall back to 'improve' for empty string", () => {
|
||||
const result = getEnhancementPrompt("");
|
||||
|
||||
expect(result.systemPrompt).toBe(IMPROVE_SYSTEM_PROMPT);
|
||||
});
|
||||
});
|
||||
|
||||
describe("getSystemPrompt", () => {
|
||||
it("should return IMPROVE_SYSTEM_PROMPT for 'improve'", () => {
|
||||
const result = getSystemPrompt("improve");
|
||||
expect(result).toBe(IMPROVE_SYSTEM_PROMPT);
|
||||
});
|
||||
|
||||
it("should return TECHNICAL_SYSTEM_PROMPT for 'technical'", () => {
|
||||
const result = getSystemPrompt("technical");
|
||||
expect(result).toBe(TECHNICAL_SYSTEM_PROMPT);
|
||||
});
|
||||
|
||||
it("should return SIMPLIFY_SYSTEM_PROMPT for 'simplify'", () => {
|
||||
const result = getSystemPrompt("simplify");
|
||||
expect(result).toBe(SIMPLIFY_SYSTEM_PROMPT);
|
||||
});
|
||||
|
||||
it("should return ACCEPTANCE_SYSTEM_PROMPT for 'acceptance'", () => {
|
||||
const result = getSystemPrompt("acceptance");
|
||||
expect(result).toBe(ACCEPTANCE_SYSTEM_PROMPT);
|
||||
});
|
||||
});
|
||||
|
||||
describe("getExamples", () => {
|
||||
it("should return IMPROVE_EXAMPLES for 'improve'", () => {
|
||||
const result = getExamples("improve");
|
||||
expect(result).toBe(IMPROVE_EXAMPLES);
|
||||
expect(result.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it("should return TECHNICAL_EXAMPLES for 'technical'", () => {
|
||||
const result = getExamples("technical");
|
||||
expect(result).toBe(TECHNICAL_EXAMPLES);
|
||||
expect(result.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it("should return SIMPLIFY_EXAMPLES for 'simplify'", () => {
|
||||
const result = getExamples("simplify");
|
||||
expect(result).toBe(SIMPLIFY_EXAMPLES);
|
||||
expect(result.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it("should return ACCEPTANCE_EXAMPLES for 'acceptance'", () => {
|
||||
const result = getExamples("acceptance");
|
||||
expect(result).toBe(ACCEPTANCE_EXAMPLES);
|
||||
expect(result.length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("buildUserPrompt", () => {
|
||||
const testText = "Add a login feature";
|
||||
|
||||
describe("with examples (default)", () => {
|
||||
it("should include examples by default for 'improve' mode", () => {
|
||||
const result = buildUserPrompt("improve", testText);
|
||||
|
||||
expect(result).toContain("Here are some examples");
|
||||
expect(result).toContain("Example 1:");
|
||||
expect(result).toContain(IMPROVE_EXAMPLES[0].input);
|
||||
expect(result).toContain(IMPROVE_EXAMPLES[0].output);
|
||||
expect(result).toContain(testText);
|
||||
});
|
||||
|
||||
it("should include examples by default for 'technical' mode", () => {
|
||||
const result = buildUserPrompt("technical", testText);
|
||||
|
||||
expect(result).toContain("Here are some examples");
|
||||
expect(result).toContain("Example 1:");
|
||||
expect(result).toContain(TECHNICAL_EXAMPLES[0].input);
|
||||
expect(result).toContain(testText);
|
||||
});
|
||||
|
||||
it("should include examples when explicitly set to true", () => {
|
||||
const result = buildUserPrompt("improve", testText, true);
|
||||
|
||||
expect(result).toContain("Here are some examples");
|
||||
expect(result).toContain(testText);
|
||||
});
|
||||
|
||||
it("should format all examples with numbered labels", () => {
|
||||
const result = buildUserPrompt("improve", testText);
|
||||
|
||||
IMPROVE_EXAMPLES.forEach((_, index) => {
|
||||
expect(result).toContain(`Example ${index + 1}:`);
|
||||
});
|
||||
});
|
||||
|
||||
it("should separate examples with dividers", () => {
|
||||
const result = buildUserPrompt("improve", testText);
|
||||
|
||||
// Count dividers (---) - should be (examples.length) + 1
|
||||
const dividerCount = (result.match(/---/g) || []).length;
|
||||
expect(dividerCount).toBe(IMPROVE_EXAMPLES.length);
|
||||
});
|
||||
|
||||
it("should include 'Now, please enhance' before user text", () => {
|
||||
const result = buildUserPrompt("improve", testText);
|
||||
|
||||
expect(result).toContain("Now, please enhance the following");
|
||||
expect(result).toContain(testText);
|
||||
});
|
||||
});
|
||||
|
||||
describe("without examples", () => {
|
||||
it("should not include examples when includeExamples is false", () => {
|
||||
const result = buildUserPrompt("improve", testText, false);
|
||||
|
||||
expect(result).not.toContain("Here are some examples");
|
||||
expect(result).not.toContain("Example 1:");
|
||||
expect(result).not.toContain(IMPROVE_EXAMPLES[0].input);
|
||||
});
|
||||
|
||||
it("should have simple prompt without examples", () => {
|
||||
const result = buildUserPrompt("improve", testText, false);
|
||||
|
||||
expect(result).toBe(
|
||||
`Please enhance the following task description:\n\n${testText}`
|
||||
);
|
||||
});
|
||||
|
||||
it("should preserve user text without examples", () => {
|
||||
const result = buildUserPrompt("technical", testText, false);
|
||||
|
||||
expect(result).toContain(testText);
|
||||
expect(result).toContain("Please enhance");
|
||||
});
|
||||
});
|
||||
|
||||
describe("text formatting", () => {
|
||||
it("should preserve multiline text", () => {
|
||||
const multilineText = "Line 1\nLine 2\nLine 3";
|
||||
const result = buildUserPrompt("improve", multilineText);
|
||||
|
||||
expect(result).toContain(multilineText);
|
||||
});
|
||||
|
||||
it("should handle empty text", () => {
|
||||
const result = buildUserPrompt("improve", "");
|
||||
|
||||
// With examples by default, it should contain "Now, please enhance"
|
||||
expect(result).toContain("Now, please enhance");
|
||||
expect(result).toContain("Here are some examples");
|
||||
});
|
||||
|
||||
it("should handle whitespace-only text", () => {
|
||||
const result = buildUserPrompt("improve", " ");
|
||||
|
||||
expect(result).toContain(" ");
|
||||
});
|
||||
|
||||
it("should handle special characters in text", () => {
|
||||
const specialText = "Test <html> & \"quotes\" 'apostrophes'";
|
||||
const result = buildUserPrompt("improve", specialText);
|
||||
|
||||
expect(result).toContain(specialText);
|
||||
});
|
||||
});
|
||||
|
||||
describe("all modes", () => {
|
||||
it("should work for all valid enhancement modes", () => {
|
||||
const modes: Array<"improve" | "technical" | "simplify" | "acceptance"> =
|
||||
["improve", "technical", "simplify", "acceptance"];
|
||||
|
||||
modes.forEach((mode) => {
|
||||
const result = buildUserPrompt(mode, testText);
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(result).toContain(testText);
|
||||
expect(result.length).toBeGreaterThan(testText.length);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("isValidEnhancementMode", () => {
|
||||
it("should return true for 'improve'", () => {
|
||||
expect(isValidEnhancementMode("improve")).toBe(true);
|
||||
});
|
||||
|
||||
it("should return true for 'technical'", () => {
|
||||
expect(isValidEnhancementMode("technical")).toBe(true);
|
||||
});
|
||||
|
||||
it("should return true for 'simplify'", () => {
|
||||
expect(isValidEnhancementMode("simplify")).toBe(true);
|
||||
});
|
||||
|
||||
it("should return true for 'acceptance'", () => {
|
||||
expect(isValidEnhancementMode("acceptance")).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false for invalid mode", () => {
|
||||
expect(isValidEnhancementMode("invalid")).toBe(false);
|
||||
});
|
||||
|
||||
it("should return false for empty string", () => {
|
||||
expect(isValidEnhancementMode("")).toBe(false);
|
||||
});
|
||||
|
||||
it("should return false for uppercase mode", () => {
|
||||
// Should be case-sensitive since we check object keys directly
|
||||
expect(isValidEnhancementMode("IMPROVE")).toBe(false);
|
||||
});
|
||||
|
||||
it("should return false for mixed case mode", () => {
|
||||
expect(isValidEnhancementMode("ImProve")).toBe(false);
|
||||
});
|
||||
|
||||
it("should return false for partial mode names", () => {
|
||||
expect(isValidEnhancementMode("impro")).toBe(false);
|
||||
expect(isValidEnhancementMode("tech")).toBe(false);
|
||||
});
|
||||
|
||||
it("should return false for mode with extra characters", () => {
|
||||
expect(isValidEnhancementMode("improve ")).toBe(false);
|
||||
expect(isValidEnhancementMode(" improve")).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("getAvailableEnhancementModes", () => {
|
||||
it("should return array of all enhancement modes", () => {
|
||||
const modes = getAvailableEnhancementModes();
|
||||
|
||||
expect(Array.isArray(modes)).toBe(true);
|
||||
expect(modes.length).toBe(4);
|
||||
});
|
||||
|
||||
it("should include all valid modes", () => {
|
||||
const modes = getAvailableEnhancementModes();
|
||||
|
||||
expect(modes).toContain("improve");
|
||||
expect(modes).toContain("technical");
|
||||
expect(modes).toContain("simplify");
|
||||
expect(modes).toContain("acceptance");
|
||||
});
|
||||
|
||||
it("should return modes in consistent order", () => {
|
||||
const modes1 = getAvailableEnhancementModes();
|
||||
const modes2 = getAvailableEnhancementModes();
|
||||
|
||||
expect(modes1).toEqual(modes2);
|
||||
});
|
||||
|
||||
it("should return all valid modes that pass isValidEnhancementMode", () => {
|
||||
const modes = getAvailableEnhancementModes();
|
||||
|
||||
modes.forEach((mode) => {
|
||||
expect(isValidEnhancementMode(mode)).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("Integration tests", () => {
|
||||
it("should work together: getEnhancementPrompt + buildUserPrompt", () => {
|
||||
const mode = "improve";
|
||||
const text = "Add search feature";
|
||||
|
||||
const { systemPrompt, description } = getEnhancementPrompt(mode);
|
||||
const userPrompt = buildUserPrompt(mode, text);
|
||||
|
||||
expect(systemPrompt).toBe(IMPROVE_SYSTEM_PROMPT);
|
||||
expect(description).toBeDefined();
|
||||
expect(userPrompt).toContain(text);
|
||||
});
|
||||
|
||||
it("should handle complete enhancement workflow", () => {
|
||||
const availableModes = getAvailableEnhancementModes();
|
||||
|
||||
expect(availableModes.length).toBeGreaterThan(0);
|
||||
|
||||
availableModes.forEach((mode) => {
|
||||
const isValid = isValidEnhancementMode(mode);
|
||||
expect(isValid).toBe(true);
|
||||
|
||||
const systemPrompt = getSystemPrompt(mode);
|
||||
expect(systemPrompt).toBeDefined();
|
||||
expect(systemPrompt.length).toBeGreaterThan(0);
|
||||
|
||||
const examples = getExamples(mode);
|
||||
expect(Array.isArray(examples)).toBe(true);
|
||||
expect(examples.length).toBeGreaterThan(0);
|
||||
|
||||
const userPrompt = buildUserPrompt(mode, "test description");
|
||||
expect(userPrompt).toContain("test description");
|
||||
});
|
||||
});
|
||||
|
||||
it("should provide consistent data across functions", () => {
|
||||
const mode = "technical";
|
||||
|
||||
const promptConfig = getEnhancementPrompt(mode);
|
||||
const systemPrompt = getSystemPrompt(mode);
|
||||
const examples = getExamples(mode);
|
||||
|
||||
expect(promptConfig.systemPrompt).toBe(systemPrompt);
|
||||
expect(examples).toBe(TECHNICAL_EXAMPLES);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Examples content validation", () => {
|
||||
it("IMPROVE_EXAMPLES should demonstrate improvement", () => {
|
||||
IMPROVE_EXAMPLES.forEach((example) => {
|
||||
// Output should be longer and more detailed than input
|
||||
expect(example.output.length).toBeGreaterThan(example.input.length);
|
||||
// Input should be brief/vague
|
||||
expect(example.input.length).toBeLessThan(100);
|
||||
});
|
||||
});
|
||||
|
||||
it("TECHNICAL_EXAMPLES should contain technical terms", () => {
|
||||
const technicalTerms = [
|
||||
"API",
|
||||
"endpoint",
|
||||
"component",
|
||||
"database",
|
||||
"frontend",
|
||||
"backend",
|
||||
"validation",
|
||||
"schema",
|
||||
"React",
|
||||
"GET",
|
||||
"PUT",
|
||||
"POST",
|
||||
];
|
||||
|
||||
TECHNICAL_EXAMPLES.forEach((example) => {
|
||||
const hasAnyTechnicalTerm = technicalTerms.some((term) =>
|
||||
example.output.includes(term)
|
||||
);
|
||||
expect(hasAnyTechnicalTerm).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("ACCEPTANCE_EXAMPLES should contain acceptance criteria format", () => {
|
||||
ACCEPTANCE_EXAMPLES.forEach((example) => {
|
||||
// Should contain numbered criteria or Given-When-Then format
|
||||
const hasAcceptanceCriteria =
|
||||
example.output.includes("Acceptance Criteria") ||
|
||||
example.output.match(/\d+\./g);
|
||||
expect(hasAcceptanceCriteria).toBeTruthy();
|
||||
|
||||
// Should contain Given-When-Then format
|
||||
const hasGWT =
|
||||
example.output.includes("Given") &&
|
||||
example.output.includes("when") &&
|
||||
example.output.includes("then");
|
||||
expect(hasGWT).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user