X-Git-Url: https://git.giacomolli.uk/onechat/blobdiff_plain/80e348724041a694002fc38f57e8868b9b9a2be9..c781f79f3c8cb9a7577ee1574d196988da2719b3:/daemon_message_test.go?ds=sidebyside diff --git a/daemon_message_test.go b/daemon_message_test.go index 432a640..27138d3 100644 --- a/daemon_message_test.go +++ b/daemon_message_test.go @@ -24,6 +24,7 @@ func TestParentMessageWakesChildAndFinalReplyWakesParent(t *testing.T) { modelWriteEvents(w, modelCompletedEvent([]any{modelMessageItem(text)}, 100, 0, 5)) } + test := newDaemonMessageTest(t, t.TempDir(), server) test.Start(t, 0, 1, 2) require.NoError(t, test.messages.Tell("OneChat", "Garden", "Check the gate size.")) @@ -68,6 +69,7 @@ func TestChildReportSendsATelegramCompletionBeforeTheParentReply(t *testing.T) { modelWriteEvents(w, modelCompletedEvent([]any{modelMessageItem(text)}, 100, 0, 5)) } + test := newDaemonMessageTest(t, t.TempDir(), server) telegram := newTelegramFake(t) bot := newTelegramBot(newTelegramAPI(telegram.URL, telegramTestToken), telegramTestOwner, filepath.Join(t.TempDir(), telegramOffsetFileName), discardLog()) @@ -97,6 +99,7 @@ func TestChildReportSendsATelegramCompletionBeforeTheParentReply(t *testing.T) { require.Eventually(t, func() bool { return len(telegram.Sent()) >= 2 }, 10*time.Second, time.Millisecond) + require.Equal(t, []string{"[Garden] finished", "I will ask the user."}, telegram.Sent()) require.Equal(t, subagentFinished, test.events[0].LastEvent("work").Status) require.Equal(t, "[Garden] Approve the gate size.", test.events[0].Last("work")) @@ -130,12 +133,14 @@ func TestEmptyChildReplySendsNothingAndWakesNobody(t *testing.T) { text: " \n\t ", }, } + for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { server := newModelFake(t) server.reply = func(w http.ResponseWriter, _ ModelFakeCall) { modelWriteEvents(w, modelCompletedEvent([]any{modelMessageItem(tc.text)}, 100, 0, 5)) } + test := newDaemonMessageTest(t, t.TempDir(), server) test.Start(t, 0, 1, 2) require.NoError(t, test.messages.Tell("OneChat", "Garden", "Keep the plan.")) @@ -162,6 +167,7 @@ func TestBusyChildQueuesTheNextParentMessage(t *testing.T) { modelWriteEvents(w, modelCompletedEvent([]any{modelMessageItem("")}, 100, 0, 5)) } + test := newDaemonMessageTest(t, t.TempDir(), server) test.Start(t, 0, 1) require.NoError(t, test.messages.Tell("OneChat", "Garden", "Check the first plan.")) @@ -194,6 +200,7 @@ func TestBusyParentQueuesItsChildReport(t *testing.T) { modelWriteEvents(w, modelCompletedEvent([]any{modelMessageItem(text)}, 100, 0, 5)) } + test := newDaemonMessageTest(t, t.TempDir(), server) test.Start(t, 0, 1) @@ -232,6 +239,7 @@ func TestChildReportsOnlyTheFinalReplyAndTakesQueuedToolInput(t *testing.T) { modelWriteEvents(w, modelCompletedEvent([]any{modelMessageItem("The plan needs approval.")}, 100, 0, 5)) } + test := newDaemonMessageTest(t, t.TempDir(), server) test.Start(t, 1) require.NoError(t, test.messages.Tell("OneChat", "Garden", "Check the plan.")) @@ -259,6 +267,7 @@ func TestQueuedParentMessageSurvivesDaemonRestart(t *testing.T) { server.reply = func(w http.ResponseWriter, _ ModelFakeCall) { modelWriteEvents(w, modelCompletedEvent([]any{modelMessageItem("")}, 100, 0, 5)) } + first := newDaemonMessageTest(t, dir, server) require.NoError(t, first.messages.Tell("OneChat", "Garden", "Remember the garden plan.")) require.Equal(t, 1, first.agents[1].memory.Len()) @@ -319,6 +328,7 @@ func TestInterruptedChildDeliveryResumesAfterDaemonRestart(t *testing.T) { modelWriteEvents(w, modelCompletedEvent([]any{modelMessageItem("")}, 100, 0, 5)) } + first := newDaemonMessageTest(t, dir, server) first.Start(t, 1) require.NoError(t, first.messages.Tell("OneChat", "Garden", "Finish the garden plan.")) @@ -348,6 +358,7 @@ func TestInterruptedParentReportResumesAfterDaemonRestart(t *testing.T) { modelWriteEvents(w, modelCompletedEvent([]any{modelMessageItem("The plan is ready.")}, 100, 0, 5)) } + first := newDaemonMessageTest(t, dir, server) first.Start(t, 0, 1) require.NoError(t, first.messages.Tell("OneChat", "Garden", "Review the plan.")) @@ -419,6 +430,7 @@ func TestAgentMessageSnapshotBlocksDelivery(t *testing.T) { require.Never(t, func() bool { return len(sent) > 0 }, 50*time.Millisecond, time.Millisecond) + once.Do(func() { close(release) }) @@ -463,6 +475,7 @@ func TestParentCanMessageOnlyItsOwnChildren(t *testing.T) { target: "Other", }, } + for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { require.ErrorContains(t, test.messages.Tell(tc.source, tc.target, "Do not deliver."), "not a child") @@ -497,6 +510,7 @@ func TestInvalidAgentMessageQueueStopsStartup(t *testing.T) { file: `{"next":0,"pending":[{"id":1,"source":"OneChat","target":"Garden","kind":"user"}]}`, }, } + for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { dir := t.TempDir() @@ -537,6 +551,7 @@ func TestChildScheduleWakesOnlyItsOwner(t *testing.T) { server.reply = func(w http.ResponseWriter, _ ModelFakeCall) { modelWriteEvents(w, modelCompletedEvent([]any{modelMessageItem("")}, 100, 0, 5)) } + test := newDaemonMessageTest(t, t.TempDir(), server) child := test.agents[1] at := child.clock().Add(time.Minute).Format(scheduleAtLayout) @@ -580,12 +595,14 @@ func TestRoutedWhatsAppBatchesWakeOnlyTheirChild(t *testing.T) { }, }, } + for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { server := newModelFake(t) server.reply = func(w http.ResponseWriter, _ ModelFakeCall) { modelWriteEvents(w, modelCompletedEvent([]any{modelMessageItem("")}, 100, 0, 5)) } + dir := t.TempDir() test := newDaemonMessageTest(t, dir, server) inbox := whatsappRouteTestInbox(t, dir) @@ -621,6 +638,7 @@ func TestWhatsAppUnrouteRestoresRootDelivery(t *testing.T) { ID: whatsappTestAna.String(), Name: "Ana", } + source := "whatsapp:" + chat.ID require.NoError(t, test.messages.routes.Set(source, "Garden")) whatsappRouteTestAdd(t, inbox, chat, "Keep the gate plan.") @@ -672,6 +690,7 @@ func TestRoutedWhatsAppRestartDoesNotDeliverTheBatchTwice(t *testing.T) { finish: true, }, } + for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { dir := t.TempDir() @@ -679,12 +698,14 @@ func TestRoutedWhatsAppRestartDoesNotDeliverTheBatchTwice(t *testing.T) { server.reply = func(w http.ResponseWriter, _ ModelFakeCall) { modelWriteEvents(w, modelCompletedEvent([]any{modelMessageItem("")}, 100, 0, 5)) } + first := newDaemonMessageTest(t, dir, server) inbox := whatsappRouteTestInbox(t, dir) chat := WhatsAppChat{ ID: whatsappTestAna.String(), Name: "Ana", } + source := "whatsapp:" + chat.ID require.NoError(t, first.messages.routes.Set(source, "Garden")) whatsappRouteTestAdd(t, inbox, chat, "Remember the gate plan.") @@ -747,6 +768,7 @@ func TestQueuedWhatsAppBatchRecoversBeforeItsLogAppend(t *testing.T) { id: new(0), }, } + for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { dir := t.TempDir() @@ -768,6 +790,7 @@ func TestQueuedWhatsAppBatchRecoversBeforeItsLogAppend(t *testing.T) { WhatsAppBatch: 1, }}, } + data, err := json.Marshal(file) require.NoError(t, err) require.NoError(t, os.WriteFile(path, data, 0o600)) @@ -824,6 +847,7 @@ func TestRoutedWhatsAppBatchesCanCloseOutOfNumberOrder(t *testing.T) { ID: whatsappTestAna.String(), Name: "Ana", } + second := WhatsAppChat{ ID: whatsappTestFamily.String(), Name: "Garden plans", @@ -867,10 +891,12 @@ func TestWhatsAppCatchupSeparatesChildAndRootBatches(t *testing.T) { Name: "Garden plans", Group: true, } + library := WhatsAppChat{ ID: whatsappTestBruno.String(), Name: "Bruno", } + root := WhatsAppChat{ ID: whatsappTestAna.String(), Name: "Ana",