src / promptPreprocessor.ts
import { type PromptPreprocessorController, type ChatMessage } from "@lmstudio/sdk";
import { pluginConfig as configSchematics } from "./config";
import { SYSTEM_PROMPT_FULL, SYSTEM_PROMPT_LITE } from "./systemPrompt";
import { readFile } from "fs/promises";
import { join } from "path";
import { loadState } from "./state";
let injectedThisSession = false;
export async function promptPreprocessor(
ctl: PromptPreprocessorController,
userMessage: ChatMessage
): Promise<string | ChatMessage> {
const cfg = ctl.getPluginConfig(configSchematics);
const workspacePath = cfg.get("workspacePath");
const compact = cfg.get("compactSystemPrompt");
const history = await ctl.pullHistory();
// Detectar primer turno de conversación
let isFirst = false;
if (Array.isArray(history)) {
isFirst = history.length === 0;
} else if ("messages" in (history as any)) {
isFirst = (history as any).messages.length === 0;
} else {
isFirst = true;
}
history.append(userMessage);
const userText = userMessage.getText();
if (!isFirst) {
// No primer turno: devuelve el mensaje tal cual
return userMessage;
}
// Reinicia flag de inyección en cada conversación nueva
injectedThisSession = false;
// Elige el sistema prompt según configuración
let systemDoc = compact ? SYSTEM_PROMPT_LITE : SYSTEM_PROMPT_FULL;
// Intenta cargar instrucciones personalizadas del workspace
const state = await loadState(workspacePath);
const customPaths = [
join(state.cwd, ".arkantu", "startup.md"),
join(state.cwd, "instructions", "startup.md"),
join(workspacePath, ".arkantu", "startup.md"),
];
for (const p of customPaths) {
try {
const custom = await readFile(p, "utf-8");
if (custom.trim()) {
systemDoc = `${custom}\n\n---\n\n${systemDoc}`;
ctl.debug(`[arkantu-core] startup.md cargado desde: ${p}`);
break;
}
} catch { /* no existe, ignorar */ }
}
// Intenta cargar memoria persistente
try {
const memPath = join(state.cwd, "memory.md");
const mem = await readFile(memPath, "utf-8");
if (mem.trim()) {
systemDoc += `\n\n## 🧠 Memoria persistente\n${mem.substring(0, 2000)}`;
}
} catch { /* no hay memory.md */ }
injectedThisSession = true;
return `${systemDoc}\n\n---\n\n${userText}`;
}