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:
@@ -99,6 +99,69 @@ export const aiSessionsApi = {
|
|||||||
return response.data
|
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> {
|
async rateSession(sessionId: string, data: { rating: number; feedback?: string }): Promise<void> {
|
||||||
await apiClient.post(`/ai-sessions/${sessionId}/rate`, data)
|
await apiClient.post(`/ai-sessions/${sessionId}/rate`, data)
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user