Forked from arkantu/arkantu-core-tools
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();
// Detect first turn of conversation
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) {
// Not the first turn: return the message as is
return userMessage;
}
// Reset injection flag for each new conversation
injectedThisSession = false;
// Select system prompt based on configuration
let systemDoc = compact ? SYSTEM_PROMPT_LITE : SYSTEM_PROMPT_FULL;
// Try loading custom instructions from the 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 loaded from: ${p}`);
break;
}
} catch { /* ignore if not exists */ }
}
// Try loading persistent memory
try {
const memPath = join(state.cwd, "memory.md");
const mem = await readFile(memPath, "utf-8");
if (mem.trim()) {
systemDoc += `\n\n## 🧠Persistent Memory\n${mem.substring(0, 2000)}`;
}
} catch { /* no memory.md found */ }
injectedThisSession = true;
return `${systemDoc}\n\n---\n\n${userText}`;
}