mirror of
https://github.com/CJackHwang/ds2api.git
synced 2026-05-12 12:17:47 +08:00
refactor: improve chat history persistence reliability with metadata-only migration, error handling, and optimized file updates
This commit is contained in:
@@ -36,9 +36,13 @@ func CollectStream(resp *http.Response, thinkingEnabled bool, closeBody bool) Co
|
||||
currentType = "thinking"
|
||||
}
|
||||
_ = deepseek.ScanSSELines(resp, func(line []byte) bool {
|
||||
if chunk, done, parsed := ParseDeepSeekSSELine(line); parsed && !done {
|
||||
chunk, done, parsed := ParseDeepSeekSSELine(line)
|
||||
if parsed && !done {
|
||||
collector.ingestChunk(chunk)
|
||||
}
|
||||
if done {
|
||||
return false
|
||||
}
|
||||
if stopped {
|
||||
return true
|
||||
}
|
||||
@@ -52,7 +56,8 @@ func CollectStream(resp *http.Response, thinkingEnabled bool, closeBody bool) Co
|
||||
contentFilter = true
|
||||
}
|
||||
// Keep scanning to collect late-arriving citation metadata lines
|
||||
// that can appear after response/status=FINISHED.
|
||||
// that can appear after response/status=FINISHED, but stop as soon
|
||||
// as [DONE] arrives.
|
||||
stopped = true
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ─── CollectStream edge cases ────────────────────────────────────────
|
||||
@@ -227,6 +228,39 @@ func TestCollectStreamStatusFinished(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCollectStreamStopsOnDoneAfterFinished(t *testing.T) {
|
||||
pr, pw := io.Pipe()
|
||||
defer func() { _ = pw.Close() }()
|
||||
|
||||
resp := &http.Response{
|
||||
StatusCode: http.StatusOK,
|
||||
Header: make(http.Header),
|
||||
Body: pr,
|
||||
}
|
||||
|
||||
resultCh := make(chan CollectResult, 1)
|
||||
go func() {
|
||||
resultCh <- CollectStream(resp, false, false)
|
||||
}()
|
||||
|
||||
_, _ = io.WriteString(pw, "data: {\"p\":\"response/content\",\"v\":\"Hello\"}\n")
|
||||
_, _ = io.WriteString(pw, "data: {\"p\":\"response/status\",\"v\":\"FINISHED\"}\n")
|
||||
_, _ = io.WriteString(pw, "data: {\"p\":\"response/fragments/-1/results\",\"v\":[{\"url\":\"https://example.com/a\",\"cite_index\":1}]}\n")
|
||||
_, _ = io.WriteString(pw, "data: [DONE]\n")
|
||||
|
||||
select {
|
||||
case result := <-resultCh:
|
||||
if result.Text != "Hello" {
|
||||
t.Fatalf("expected text to freeze at FINISHED, got %q", result.Text)
|
||||
}
|
||||
if got := result.CitationLinks[1]; got != "https://example.com/a" {
|
||||
t.Fatalf("expected citation metadata after FINISHED, got %q", got)
|
||||
}
|
||||
case <-time.After(500 * time.Millisecond):
|
||||
t.Fatal("CollectStream did not stop on [DONE] after FINISHED")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCollectStreamStopsOnContentFilterStatus(t *testing.T) {
|
||||
resp := makeHTTPResponse(
|
||||
"data: {\"p\":\"response/content\",\"v\":\"safe\"}\n" +
|
||||
|
||||
Reference in New Issue
Block a user