fix(cron): publish deliver false agent replies
This commit is contained in:
parent
4a8a2e9c23
commit
2b8d241ae1
2 changed files with 103 additions and 2 deletions
|
|
@ -341,7 +341,14 @@ func (t *CronTool) ExecuteJob(ctx context.Context, job *cron.CronJob) string {
|
||||||
return fmt.Sprintf("Error: %v", err)
|
return fmt.Sprintf("Error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Response is automatically sent via MessageBus by AgentLoop
|
if strings.TrimSpace(response) != "" {
|
||||||
_ = response // Will be sent by AgentLoop
|
pubCtx, pubCancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||||
|
defer pubCancel()
|
||||||
|
t.msgBus.PublishOutbound(pubCtx, bus.OutboundMessage{
|
||||||
|
Channel: channel,
|
||||||
|
ChatID: chatID,
|
||||||
|
Content: response,
|
||||||
|
})
|
||||||
|
}
|
||||||
return "ok"
|
return "ok"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,27 @@ import (
|
||||||
"github.com/sipeed/picoclaw/pkg/cron"
|
"github.com/sipeed/picoclaw/pkg/cron"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type mockCronExecutor struct {
|
||||||
|
response string
|
||||||
|
err error
|
||||||
|
calls int
|
||||||
|
lastMsg string
|
||||||
|
lastSess string
|
||||||
|
lastChan string
|
||||||
|
lastChat string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockCronExecutor) ProcessDirectWithChannel(
|
||||||
|
ctx context.Context, content, sessionKey, channel, chatID string,
|
||||||
|
) (string, error) {
|
||||||
|
m.calls++
|
||||||
|
m.lastMsg = content
|
||||||
|
m.lastSess = sessionKey
|
||||||
|
m.lastChan = channel
|
||||||
|
m.lastChat = chatID
|
||||||
|
return m.response, m.err
|
||||||
|
}
|
||||||
|
|
||||||
func newTestCronTool(t *testing.T) *CronTool {
|
func newTestCronTool(t *testing.T) *CronTool {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
storePath := filepath.Join(t.TempDir(), "cron.json")
|
storePath := filepath.Join(t.TempDir(), "cron.json")
|
||||||
|
|
@ -114,3 +135,76 @@ func TestCronTool_NonCommandJobAllowedFromRemoteChannel(t *testing.T) {
|
||||||
t.Fatalf("expected non-command reminder to succeed from remote channel, got: %s", result.ForLLM)
|
t.Fatalf("expected non-command reminder to succeed from remote channel, got: %s", result.ForLLM)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCronTool_ExecuteJob_DeliverFalsePublishesAgentResponse(t *testing.T) {
|
||||||
|
storePath := filepath.Join(t.TempDir(), "cron.json")
|
||||||
|
cronService := cron.NewCronService(storePath, nil)
|
||||||
|
msgBus := bus.NewMessageBus()
|
||||||
|
executor := &mockCronExecutor{response: "agent reply"}
|
||||||
|
cfg := config.DefaultConfig()
|
||||||
|
tool, err := NewCronTool(cronService, executor, msgBus, t.TempDir(), true, 0, cfg)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("NewCronTool() error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
job := &cron.CronJob{
|
||||||
|
ID: "job-1",
|
||||||
|
Payload: cron.CronPayload{
|
||||||
|
Message: "summarize status",
|
||||||
|
Deliver: false,
|
||||||
|
Channel: "telegram",
|
||||||
|
To: "chat-42",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if got := tool.ExecuteJob(context.Background(), job); got != "ok" {
|
||||||
|
t.Fatalf("ExecuteJob() = %q, want ok", got)
|
||||||
|
}
|
||||||
|
if executor.calls != 1 {
|
||||||
|
t.Fatalf("executor calls = %d, want 1", executor.calls)
|
||||||
|
}
|
||||||
|
if executor.lastSess != "cron-job-1" {
|
||||||
|
t.Fatalf("sessionKey = %q, want %q", executor.lastSess, "cron-job-1")
|
||||||
|
}
|
||||||
|
|
||||||
|
msg, ok := msgBus.SubscribeOutbound(context.Background())
|
||||||
|
if !ok {
|
||||||
|
t.Fatal("expected outbound message")
|
||||||
|
}
|
||||||
|
if msg.Content != "agent reply" {
|
||||||
|
t.Fatalf("outbound content = %q, want %q", msg.Content, "agent reply")
|
||||||
|
}
|
||||||
|
if msg.Channel != "telegram" || msg.ChatID != "chat-42" {
|
||||||
|
t.Fatalf("unexpected destination: %+v", msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCronTool_ExecuteJob_DeliverFalseSkipsEmptyAgentResponse(t *testing.T) {
|
||||||
|
storePath := filepath.Join(t.TempDir(), "cron.json")
|
||||||
|
cronService := cron.NewCronService(storePath, nil)
|
||||||
|
msgBus := bus.NewMessageBus()
|
||||||
|
executor := &mockCronExecutor{response: " "}
|
||||||
|
cfg := config.DefaultConfig()
|
||||||
|
tool, err := NewCronTool(cronService, executor, msgBus, t.TempDir(), true, 0, cfg)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("NewCronTool() error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
job := &cron.CronJob{
|
||||||
|
ID: "job-2",
|
||||||
|
Payload: cron.CronPayload{
|
||||||
|
Message: "noop",
|
||||||
|
Deliver: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if got := tool.ExecuteJob(context.Background(), job); got != "ok" {
|
||||||
|
t.Fatalf("ExecuteJob() = %q, want ok", got)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
cancel()
|
||||||
|
if _, ok := msgBus.SubscribeOutbound(ctx); ok {
|
||||||
|
t.Fatal("did not expect outbound message for empty response")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue