Project Files
src / preprocessor.ts
/**
* @file Merged preprocessor — runs memory injection first, then tools RAG/docs injection.
*
* Order: memory (prepends relevant memories) → tools (appends RAG citations, docs, delegation hints).
* The model sees: [memories] + [user message] + [RAG citations / docs / delegation]
*/
import type { PromptPreprocessorController } from "@lmstudio/sdk";
import { promptPreprocessor as memoryPreprocessor } from "./memory/preprocessor";
import { promptPreprocessor as toolsPreprocessor } from "./tools/promptPreprocessor";
export async function maestroPreprocessor(
ctl: PromptPreprocessorController,
userMessage: any,
): Promise<any> {
// Stage 1: inject memories (expects string in, string out)
let messageText: string;
if (typeof userMessage === "string") {
messageText = userMessage;
} else if (typeof userMessage?.getText === "function") {
messageText = userMessage.getText();
} else {
messageText = String(userMessage);
}
let afterMemory: string;
try {
const memResult = await memoryPreprocessor(ctl as any, messageText);
afterMemory = typeof memResult === "string" ? memResult : messageText;
} catch {
// Memory preprocessor failed — continue without it
afterMemory = messageText;
}
// Stage 2: run tools preprocessor (expects ChatMessage or string)
try {
// If the SDK gives us a ChatMessage object, create a wrapper with the memory-enriched text
if (typeof userMessage !== "string" && typeof userMessage?.getText === "function") {
// Replace the text content if memories were injected
if (afterMemory !== messageText && typeof userMessage.replaceText === "function") {
userMessage.replaceText(afterMemory);
}
return toolsPreprocessor(ctl, userMessage);
}
// String-based SDK — pass enriched string directly
return toolsPreprocessor(ctl, afterMemory as any);
} catch {
// Tools preprocessor failed — return memory-enriched content
return afterMemory;
}
}