import { dirname } from "node:path"; import type { Content } from "../content/content.js"; import { isDefined } from "../util.js"; import type { Message } from "./index.js"; export async function addContentMessages( content: Content, context: Record, ) { content.meta ??= {}; if (content.context.folder) content.meta.messages = getMessagesFolder(content, context); else content.meta.messages = getMessagesPredecessor(content, context); const messages = content.meta.messages; if ( messages.at(-1)?.role === "assistant" && (content.context.edit || !content.meta.continue) ) { messages.splice(-1, 1); } if (content.context.edit) { const lang = content.context.edit.file.split(".").at(-1) ?? ""; messages.push({ role: "assistant", content: `\`\`\`${lang}`, tokens: Number.NaN, }); } } export function getMessagesPredecessor( content: Content, context: Record, ): Message[] { const system = (content.context.system ?? []) .map((s) => s.content) .join("\n"); const history: Content[] = []; while (content) { history.push(content); // biome-ignore lint/style/noParameterAssign: Collate content up the stack content = context[content.context.predecessor ?? -1]; } history.reverse(); const augment: Message[] = history.flatMap((c) => (c.context.augment ?? []).map(({ content }) => ({ role: "user", content, tokens: Number.NaN, })), ); const parts: Message[] = history .flatMap((content) => [ { role: "user", content: content.prompt, }, content.response ? { role: "assistant", content: content.response } : undefined, ]) .filter(isDefined); return [ { role: "system", content: system } satisfies Message, ...augment, ...parts, ]; } export function getMessagesFolder( content: Content, context: Record, ): Message[] { // TODO: move this to a template const system = `${(content.context.system ?? []) .map((s) => s.content) .join( "\n", )}\nInstructions are happening in the context of this folder:\n\n${(content.context.folder ?? []) .map((c) => context[c]) .map( (c) => `\n${ c.meta?.text ?? `${c.prompt}\n${c.response}` }`, ) .join("\n")}\n`; const history: Content[] = [content]; const augment: Message[] = []; const parts: Message[] = history .flatMap((content) => [ { role: "user", content: content.prompt, tokens: Number.NaN, }, content.response ? { role: "assistant", content: content.response, tokens: Number.NaN } : undefined, ]) .filter(isDefined); return [ { role: "system", content: system, tokens: Number.NaN }, ...augment, ...parts, ]; }