mirror of
https://github.com/YspCoder/clawgo.git
synced 2026-04-13 20:47:49 +08:00
193 lines
4.3 KiB
Go
193 lines
4.3 KiB
Go
package agent
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"clawgo/pkg/bus"
|
|
)
|
|
|
|
func TestDetectRunControlIntent(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
intent, ok := detectRunControlIntent("请等待 run-123-7 120 秒后告诉我状态")
|
|
if !ok {
|
|
t.Fatalf("expected run control intent")
|
|
}
|
|
if intent.runID != "run-123-7" {
|
|
t.Fatalf("unexpected run id: %s", intent.runID)
|
|
}
|
|
if !intent.wait {
|
|
t.Fatalf("expected wait=true")
|
|
}
|
|
if intent.timeout != 120*time.Second {
|
|
t.Fatalf("unexpected timeout: %s", intent.timeout)
|
|
}
|
|
}
|
|
|
|
func TestDetectRunControlIntentLatest(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
intent, ok := detectRunControlIntent("latest run status")
|
|
if !ok {
|
|
t.Fatalf("expected latest run status intent")
|
|
}
|
|
if !intent.latest {
|
|
t.Fatalf("expected latest=true")
|
|
}
|
|
if intent.runID != "" {
|
|
t.Fatalf("expected empty run id")
|
|
}
|
|
}
|
|
|
|
func TestParseRunWaitTimeout_MinClamp(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
got := parseRunWaitTimeout("wait run-1-1 1 s")
|
|
if got != minRunWaitTimeout {
|
|
t.Fatalf("expected min timeout %s, got %s", minRunWaitTimeout, got)
|
|
}
|
|
}
|
|
|
|
func TestParseRunWaitTimeout_MinuteUnit(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
got := parseRunWaitTimeout("等待 run-1-1 2 分钟")
|
|
if got != 2*time.Minute {
|
|
t.Fatalf("expected 2m, got %s", got)
|
|
}
|
|
}
|
|
|
|
func TestDetectRunControlIntentIgnoresNonControlText(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
if _, ok := detectRunControlIntent("帮我写一个README"); ok {
|
|
t.Fatalf("did not expect run control intent")
|
|
}
|
|
}
|
|
|
|
func TestDetectRunControlIntentWithCustomLexicon(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
lex := runControlLexicon{
|
|
latestKeywords: []string{"newest"},
|
|
waitKeywords: []string{"block"},
|
|
statusKeywords: []string{"health"},
|
|
runMentionKeywords: []string{"job"},
|
|
minuteUnits: map[string]struct{}{"mins": {}},
|
|
}
|
|
|
|
intent, ok := detectRunControlIntentWithLexicon("block run-55-1 for 2 mins and show health", lex)
|
|
if !ok {
|
|
t.Fatalf("expected intent with custom lexicon")
|
|
}
|
|
if !intent.wait {
|
|
t.Fatalf("expected wait=true")
|
|
}
|
|
if intent.timeout != 2*time.Minute {
|
|
t.Fatalf("unexpected timeout: %s", intent.timeout)
|
|
}
|
|
}
|
|
|
|
func TestLatestRunStateBySession(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
now := time.Now()
|
|
al := &AgentLoop{
|
|
runStates: map[string]*runState{
|
|
"run-1-1": {
|
|
runID: "run-1-1",
|
|
sessionKey: "s1",
|
|
startedAt: now.Add(-2 * time.Minute),
|
|
},
|
|
"run-1-2": {
|
|
runID: "run-1-2",
|
|
sessionKey: "s1",
|
|
startedAt: now.Add(-time.Minute),
|
|
},
|
|
"run-2-1": {
|
|
runID: "run-2-1",
|
|
sessionKey: "s2",
|
|
startedAt: now,
|
|
},
|
|
},
|
|
}
|
|
|
|
rs, ok := al.latestRunState("s1")
|
|
if !ok {
|
|
t.Fatalf("expected state for s1")
|
|
}
|
|
if rs.runID != "run-1-2" {
|
|
t.Fatalf("unexpected run id: %s", rs.runID)
|
|
}
|
|
}
|
|
|
|
func TestHandleSlashCommand_StatusRunLatest(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
al := &AgentLoop{
|
|
runStates: map[string]*runState{
|
|
"run-100-1": {
|
|
runID: "run-100-1",
|
|
sessionKey: "s1",
|
|
status: runStatusOK,
|
|
acceptedAt: time.Now().Add(-time.Minute),
|
|
startedAt: time.Now().Add(-time.Minute),
|
|
endedAt: time.Now().Add(-30 * time.Second),
|
|
done: closedChan(),
|
|
},
|
|
},
|
|
}
|
|
handled, out, err := al.handleSlashCommand(context.Background(), bus.InboundMessage{
|
|
Content: "/status run latest",
|
|
SessionKey: "s1",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
if !handled {
|
|
t.Fatalf("expected command handled")
|
|
}
|
|
if out == "" || !containsAnySubstring(out, "run-100-1", "Run ID: run-100-1") {
|
|
t.Fatalf("unexpected output: %s", out)
|
|
}
|
|
}
|
|
|
|
func TestHandleSlashCommand_StatusWaitDoneRun(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
al := &AgentLoop{
|
|
runStates: map[string]*runState{
|
|
"run-200-2": {
|
|
runID: "run-200-2",
|
|
sessionKey: "s1",
|
|
status: runStatusOK,
|
|
acceptedAt: time.Now().Add(-time.Minute),
|
|
startedAt: time.Now().Add(-time.Minute),
|
|
endedAt: time.Now().Add(-20 * time.Second),
|
|
done: closedChan(),
|
|
},
|
|
},
|
|
}
|
|
handled, out, err := al.handleSlashCommand(context.Background(), bus.InboundMessage{
|
|
Content: "/status wait run-200-2 3",
|
|
SessionKey: "s1",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
if !handled {
|
|
t.Fatalf("expected command handled")
|
|
}
|
|
if out == "" || !containsAnySubstring(out, "run-200-2", "Run ID: run-200-2") {
|
|
t.Fatalf("unexpected output: %s", out)
|
|
}
|
|
}
|
|
|
|
func closedChan() chan struct{} {
|
|
ch := make(chan struct{})
|
|
close(ch)
|
|
return ch
|
|
}
|