Fork tasks from snapshots; snapshot only when text follows tool calls
This commit is contained in:
@@ -262,6 +262,67 @@ func TestResume(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestForkAt(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := testContext(t)
|
||||
|
||||
first, err := claude.Start(ctx, options(t, "first", claude.Options{Cwd: scratchRepo(t)}))
|
||||
if err != nil {
|
||||
t.Fatalf("start: %v", err)
|
||||
}
|
||||
send(t, first, "Run the bash command `echo APPLE-1`. After it finishes, run the bash command `echo BANANA-2`. Then reply with the single word ok.")
|
||||
cut := ""
|
||||
waitResult(t, ctx, first, func(ev claude.Event) {
|
||||
if cut != "" || ev.Type != "user" {
|
||||
return
|
||||
}
|
||||
blocks, err := ev.Blocks()
|
||||
if err != nil {
|
||||
t.Fatalf("parse user: %v", err)
|
||||
}
|
||||
for _, b := range blocks {
|
||||
if b.Type == "tool_result" && strings.Contains(string(b.Content), "APPLE-1") {
|
||||
cut, err = ev.UUID()
|
||||
if err != nil {
|
||||
t.Fatalf("parse uuid: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
id := first.ID()
|
||||
closeSession(t, first)
|
||||
|
||||
if cut == "" {
|
||||
t.Fatalf("never saw the APPLE-1 tool result")
|
||||
}
|
||||
|
||||
forkID := "8a1b2c3d-0000-4000-8000-" + strings.ReplaceAll(time.Now().Format("150405.000000"), ".", "")
|
||||
fork, err := claude.Start(ctx, options(t, "fork", claude.Options{
|
||||
Cwd: scratchRepo(t),
|
||||
SessionID: forkID,
|
||||
Resume: id,
|
||||
ResumeAt: cut,
|
||||
ForkSession: true,
|
||||
}))
|
||||
if err != nil {
|
||||
t.Fatalf("fork: %v", err)
|
||||
}
|
||||
t.Cleanup(func() { closeSession(t, fork) })
|
||||
|
||||
send(t, fork, "Without running anything, list the exact output of every bash command you have run in this conversation, one per line, and nothing else.")
|
||||
text := waitResult(t, ctx, fork, nil)
|
||||
|
||||
if !strings.Contains(text, "APPLE-1") {
|
||||
t.Fatalf("fork lost the conversation before the cut; assistant said %q", text)
|
||||
}
|
||||
if strings.Contains(text, "BANANA-2") {
|
||||
t.Fatalf("fork kept the conversation after the cut; assistant said %q", text)
|
||||
}
|
||||
if fork.ID() != forkID {
|
||||
t.Fatalf("fork has session id %s, want %s", fork.ID(), forkID)
|
||||
}
|
||||
}
|
||||
|
||||
func testContext(t *testing.T) context.Context {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
Reference in New Issue
Block a user