feat: character system v2 — schema upgrade, memory system, per-character TTS routing
Character schema v2: background, dialogue_style, appearance, skills, gaze_presets with automatic v1→v2 migration. LLM-assisted character creation via Character MCP server. Two-tier memory system (personal per-character + general shared) with budget-based injection into LLM system prompt. Per-character TTS voice routing via state file — Wyoming TTS server reads active config to route between Kokoro (local) and ElevenLabs (cloud PCM 24kHz). Dashboard: memories page, conversation history, character profile on cards, auto-TTS engine selection from character config. Also includes VTube Studio expression bridge and ComfyUI API guide. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,30 @@
|
||||
export async function sendMessage(text) {
|
||||
const res = await fetch('/api/agent/message', {
|
||||
const MAX_RETRIES = 3
|
||||
const RETRY_DELAY_MS = 2000
|
||||
|
||||
async function fetchWithRetry(url, options, retries = MAX_RETRIES) {
|
||||
for (let attempt = 1; attempt <= retries; attempt++) {
|
||||
try {
|
||||
const res = await fetch(url, options)
|
||||
if (res.status === 502 && attempt < retries) {
|
||||
// Bridge unreachable — wait and retry
|
||||
await new Promise(r => setTimeout(r, RETRY_DELAY_MS * attempt))
|
||||
continue
|
||||
}
|
||||
return res
|
||||
} catch (err) {
|
||||
if (attempt >= retries) throw err
|
||||
await new Promise(r => setTimeout(r, RETRY_DELAY_MS * attempt))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function sendMessage(text, characterId = null) {
|
||||
const payload = { message: text, agent: 'main' }
|
||||
if (characterId) payload.character_id = characterId
|
||||
const res = await fetchWithRetry('/api/agent/message', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ message: text, agent: 'main' }),
|
||||
body: JSON.stringify(payload),
|
||||
})
|
||||
if (!res.ok) {
|
||||
const err = await res.json().catch(() => ({ error: 'Request failed' }))
|
||||
@@ -12,11 +34,13 @@ export async function sendMessage(text) {
|
||||
return data.response
|
||||
}
|
||||
|
||||
export async function synthesize(text, voice) {
|
||||
export async function synthesize(text, voice, engine = 'kokoro', model = null) {
|
||||
const payload = { text, voice, engine }
|
||||
if (model) payload.model = model
|
||||
const res = await fetch('/api/tts', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ text, voice }),
|
||||
body: JSON.stringify(payload),
|
||||
})
|
||||
if (!res.ok) throw new Error('TTS failed')
|
||||
return await res.arrayBuffer()
|
||||
|
||||
Reference in New Issue
Block a user