mirror of
https://github.com/sipeed/picoclaw.git
synced 2026-06-12 18:08:54 +00:00
Merge pull request #1617 from yzxlr/codex/fix-1561-heartbeat-template-idle
fix(heartbeat): ignore untouched default template
This commit is contained in:
@@ -26,6 +26,7 @@ import (
|
||||
const (
|
||||
minIntervalMinutes = 5
|
||||
defaultIntervalMinutes = 30
|
||||
userTasksMarker = "Add your heartbeat tasks below this line:"
|
||||
)
|
||||
|
||||
// HeartbeatHandler is the function type for handling heartbeat.
|
||||
@@ -232,7 +233,7 @@ func (hs *HeartbeatService) buildPrompt() string {
|
||||
}
|
||||
|
||||
content := string(data)
|
||||
if len(content) == 0 {
|
||||
if !heartbeatHasUserTasks(content) {
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -284,6 +285,32 @@ Add your heartbeat tasks below this line:
|
||||
}
|
||||
}
|
||||
|
||||
func heartbeatHasUserTasks(content string) bool {
|
||||
trimmed := strings.TrimSpace(content)
|
||||
if trimmed == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
markerIdx := strings.Index(content, userTasksMarker)
|
||||
if markerIdx < 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
tasksSection := content[markerIdx+len(userTasksMarker):]
|
||||
for _, line := range strings.Split(tasksSection, "\n") {
|
||||
trimmedLine := strings.TrimSpace(line)
|
||||
if trimmedLine == "" {
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(trimmedLine, "#") {
|
||||
continue
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// sendResponse sends the heartbeat response to the last channel
|
||||
func (hs *HeartbeatService) sendResponse(response string) {
|
||||
hs.mu.RLock()
|
||||
|
||||
@@ -3,6 +3,7 @@ package heartbeat
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -203,3 +204,47 @@ func TestHeartbeatFilePath(t *testing.T) {
|
||||
t.Errorf("Expected HEARTBEAT.md at %s, but it doesn't exist", expectedPath)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildPrompt_DefaultTemplateStaysIdle(t *testing.T) {
|
||||
tmpDir, err := os.MkdirTemp("", "heartbeat-test-*")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create temp dir: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
hs := NewHeartbeatService(tmpDir, 30, true)
|
||||
hs.createDefaultHeartbeatTemplate()
|
||||
|
||||
if prompt := hs.buildPrompt(); prompt != "" {
|
||||
t.Fatalf("buildPrompt() = %q, want empty prompt for untouched default template", prompt)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildPrompt_UserTasksAfterMarkerProducePrompt(t *testing.T) {
|
||||
tmpDir, err := os.MkdirTemp("", "heartbeat-test-*")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create temp dir: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
hs := NewHeartbeatService(tmpDir, 30, true)
|
||||
hs.createDefaultHeartbeatTemplate()
|
||||
|
||||
path := filepath.Join(tmpDir, "HEARTBEAT.md")
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read HEARTBEAT.md: %v", err)
|
||||
}
|
||||
updated := string(data) + "\n- Check unread Feishu messages\n"
|
||||
if err := os.WriteFile(path, []byte(updated), 0o644); err != nil {
|
||||
t.Fatalf("Failed to update HEARTBEAT.md: %v", err)
|
||||
}
|
||||
|
||||
prompt := hs.buildPrompt()
|
||||
if prompt == "" {
|
||||
t.Fatal("buildPrompt() = empty, want non-empty prompt when user tasks are present")
|
||||
}
|
||||
if !strings.Contains(prompt, "Check unread Feishu messages") {
|
||||
t.Fatalf("prompt = %q, want user task content", prompt)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user