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:
@@ -88,12 +88,12 @@ function RichContent({ text }) {
|
||||
)
|
||||
}
|
||||
|
||||
export default function MessageBubble({ message, onReplay, character }) {
|
||||
export default function MessageBubble({ message, onReplay, onRetry, character }) {
|
||||
const isUser = message.role === 'user'
|
||||
|
||||
return (
|
||||
<div className={`flex ${isUser ? 'justify-end' : 'justify-start'} px-4 py-1.5`}>
|
||||
<div className={`flex items-start gap-3 max-w-[80%] ${isUser ? 'flex-row-reverse' : ''}`}>
|
||||
<div className={`flex ${isUser ? 'justify-end' : 'justify-start'} px-3 sm:px-4 py-1.5`}>
|
||||
<div className={`flex items-start gap-2 sm:gap-3 max-w-[92%] sm:max-w-[80%] ${isUser ? 'flex-row-reverse' : ''}`}>
|
||||
{!isUser && <Avatar character={character} />}
|
||||
<div>
|
||||
<div
|
||||
@@ -114,6 +114,18 @@ export default function MessageBubble({ message, onReplay, character }) {
|
||||
{message.model}
|
||||
</span>
|
||||
)}
|
||||
{message.isError && onRetry && (
|
||||
<button
|
||||
onClick={() => onRetry(message.id)}
|
||||
className="text-red-400 hover:text-red-300 transition-colors flex items-center gap-1 text-xs"
|
||||
title="Retry"
|
||||
>
|
||||
<svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0l3.181 3.183a8.25 8.25 0 0013.803-3.7M4.031 9.865a8.25 8.25 0 0113.803-3.7l3.181 3.182" />
|
||||
</svg>
|
||||
Retry
|
||||
</button>
|
||||
)}
|
||||
{!message.isError && onReplay && (
|
||||
<button
|
||||
onClick={() => onReplay(message.content)}
|
||||
|
||||
Reference in New Issue
Block a user