feat(chat): add system prompt editor & personas (M9.2)

Named personas with system prompt, model preference, and accent colour.
Persona pill selector above chat input, editor modal for create/edit/delete.
Default persona auto-applied to new conversations. Persona system prompt
prepended to AI context.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-03 23:29:01 +00:00
co-authored by Claude Opus 4.6
parent 27aeb2b188
commit 77b985db9c
6 changed files with 450 additions and 14 deletions
+26 -12
View File
@@ -3,6 +3,7 @@ import { useChatStore } from '@/stores/chat'
import { searchWeb } from '@/composables/useWebSearch'
import { getApiKey } from '@/utils/key-vault'
import type { ImageAttachment } from '@aiui/core/types/message'
import { usePersonaStore } from '@/stores/personas'
type Provider = 'claude' | 'openrouter' | 'mock'
@@ -303,6 +304,29 @@ function formatWebSearchContext(results: { title: string; url: string; content?:
- You MAY add [[podcast_ext:...]] or [[film_ext:...]] tags for "to learn more" recommendations after your answer.\n\n${lines.join('\n')}`
}
/** Build the system prompt, incorporating persona if active */
function buildSystemPrompt(chatStore: ReturnType<typeof useChatStore>): string {
let prompt = SYSTEM_PROMPT
// Prepend persona system prompt if active
const personaId = chatStore.activeConversation?.personaId
if (personaId) {
const personaStore = usePersonaStore()
const persona = personaStore.getPersona(personaId)
if (persona?.systemPrompt) {
prompt = persona.systemPrompt + '\n\n' + prompt
}
}
if (chatStore.webSearchEnabled) {
prompt += `
**Web search:** You have access to WebSearch and WebFetch tools. Use them to look up current information, news, and facts when the user asks. You can search the web and fetch page content. Web search is enabled for this session—do not tell the user it is unavailable.`
}
return prompt
}
let currentAbort: AbortController | null = null
/** Background title generation after first exchange */
@@ -408,12 +432,7 @@ export function useAI() {
chatStore.isStreaming = true
let systemPrompt = SYSTEM_PROMPT
if (chatStore.webSearchEnabled) {
systemPrompt += `
**Web search:** You have access to WebSearch and WebFetch tools. Use them to look up current information, news, and facts when the user asks. You can search the web and fetch page content. Web search is enabled for this session—do not tell the user it is unavailable.`
}
let systemPrompt = buildSystemPrompt(chatStore)
if (chatStore.webSearchEnabled && userText.trim()) {
const results = await searchWeb(userText)
if (results.length > 0) {
@@ -522,12 +541,7 @@ export function useAI() {
chatStore.isStreaming = true
let systemPrompt = SYSTEM_PROMPT
if (chatStore.webSearchEnabled) {
systemPrompt += `
**Web search:** You have access to WebSearch and WebFetch tools. Use them to look up current information, news, and facts when the user asks. You can search the web and fetch page content. Web search is enabled for this session—do not tell the user it is unavailable.`
}
let systemPrompt = buildSystemPrompt(chatStore)
if (chatStore.webSearchEnabled && lastUserMsg.content.trim()) {
const results = await searchWeb(lastUserMsg.content)
if (results.length > 0) {