feat: add streamDocumentation SSE client for ticket notes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
chihlasm
2026-03-28 23:05:20 +00:00
parent 7a5d56494b
commit bcab8158ab

View File

@@ -99,6 +99,69 @@ export const aiSessionsApi = {
return response.data
},
async streamDocumentation(
sessionId: string,
onChunk: (text: string) => void,
onDone: () => void,
onError: (error: string) => void,
): Promise<void> {
const token = localStorage.getItem('access_token')
const baseUrl = import.meta.env.VITE_API_URL || ''
try {
const response = await fetch(
`${baseUrl}/api/ai-sessions/${sessionId}/documentation/stream`,
{
headers: {
Authorization: `Bearer ${token}`,
},
},
)
if (!response.ok) {
onError(`HTTP ${response.status}`)
return
}
const reader = response.body?.getReader()
if (!reader) {
onError('No response body')
return
}
const decoder = new TextDecoder()
let buffer = ''
while (true) {
const { done, value } = await reader.read()
if (done) break
buffer += decoder.decode(value, { stream: true })
const lines = buffer.split('\n')
buffer = lines.pop() || ''
for (const line of lines) {
if (line.startsWith('data: ')) {
const data = line.slice(6)
if (data === '[DONE]') {
onDone()
return
}
if (data.startsWith('[ERROR]')) {
onError(data.slice(8))
return
}
onChunk(data)
}
}
}
// Stream ended without [DONE]
onDone()
} catch (err) {
onError(err instanceof Error ? err.message : 'Stream failed')
}
},
async rateSession(sessionId: string, data: { rating: number; feedback?: string }): Promise<void> {
await apiClient.post(`/ai-sessions/${sessionId}/rate`, data)
},