mirror of
https://github.com/Monadical-SAS/reflector.git
synced 2026-02-04 18:06:48 +00:00
- Import topics_to_webvtt_named and recordings controller - Add _get_is_multitrack helper function - Generate WebVTT context on WebSocket connection - Add get_context message type to retrieve WebVTT - Maintain backward compatibility with echo for other messages - Add test fixture and test for WebVTT context generation Implements task fn-1.2: WebVTT context generation for transcript chat
103 lines
2.5 KiB
Markdown
103 lines
2.5 KiB
Markdown
# Task 5: Frontend WebSocket Hook
|
|
|
|
**File:** `www/app/(app)/transcripts/useTranscriptChat.ts`
|
|
**Lines:** ~60
|
|
**Dependencies:** Task 1 (protocol defined)
|
|
|
|
## Objective
|
|
Create React hook for WebSocket chat communication.
|
|
|
|
## Implementation
|
|
```typescript
|
|
import { useEffect, useState, useRef } from "react"
|
|
import { WEBSOCKET_URL } from "../../lib/apiClient"
|
|
|
|
type Message = {
|
|
id: string
|
|
role: "user" | "assistant"
|
|
text: string
|
|
timestamp: Date
|
|
}
|
|
|
|
export const useTranscriptChat = (transcriptId: string) => {
|
|
const [messages, setMessages] = useState<Message[]>([])
|
|
const [isStreaming, setIsStreaming] = useState(false)
|
|
const [currentStreamingText, setCurrentStreamingText] = useState("")
|
|
const wsRef = useRef<WebSocket | null>(null)
|
|
|
|
useEffect(() => {
|
|
const ws = new WebSocket(
|
|
`${WEBSOCKET_URL}/v1/transcripts/${transcriptId}/chat`
|
|
)
|
|
wsRef.current = ws
|
|
|
|
ws.onopen = () => console.log("Chat WebSocket connected")
|
|
|
|
ws.onmessage = (event) => {
|
|
const msg = JSON.parse(event.data)
|
|
|
|
switch (msg.type) {
|
|
case "token":
|
|
setIsStreaming(true)
|
|
setCurrentStreamingText((prev) => prev + msg.text)
|
|
break
|
|
|
|
case "done":
|
|
setMessages((prev) => [
|
|
...prev,
|
|
{
|
|
id: Date.now().toString(),
|
|
role: "assistant",
|
|
text: currentStreamingText,
|
|
timestamp: new Date(),
|
|
},
|
|
])
|
|
setCurrentStreamingText("")
|
|
setIsStreaming(false)
|
|
break
|
|
|
|
case "error":
|
|
console.error("Chat error:", msg.message)
|
|
setIsStreaming(false)
|
|
break
|
|
}
|
|
}
|
|
|
|
ws.onerror = (error) => console.error("WebSocket error:", error)
|
|
ws.onclose = () => console.log("Chat WebSocket closed")
|
|
|
|
return () => ws.close()
|
|
}, [transcriptId, currentStreamingText])
|
|
|
|
const sendMessage = (text: string) => {
|
|
if (!wsRef.current) return
|
|
|
|
setMessages((prev) => [
|
|
...prev,
|
|
{
|
|
id: Date.now().toString(),
|
|
role: "user",
|
|
text,
|
|
timestamp: new Date(),
|
|
},
|
|
])
|
|
|
|
wsRef.current.send(JSON.stringify({ type: "message", text }))
|
|
}
|
|
|
|
return { messages, sendMessage, isStreaming, currentStreamingText }
|
|
}
|
|
```
|
|
|
|
## Validation
|
|
- [ ] Hook connects to WebSocket
|
|
- [ ] Sends messages to server
|
|
- [ ] Receives streaming tokens
|
|
- [ ] Accumulates tokens into messages
|
|
- [ ] Handles done/error events
|
|
- [ ] Closes connection on unmount
|
|
|
|
## Notes
|
|
- Test with browser console first
|
|
- Verify message format matches backend protocol
|