How to Customize the System Prompt and Citation Formatting in MiniSearch
You can customize the system prompt and citation formatting in MiniSearch by editing the systemPrompt template in client/modules/settings.ts and modifying the getFormattedSearchResults() function in client/modules/textGenerationUtilities.ts to control how search results appear to the LLM.
MiniSearch is an open-source AI search interface that exposes its prompt assembly logic through user-editable settings and modular utility functions. The repository felladrin/minisearch separates prompt templates from result formatting, allowing you to tailor both the assistant's personality and citation style without touching core generation logic.
Where the System Prompt Template Lives
The default prompt is defined in client/modules/settings.ts as the systemPrompt property of defaultSettings. This template uses placeholder syntax for dynamic values:
systemPrompt: `Answer using the search results below as your primary source, supplemented by your own knowledge when needed. …
Below are the search results fetched at {{currentDate}}.
{{searchResults}}`,
The template contains two key placeholders:
{{searchResults}}— Replaced with formatted search results at runtime{{currentDate}}or{{dateTime}}— Replaced with the current date inen-CAformat
Source: client/modules/settings.ts:19-27
Runtime Prompt Assembly
When processing a query, client/modules/systemPrompt.ts interpolates the template through the getSystemPrompt() function:
export function getSystemPrompt(searchResults: string) {
const currentDate = new Intl.DateTimeFormat("en-CA", {
year: "numeric",
month: "2-digit",
day: "2-digit",
}).format(new Date());
return getSettings()
.systemPrompt.replace("{{searchResults}}", searchResults)
.replace(/{{dateTime}}|{{currentDate}}/g, currentDate);
}
This function pulls live settings via getSettings(), then performs string replacement to inject the formatted results and timestamp. Any customizations made to the systemPrompt setting automatically flow through this interpolation chain.
Source: client/modules/systemPrompt.ts:8-17
Editing the Prompt Through the UI
Users can modify the system prompt without editing source files. The System Prompt editor resides in client/components/Pages/Main/Menu/AISettings/components/SystemPromptInput.tsx, which binds a <Textarea> component directly to the systemPrompt field:
- Custom prompts persist via
settingsPubSuband override defaults immediately - Restore default functionality calls
handleRestoreDefaultInstructions()to revert to the template defined indefaultSettings
Source: SystemPromptInput.tsx:17-26
How Citations Are Generated
The bullet list that replaces {{searchResults}} is constructed by getFormattedSearchResults() in client/modules/textGenerationUtilities.ts:
export function getFormattedSearchResults(shouldIncludeUrl: boolean) {
const searchResults = getLlmTextSearchResults();
if (searchResults.length === 0) return "None.";
if (shouldIncludeUrl) {
return searchResults
.map(([title, snippet, url]) => `• [${title}](${url}) | ${snippet}`)
.join("\n");
}
return searchResults
.map(([title, snippet]) => `• ${title} | ${snippet}`)
.join("\n");
}
When shouldIncludeUrl is true (the default in the generation flow), each result renders as a markdown link [title](url) followed by the snippet. This formatted string becomes the value substituted for {{searchResults}} in the system prompt.
Source: textGenerationUtilities.ts:38-45
Customizing Citation Formatting
You have two entry points to modify citation appearance:
1. Edit the template description — Update defaultSettings.systemPrompt (or the UI field) to instruct the LLM on alternative citation styles (e.g., footnotes, author-date, or numbered references).
2. Override the formatter function — Modify getFormattedSearchResults() in client/modules/textGenerationUtilities.ts to output different markdown structures. For example, to extract domain-only citations:
.map(([title, snippet, url]) => {
const domain = new URL(url).hostname.replace(/^www\./, '');
return `• ${title} (${domain}) | ${snippet}`;
})
End-to-End Flow
- User edits the prompt in AI Settings → updates persist via
settingsPubSub textGeneration.tscallsgetFormattedSearchResults(true)to generate the markdown listgetSystemPrompt()substitutes{{searchResults}}and date placeholders- Final string populates the first chat message (
ChatMessage.role === "user") sent to the LLM
Sources: textGeneration.ts:12-18 and textGenerationUtilities.ts:12-18
Complete Customization Examples
Changing the Default System Prompt
Modify client/modules/settings.ts to enforce footnote-style citations:
// client/modules/settings.ts
export const defaultSettings = {
// …other settings,
systemPrompt: `You are a concise assistant. Use the results below as your only source.
// Custom citation rule (footnotes):
Cite each fact with a footnote like [^1]. The footnote list will appear after the answer.
Fetched on {{currentDate}}:
{{searchResults}}`,
};
Adding a Custom Citation Formatter
Extend client/modules/textGenerationUtilities.ts to generate numbered footnotes:
// client/modules/textGenerationUtilities.ts
export function getFormattedSearchResults(shouldIncludeUrl: boolean) {
const searchResults = getLlmTextSearchResults();
if (searchResults.length === 0) return "None.";
if (shouldIncludeUrl) {
// New footnote style
return searchResults
.map(([title, snippet, url], idx) => {
const footnote = `[^${idx + 1}]`;
return `• ${title} ${footnote} | ${snippet}`;
})
.join("\n");
}
return searchResults
.map(([title, snippet]) => `• ${title} | ${snippet}`)
.join("\n");
}
Then append footnote definitions in client/modules/systemPrompt.ts:
// client/modules/systemPrompt.ts
export function getSystemPrompt(searchResults: string) {
const currentDate = new Intl.DateTimeFormat("en-CA", {
year: "numeric",
month: "2-digit",
day: "2-digit",
}).format(new Date());
const promptWithResults = getSettings()
.systemPrompt.replace("{{searchResults}}", searchResults)
.replace(/{{dateTime}}|{{currentDate}}/g, currentDate);
const footnotes = getLlmTextSearchResults()
.map(([, , url], idx) => `[^${idx + 1}]: ${url}`)
.join("\n");
return `${promptWithResults}\n\n${footnotes}`;
}
Summary
- Template location: The default system prompt lives in
client/modules/settings.tsasdefaultSettings.systemPrompt, supporting{{searchResults}}and{{currentDate}}placeholders. - Runtime interpolation:
getSystemPrompt()inclient/modules/systemPrompt.tsperforms placeholder substitution using live settings. - UI editing: Users can modify prompts via
SystemPromptInput.tsx, with changes persisting throughsettingsPubSub. - Citation formatting:
getFormattedSearchResults()inclient/modules/textGenerationUtilities.tscontrols how search results appear, defaulting to markdown bullet lists with linked titles. - Customization paths: Change the template text to alter instructions, or modify the formatter function to change the actual citation markup structure.
Frequently Asked Questions
How do I reset the system prompt to default in MiniSearch?
Click the restore default button in the AI Settings UI, which triggers handleRestoreDefaultInstructions() in SystemPromptInput.tsx to reset the form value to defaultSettings.systemPrompt. This reverts any custom text to the original template defined in client/modules/settings.ts.
Can I use different date formats in the system prompt?
Yes. Modify the Intl.DateTimeFormat configuration in getSystemPrompt() within client/modules/systemPrompt.ts. The current implementation hardcodes "en-CA" with year: "numeric", month: "2-digit", and day: "2-digit", but you can change the locale or options to match regional requirements.
Where does MiniSearch inject the formatted prompt into the LLM request?
The assembled prompt is injected into the chat message array by client/modules/textGeneration.ts (lines 12-18) and client/modules/textGenerationUtilities.ts (lines 12-18). The system prompt becomes the first user message (ChatMessage.role === "user") sent to the language model, combining the template, current date, and formatted search results.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →