feat: voice mic, pixel life layer, enhanced transcript-debug UX

VoiceMicButton component, PixelLife aquatic layer, improved UserMessageBubble
with voice display, AgentBadge terminal switcher, ChatContainer voice integration,
FloatingTranscriptDebug ocean life enhancements, and terminal registry support.
Remove traefik config.
This commit is contained in:
2026-02-20 12:12:53 -06:00
parent b7f03a777b
commit 220d595568
19 changed files with 2221 additions and 358 deletions

View File

@@ -1,6 +1,7 @@
<script setup lang="ts">
import { onMounted, onUnmounted } from 'vue'
import { useTranscriptDebug } from '@/composables/transcript-debug'
import { useVoiceInput } from '@/composables/useVoiceInput'
import { SessionSelector, RawJsonViewer, ChatContainer } from '@/components/transcript-debug'
import type { AgentName } from '@/types/transcript-debug'
@@ -27,6 +28,19 @@ const {
sendPrompt
} = useTranscriptDebug()
const voice = useVoiceInput({ language: 'es-419' })
const {
isRecording: voiceRecording,
transcript: voiceTranscript,
interimTranscript: voiceInterim,
voiceMode,
whisperStatus,
audioDevices,
selectedDeviceId,
lastAudioUrl,
isPlayingAudio,
} = voice
const agents: { id: AgentName; label: string }[] = [
{ id: 'ejecutor', label: 'Ejecutor' },
{ id: 'nucleo000', label: 'nucleo000' },
@@ -34,6 +48,7 @@ const agents: { id: AgentName; label: string }[] = [
]
function handleSend(message: string) {
voice.clearTranscript()
sendPrompt(message)
}
@@ -41,12 +56,14 @@ function handleCreateSession() {
createNewSession()
}
onMounted(() => {
onMounted(async () => {
init()
await voice.init()
})
onUnmounted(() => {
disconnectRealtime()
voice.cleanup()
})
</script>
@@ -119,8 +136,21 @@ onUnmounted(() => {
:terminal-ready="terminalReady"
:terminal="ephemeral"
:selected-agent="selectedAgent"
:voice-mode="voiceMode"
:whisper-status="whisperStatus"
:audio-devices="audioDevices"
:selected-device-id="selectedDeviceId"
:is-recording="voiceRecording"
:voice-transcript="voiceTranscript + voiceInterim"
:last-audio-url="lastAudioUrl"
:is-playing-audio="isPlayingAudio"
@send="handleSend"
@create-session="handleCreateSession"
@start-recording="voice.startRecording()"
@stop-recording="voice.stopRecording()"
@set-voice-mode="voice.setMode($event)"
@select-microphone="voice.selectMicrophone($event)"
@play-last-audio="voice.playLastAudio()"
/>
</div>
</div>