refactor(heartbeat): add configurable interval and channel-aware routing

feat(config): add heartbeat interval configuration with default 30 minutes

feat(state): migrate state file from workspace root to state directory

feat(channels): skip internal channels in outbound dispatcher

feat(agent): record last active channel for heartbeat context

refactor(subagent): use configurable default model instead of provider default
This commit is contained in:
yinwm
2026-02-13 11:13:32 +08:00
parent 8fbbb67f70
commit 4dfa133cb8
9 changed files with 120 additions and 47 deletions

View File

@@ -28,7 +28,7 @@ func TestExecuteHeartbeat_Async(t *testing.T) {
Async: true,
}
hs.SetHandler(func(prompt string) *tools.ToolResult {
hs.SetHandler(func(prompt, channel, chatID string) *tools.ToolResult {
asyncCalled = true
if prompt == "" {
t.Error("Expected non-empty prompt")
@@ -57,7 +57,7 @@ func TestExecuteHeartbeat_Error(t *testing.T) {
hs := NewHeartbeatService(tmpDir, 30, true)
hs.started = true // Enable for testing
hs.SetHandler(func(prompt string) *tools.ToolResult {
hs.SetHandler(func(prompt, channel, chatID string) *tools.ToolResult {
return &tools.ToolResult{
ForLLM: "Heartbeat failed: connection error",
ForUser: "",
@@ -95,7 +95,7 @@ func TestExecuteHeartbeat_Silent(t *testing.T) {
hs := NewHeartbeatService(tmpDir, 30, true)
hs.started = true // Enable for testing
hs.SetHandler(func(prompt string) *tools.ToolResult {
hs.SetHandler(func(prompt, channel, chatID string) *tools.ToolResult {
return &tools.ToolResult{
ForLLM: "Heartbeat completed successfully",
ForUser: "",
@@ -169,7 +169,7 @@ func TestExecuteHeartbeat_NilResult(t *testing.T) {
hs := NewHeartbeatService(tmpDir, 30, true)
hs.started = true // Enable for testing
hs.SetHandler(func(prompt string) *tools.ToolResult {
hs.SetHandler(func(prompt, channel, chatID string) *tools.ToolResult {
return nil
})