refactor(lmc): modularize prompt generation and add XML-like fences

This commit is contained in:
mitchell 2026-06-26 16:55:57 -04:00
parent da317b7177
commit b1730bfaf4
2 changed files with 42 additions and 29 deletions

View file

@ -8,7 +8,14 @@ import { streamText } from "ai";
import { initConfig, loadConfig } from "./config"; import { initConfig, loadConfig } from "./config";
import { Conversation } from "./conversation"; import { Conversation } from "./conversation";
import { handleTopLevel } from "./errors"; import { handleTopLevel } from "./errors";
import { commitDiff, file, reviewDiff, reviewFile } from "./prompts"; import {
base,
commitDiff,
contextFence,
diffFence,
fileFence,
review,
} from "./prompts";
import Renderer from "./render"; import Renderer from "./render";
async function main() { async function main() {
@ -32,6 +39,8 @@ async function main() {
r: { type: "boolean" }, r: { type: "boolean" },
file: { type: "string" }, file: { type: "string" },
f: { type: "string" }, f: { type: "string" },
stdin: { type: "boolean" },
i: { type: "boolean" },
}, },
strict: true, strict: true,
allowPositionals: true, allowPositionals: true,
@ -46,6 +55,7 @@ async function main() {
const generateGitMessage = args["git-message"] ?? args.g; const generateGitMessage = args["git-message"] ?? args.g;
const generateReview = args.review ?? args.r; const generateReview = args.review ?? args.r;
const inputFile = args.file ?? args.f; const inputFile = args.file ?? args.f;
const stdinContent = args.stdin ?? args.i;
if (showVersion) { if (showVersion) {
console.log("0.0.0"); console.log("0.0.0");
@ -77,20 +87,18 @@ async function main() {
if (modelOverride) convo.model = modelOverride; if (modelOverride) convo.model = modelOverride;
} }
let input = positionals.join(" ").trim(); const input = positionals.join(" ").trim();
if (input === "-") input = await consumers.text(process.stdin); let stdinText = "";
if (stdinContent) stdinText = await consumers.text(process.stdin);
let fileText = "";
if (inputFile)
fileText = fileFence(inputFile, await fs.readFile(inputFile, "utf8"));
let prompt = input; let prompt = base(input, [fileText, contextFence(stdinText)]);
if (generateGitMessage) { if (generateGitMessage) {
prompt = commitDiff(input); prompt = commitDiff(stdinText, [fileText]);
} else if (generateReview && inputFile) {
const content = await fs.readFile(inputFile, "utf8");
prompt = reviewFile(file(inputFile, content));
} else if (inputFile) {
const content = await fs.readFile(inputFile, "utf8");
prompt = `${file(inputFile, content)}\n\n${input}`;
} else if (generateReview) { } else if (generateReview) {
prompt = reviewDiff(input); prompt = review([fileText, stdinText ? diffFence(stdinText) : "", input]);
} }
if (!prompt) throw new Error("No prompt given."); if (!prompt) throw new Error("No prompt given.");

View file

@ -1,26 +1,31 @@
export const file = (name: string, input: string) => `${name}: const blocks = (input?: string[]) =>
\`\`\` input?.map((block) => (block ? `${block}\n` : "")).join("") ?? "";
export const base = (input: string, extra?: string[]) =>
`${blocks(extra)}${input}`;
export const fileFence = (name: string, input: string) => `<file name="${name}">
${input} ${input}
\`\`\``; </file>
`;
export const commitDiff = (input: string) => `\`\`\`diff export const diffFence = (input: string) => `<diff>
${input} ${input}
\`\`\` </diff>`;
Generate a conventional commit message for this diff. If you are unable to generate a reasonable option, ask for more context.`; export const contextFence = (input: string) => `<context>
${input}
</context>`;
export const reviewFile = (input: string) => `${input} export const commitDiff = (
input: string,
extra?: string[],
) => `${blocks(extra)}${diffFence(input)}
Generate a conventional commit message for the included context. If you are unable to generate a reasonable option, ask for more context.`;
export const review = (input: string[]) => `${blocks(input)}
Review the included context for any potential bugs, best practices, performance issues, or security flaws.
Today's date is ${new Date().toISOString()}, your version info is likely out-of-date. Today's date is ${new Date().toISOString()}, your version info is likely out-of-date.
Review the included file for any potential bugs, best practices, performance issues, or security flaws.
Let me know if you need any more context to complete your review.`;
export const reviewDiff = (input: string) => `\`\`\`diff
${input}
\`\`\`
Today's date is ${new Date().toISOString()}, your version info is likely out-of-date.
Review the included diff for any potential bugs, best practices, performance issues, or security flaws.
Let me know if you need any more context to complete your review.`; Let me know if you need any more context to complete your review.`;