fix(cron): publish deliver-false agent replies
This commit is contained in:
parent
5bc4fe4dea
commit
bf2ed429b2
2 changed files with 102 additions and 2 deletions
|
|
@ -374,7 +374,18 @@ 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
|
// ProcessDirectWithChannel bypasses the normal inbound loop, so publish the
|
||||||
_ = response // Will be sent by AgentLoop
|
// returned final text here when the agent produced one.
|
||||||
|
if strings.TrimSpace(response) == "" {
|
||||||
|
return "ok"
|
||||||
|
}
|
||||||
|
|
||||||
|
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"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,39 @@ import (
|
||||||
"github.com/sipeed/picoclaw/pkg/cron"
|
"github.com/sipeed/picoclaw/pkg/cron"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type stubJobExecutor struct {
|
||||||
|
response string
|
||||||
|
err error
|
||||||
|
calls []struct {
|
||||||
|
content string
|
||||||
|
sessionKey string
|
||||||
|
channel string
|
||||||
|
chatID string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stubJobExecutor) ProcessDirectWithChannel(
|
||||||
|
_ context.Context,
|
||||||
|
content,
|
||||||
|
sessionKey,
|
||||||
|
channel,
|
||||||
|
chatID string,
|
||||||
|
) (string, error) {
|
||||||
|
s.calls = append(s.calls, struct {
|
||||||
|
content string
|
||||||
|
sessionKey string
|
||||||
|
channel string
|
||||||
|
chatID string
|
||||||
|
}{
|
||||||
|
content: content,
|
||||||
|
sessionKey: sessionKey,
|
||||||
|
channel: channel,
|
||||||
|
chatID: chatID,
|
||||||
|
})
|
||||||
|
|
||||||
|
return s.response, s.err
|
||||||
|
}
|
||||||
|
|
||||||
func newTestCronToolWithConfig(t *testing.T, cfg *config.Config) *CronTool {
|
func newTestCronToolWithConfig(t *testing.T, cfg *config.Config) *CronTool {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
storePath := filepath.Join(t.TempDir(), "cron.json")
|
storePath := filepath.Join(t.TempDir(), "cron.json")
|
||||||
|
|
@ -234,3 +267,59 @@ func TestCronTool_ExecuteJobPublishesErrorWhenExecDisabled(t *testing.T) {
|
||||||
t.Fatalf("expected exec disabled message, got: %s", msg.Content)
|
t.Fatalf("expected exec disabled message, got: %s", msg.Content)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCronTool_ExecuteJobPublishesAgentReplyWhenDeliverFalse(t *testing.T) {
|
||||||
|
tool := newTestCronTool(t)
|
||||||
|
executor := &stubJobExecutor{response: "remember to stretch"}
|
||||||
|
tool.executor = executor
|
||||||
|
|
||||||
|
job := &cron.CronJob{ID: "job-123"}
|
||||||
|
job.Payload.Channel = "discord"
|
||||||
|
job.Payload.To = "chat-42"
|
||||||
|
job.Payload.Message = "stretch reminder"
|
||||||
|
|
||||||
|
if got := tool.ExecuteJob(context.Background(), job); got != "ok" {
|
||||||
|
t.Fatalf("ExecuteJob() = %q, want ok", got)
|
||||||
|
}
|
||||||
|
if len(executor.calls) != 1 {
|
||||||
|
t.Fatalf("executor calls = %d, want 1", len(executor.calls))
|
||||||
|
}
|
||||||
|
if executor.calls[0].sessionKey != "cron-job-123" {
|
||||||
|
t.Fatalf("sessionKey = %q, want %q", executor.calls[0].sessionKey, "cron-job-123")
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
msg, ok := tool.msgBus.SubscribeOutbound(ctx)
|
||||||
|
if !ok {
|
||||||
|
t.Fatal("expected outbound message")
|
||||||
|
}
|
||||||
|
if msg.Channel != "discord" || msg.ChatID != "chat-42" {
|
||||||
|
t.Fatalf("message route = %s/%s, want discord/chat-42", msg.Channel, msg.ChatID)
|
||||||
|
}
|
||||||
|
if msg.Content != "remember to stretch" {
|
||||||
|
t.Fatalf("message content = %q, want %q", msg.Content, "remember to stretch")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCronTool_ExecuteJobSkipsBlankAgentReplyWhenDeliverFalse(t *testing.T) {
|
||||||
|
tool := newTestCronTool(t)
|
||||||
|
tool.executor = &stubJobExecutor{response: " \n\t"}
|
||||||
|
|
||||||
|
job := &cron.CronJob{ID: "job-blank"}
|
||||||
|
job.Payload.Channel = "discord"
|
||||||
|
job.Payload.To = "chat-blank"
|
||||||
|
job.Payload.Message = "stretch reminder"
|
||||||
|
|
||||||
|
if got := tool.ExecuteJob(context.Background(), job); got != "ok" {
|
||||||
|
t.Fatalf("ExecuteJob() = %q, want ok", got)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
if _, ok := tool.msgBus.SubscribeOutbound(ctx); ok {
|
||||||
|
t.Fatal("expected no outbound message for blank agent reply")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue