Merge pull request #218 from CJackHwang/dev

fix: reverse snapshot order to preserve capture sequence during stabl…
This commit is contained in:
CJACK.
2026-04-06 02:55:59 +08:00
committed by GitHub
2 changed files with 39 additions and 4 deletions

View File

@@ -324,11 +324,13 @@ func buildCaptureChains(snapshot []devcapture.Entry) []captureChain {
return nil
}
ordered := make([]devcapture.Entry, len(snapshot))
copy(ordered, snapshot)
// devcapture snapshots are newest-first because the store prepends entries.
// Reverse once so equal-second timestamps can preserve the actual capture
// order (completion before continue) under the stable CreatedAt sort below.
for i := range snapshot {
ordered[len(snapshot)-1-i] = snapshot[i]
}
sort.SliceStable(ordered, func(i, j int) bool {
if ordered[i].CreatedAt == ordered[j].CreatedAt {
return ordered[i].ID < ordered[j].ID
}
return ordered[i].CreatedAt < ordered[j].CreatedAt
})

View File

@@ -285,6 +285,39 @@ func TestQueryRawSampleCapturesGroupsBySessionAndMatchesQuestion(t *testing.T) {
}
}
func TestBuildCaptureChainsPreservesCaptureOrderWhenTimestampsCollide(t *testing.T) {
snapshot := []devcapture.Entry{
{
ID: "cap_continue",
CreatedAt: 1712365200,
Label: "deepseek_continue",
RequestBody: `{"chat_session_id":"session-collision","message_id":2}`,
ResponseBody: "data: {\"v\":\"第二段\"}\n\n",
},
{
ID: "cap_completion",
CreatedAt: 1712365200,
Label: "deepseek_completion",
RequestBody: `{"chat_session_id":"session-collision","prompt":"题目"}`,
ResponseBody: "data: {\"v\":\"第一段\"}\n\n",
},
}
chains := buildCaptureChains(snapshot)
if len(chains) != 1 {
t.Fatalf("expected 1 chain, got %d", len(chains))
}
if len(chains[0].Entries) != 2 {
t.Fatalf("expected 2 entries, got %d", len(chains[0].Entries))
}
if chains[0].Entries[0].Label != "deepseek_completion" {
t.Fatalf("expected completion first, got %#v", chains[0].Entries)
}
if chains[0].Entries[1].Label != "deepseek_continue" {
t.Fatalf("expected continue second, got %#v", chains[0].Entries)
}
}
func TestSaveRawSampleFromCapturesPersistsSelectedChain(t *testing.T) {
root := t.TempDir()
t.Setenv("DS2API_RAW_STREAM_SAMPLE_ROOT", root)