X-Git-Url: https://git.giacomolli.uk/onechat/blobdiff_plain/6844f8c992ec4e276a3a0d93b544de0127eebbd2..36229ef68a30c5a117599037d79fa1fc708fbfef:/backup_test.go?ds=sidebyside diff --git a/backup_test.go b/backup_test.go index 440dfe2..8628ee4 100644 --- a/backup_test.go +++ b/backup_test.go @@ -110,6 +110,89 @@ func TestRunningDaemonBackupRestoresTheChatAndLinks(t *testing.T) { require.Equal(t, childText, restoredText) } +func TestBackupRestoresEachChildWithItsOwnState(t *testing.T) { + dir := t.TempDir() + daemonChildConfig(t, dir, "Garden") + daemonChildConfig(t, dir, "Library") + + server := newModelFake(t) + clock := newTestClock() + agents, err := openDaemonAgents(t.Context(), dir, server.URL, ModelAPIKey(modelTestKey), defaultConfig().Compactor, clock.Now, discardLog()) + require.NoError(t, err) + + defer func() { + require.NoError(t, agents.Close()) + }() + + whatsapp, _, _ := whatsappStartTest(t, dir, clock) + + var loops []*TurnLoop + + for _, agent := range agents { + loop, err := agent.Loop(whatsapp, func(Event) { + }) + require.NoError(t, err) + + loops = append(loops, loop) + _, err = loop.Submit("parent", "Keep the decision of "+agent.agent.config.Name) + require.NoError(t, err) + require.NoError(t, loop.turn(t.Context())) + require.NoError(t, agent.memory.Settle(t.Context())) + + subagent, err := agent.subagents.Create(t.Context()) + require.NoError(t, err) + + _, err = subagent.Append("user", "Keep the task of "+agent.agent.config.Name) + require.NoError(t, err) + } + + archive := filepath.Join(t.TempDir(), "children.tar.gz") + _, err = backupData(t.Context(), dir, archive, whatsapp, func(ctx context.Context, snapshot func() error) error { + return daemonSnapshot(ctx, loops, snapshot) + }) + require.NoError(t, err) + + restored := t.TempDir() + require.NoError(t, backupRestore(t.Context(), archive, restored)) + + restoredAgents, err := openDaemonAgents(t.Context(), restored, server.URL, ModelAPIKey(modelTestKey), defaultConfig().Compactor, clock.Now, discardLog()) + require.NoError(t, err) + + defer func() { + require.NoError(t, restoredAgents.Close()) + }() + + require.Len(t, restoredAgents, 3) + + for i, agent := range agents { + other := restoredAgents[i] + require.Equal(t, agent.agent.config, other.agent.config) + require.Equal(t, agent.memory.View(), other.memory.View()) + require.Equal(t, agent.memory.Len(), other.memory.Len()) + require.Equal(t, modelReadUsage(t, agent.client.UsagePath()), modelReadUsage(t, other.client.UsagePath())) + + for id := range agent.memory.Len() { + before, err := agent.memory.Message(id) + require.NoError(t, err) + + after, err := other.memory.Message(id) + require.NoError(t, err) + require.Equal(t, before, after) + } + + entries, err := os.ReadDir(filepath.Join(agent.agent.dir, subagentDirName)) + require.NoError(t, err) + require.Len(t, entries, 1) + + subagent, err := other.subagents.Get(t.Context(), entries[0].Name()) + require.NoError(t, err) + + text, err := subagent.Show() + require.NoError(t, err) + require.Contains(t, text, "Keep the task of "+agent.agent.config.Name) + } +} + func TestRestoreRefusesNonemptyDataWithoutChangingIt(t *testing.T) { dir := t.TempDir() path := filepath.Join(dir, "keep") @@ -295,7 +378,7 @@ func backupStartDaemon(t *testing.T, dir string) (*Memory, *WhatsApp, *Subagents whatsapp, _, _ := whatsappStartTest(t, dir, clock) subagents := newSubagents(filepath.Join(agent.dir, subagentDirName), clock.Now, subagentNameRandom) - schedules, err := openSchedules(filepath.Join(agent.dir, scheduleFileName), clock.Now, discardLog()) + schedules, err := openSchedules(filepath.Join(agent.dir, scheduleFileName), "OneChat", clock.Now, discardLog()) require.NoError(t, err) server := newModelFake(t)