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."))
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())
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"))
text string
}{
{
- name: "empty final reply",
+ name: "sends nothing for an empty final reply",
text: "",
},
{
- name: "whitespace final reply",
+ name: "sends nothing for a whitespace final reply",
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."))
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."))
modelWriteEvents(w, modelCompletedEvent([]any{modelMessageItem(text)}, 100, 0, 5))
}
+
test := newDaemonMessageTest(t, t.TempDir(), server)
test.Start(t, 0, 1)
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."))
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())
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."))
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."))
require.Never(t, func() bool {
return len(sent) > 0
}, 50*time.Millisecond, time.Millisecond)
+
once.Do(func() {
close(release)
})
target: "OneChat",
},
{
- name: "unknown sender",
+ name: "refuses an unknown sender",
source: "Other",
target: "Garden",
},
{
- name: "unknown recipient",
+ name: "refuses an unknown recipient",
source: "OneChat",
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")
file string
}{
{
- name: "broken JSON",
+ name: "stops startup for broken JSON",
file: "{",
},
{
- name: "unknown sender",
+ name: "stops startup for unknown sender",
file: `{"next":1,"pending":[{"id":1,"source":"Other","target":"Garden","kind":"user"}]}`,
},
{
- name: "sibling delivery",
+ name: "stops startup for sibling delivery",
file: `{"next":1,"pending":[{"id":1,"source":"Library","target":"Garden","kind":"user"}]}`,
},
{
- name: "invalid sequence",
+ name: "stops startup for invalid sequence",
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()
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)
chat WhatsAppChat
}{
{
- name: "private chat",
+ name: "routes a private chat only to its child",
chat: WhatsAppChat{
ID: whatsappTestAna.String(),
Name: "Ana",
},
},
{
- name: "group without a mention",
+ name: "routes an unmentioned group only to its child",
chat: WhatsAppChat{
ID: whatsappTestFamily.String(),
Name: "Garden plans",
},
},
}
+
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)
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.")
finish: true,
},
}
+
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
dir := t.TempDir()
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.")
id *int
}{
{
- name: "before log ID is stored",
+ name: "recovers one message before its log ID is stored",
id: nil,
},
{
- name: "after log ID is stored",
+ name: "recovers one message after its log ID is stored",
id: new(0),
},
}
+
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
dir := t.TempDir()
WhatsAppBatch: 1,
}},
}
+
data, err := json.Marshal(file)
require.NoError(t, err)
require.NoError(t, os.WriteFile(path, data, 0o600))
ID: whatsappTestAna.String(),
Name: "Ana",
}
+
second := WhatsAppChat{
ID: whatsappTestFamily.String(),
Name: "Garden plans",
Name: "Garden plans",
Group: true,
}
+
library := WhatsAppChat{
ID: whatsappTestBruno.String(),
Name: "Bruno",
}
+
root := WhatsAppChat{
ID: whatsappTestAna.String(),
Name: "Ana",