Compare commits

...

1 Commits

Author SHA1 Message Date
Augustin
b407ab879b fix(studio): forward AI thinking chunks to frontend instead of dropping them
All checks were successful
Beta Release / beta (push) Successful in 40s
The ThinkingBlock component existed but was dead code — the backend
silently discarded all <think chunks. Now emits thinking SSE events
so the UI can display AI reflections in real-time.

\xe2\x98\x85 Generated with Crush

Assisted-by: GLM-5-Turbo via Crush <crush@charm.land>
2026-04-22 19:12:32 +02:00
2 changed files with 16 additions and 2 deletions

View File

@@ -73,8 +73,20 @@ RÈGLES ABSOLUES:
flusher, canFlush := w.(http.Flusher)
result, err := orb.SendStream(body.Message, func(chunk string) {
// Skip thinking tags - user doesn't see them
if strings.HasPrefix(chunk, "<think") {
data, _ := json.Marshal(map[string]string{"thinking": strings.TrimPrefix(chunk, "<think")})
w.Write([]byte("data: " + string(data) + "\n\n"))
if canFlush {
flusher.Flush()
}
return
}
if chunk == "</think>" {
data, _ := json.Marshal(map[string]string{"thinking_end": "true"})
w.Write([]byte("data: " + string(data) + "\n\n"))
if canFlush {
flusher.Flush()
}
return
}
data, _ := json.Marshal(map[string]string{"content": chunk})

View File

@@ -68,7 +68,9 @@ const api = {
if (data.done) { resolve(full); return }
if (data.content) {
full += data.content
if (onChunk) onChunk(full)
if (onChunk) onChunk(full, data)
} else if (data.thinking !== undefined || data.thinking_end) {
if (onChunk) onChunk(full, data)
}
} catch {}
}