feat: memory v2, prompt styles, Dream/GAZE integration, Wyoming TTS fix

SQLite + sqlite-vec replaces JSON memory files with semantic search,
follow-up injection, privacy levels, and lifecycle management.

Six prompt styles (quick/standard/creative/roleplayer/game-master/storyteller)
with per-style Claude model tiering (Haiku/Sonnet/Opus), temperature control,
and section stripping. Characters can set default style and per-style overrides.

Dream character import and GAZE character linking in the dashboard editor
with auto-populated fields, cover image resolution, and preset assignment.

Bridge: session isolation (conversation_id / 12h satellite buckets),
model routing refactor, PUT/DELETE support, memory REST endpoints.

Dashboard: mobile-responsive sidebar, retry button, style picker in chat,
follow-up banner, memory lifecycle/privacy UI, cloud model options in editor.

Wyoming TTS: upgraded to v1.8.0 for HA 1.7.2 compatibility.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Aodhan Collins
2026-03-24 22:31:04 +00:00
parent c3bae6fdc0
commit 56580a2cb2
34 changed files with 2891 additions and 467 deletions

View File

@@ -18,9 +18,11 @@ async function fetchWithRetry(url, options, retries = MAX_RETRIES) {
}
}
export async function sendMessage(text, characterId = null) {
export async function sendMessage(text, characterId = null, promptStyle = null, conversationId = null) {
const payload = { message: text, agent: 'main' }
if (characterId) payload.character_id = characterId
if (promptStyle) payload.prompt_style = promptStyle
if (conversationId) payload.conversation_id = conversationId
const res = await fetchWithRetry('/api/agent/message', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
@@ -31,7 +33,29 @@ export async function sendMessage(text, characterId = null) {
throw new Error(err.error || `HTTP ${res.status}`)
}
const data = await res.json()
return { response: data.response, model: data.model || null }
return { response: data.response, model: data.model || null, prompt_style: data.prompt_style || null }
}
export async function getPromptStyles() {
const res = await fetch('/api/prompt-styles')
if (!res.ok) return []
return await res.json()
}
export async function getActiveStyle() {
const res = await fetch('/api/prompt-style')
if (!res.ok) return { style: 'standard' }
return await res.json()
}
export async function setActiveStyle(style) {
const res = await fetch('/api/prompt-style', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ style }),
})
if (!res.ok) throw new Error('Failed to set prompt style')
return await res.json()
}
export async function synthesize(text, voice, engine = 'kokoro', model = null) {