diff --git a/intercept/intercept.go b/intercept/intercept.go
index 21a376b..629811d 100644
--- a/intercept/intercept.go
+++ b/intercept/intercept.go
@@ -316,6 +316,7 @@ const (
// Judge default values.
const (
defaultJudgeTimeoutSecs = 15
+ defaultJudgeRetryCount = 3
defaultJudgeFailAction = "ask"
defaultJudgeAskTimeoutSecs = 300
defaultJudgeAskTimeoutAction = "deny"
@@ -346,7 +347,7 @@ func (i *Interceptor) judgeConfig() JudgeConfig {
Enabled: i.db.GetBool(settingJudgeEnabled, false),
ProfileID: int64(i.getSettingInt(settingJudgeProfileID, 0)),
TimeoutSeconds: i.getSettingInt(settingJudgeTimeoutSecs, defaultJudgeTimeoutSecs),
- RetryCount: min(max(i.getSettingInt(settingJudgeRetryCount, 0), 0), MaxJudgeRetryCount),
+ RetryCount: min(max(i.getSettingInt(settingJudgeRetryCount, defaultJudgeRetryCount), 0), MaxJudgeRetryCount),
RetryIntervalMS: min(max(i.getSettingInt(settingJudgeRetryIntervalMS, defaultJudgeRetryIntervalMS), 0), MaxJudgeRetryIntervalMS),
FailAction: i.getSettingChoice(settingJudgeFailAction, defaultJudgeFailAction, "allow", "ask", "deny"),
AskTimeoutSeconds: i.getSettingInt(settingJudgeAskTimeoutSecs, defaultJudgeAskTimeoutSecs),
diff --git a/intercept/judge_retry_test.go b/intercept/judge_retry_test.go
index b71c715..6e0cdc5 100644
--- a/intercept/judge_retry_test.go
+++ b/intercept/judge_retry_test.go
@@ -59,10 +59,11 @@ func TestJudgeRetryConfigDefaultsAndBounds(t *testing.T) {
settings map[string]string
count, interval int
}{
- {"legacy", nil, 0, 1000},
- {"configured", map[string]string{settingJudgeRetryCount: "3", settingJudgeRetryIntervalMS: "25"}, 3, 25},
+ {"default", nil, 3, 1000},
+ {"configured", map[string]string{settingJudgeRetryCount: "2", settingJudgeRetryIntervalMS: "25"}, 2, 25},
+ {"disabled", map[string]string{settingJudgeRetryCount: "0"}, 0, 1000},
{"immediate", map[string]string{settingJudgeRetryCount: "1", settingJudgeRetryIntervalMS: "0"}, 1, 0},
- {"malformed", map[string]string{settingJudgeRetryCount: "bad", settingJudgeRetryIntervalMS: "bad"}, 0, 1000},
+ {"malformed", map[string]string{settingJudgeRetryCount: "bad", settingJudgeRetryIntervalMS: "bad"}, 3, 1000},
{"negative", map[string]string{settingJudgeRetryCount: "-1", settingJudgeRetryIntervalMS: "-1"}, 0, 0},
{"excessive", map[string]string{settingJudgeRetryCount: "999", settingJudgeRetryIntervalMS: "999999999"}, 20, 3600000},
} {
@@ -149,16 +150,33 @@ func TestJudgeRetriesInvalidVerdict(t *testing.T) {
}
}
-func TestJudgeLegacyConfigDoesNotRetry(t *testing.T) {
- i := retryTestInterceptor(t, map[string]string{settingJudgeEnabled: "true", settingJudgeFailAction: "deny"})
- calls := 0
- i.SetReviewer(func(context.Context, int64, string, ReviewInput) (Decision, error) {
- calls++
- return Decision{}, errors.New("failed")
- })
- got, _ := i.Judge(t.Context(), "Bash", json.RawMessage(`{"command":"echo ok"}`))
- if calls != 1 || got.Action != "deny" || !got.ModelFallback {
- t.Fatalf("calls=%d out=%+v", calls, got)
+func TestJudgeDefaultRetriesAndExplicitDisable(t *testing.T) {
+ for _, tc := range []struct {
+ name string
+ settings map[string]string
+ wantCalls int
+ }{
+ {"default", nil, 4},
+ {"disabled", map[string]string{settingJudgeRetryCount: "0"}, 1},
+ } {
+ t.Run(tc.name, func(t *testing.T) {
+ settings := map[string]string{
+ settingJudgeEnabled: "true", settingJudgeFailAction: "deny", settingJudgeRetryIntervalMS: "0",
+ }
+ for key, value := range tc.settings {
+ settings[key] = value
+ }
+ i := retryTestInterceptor(t, settings)
+ calls := 0
+ i.SetReviewer(func(context.Context, int64, string, ReviewInput) (Decision, error) {
+ calls++
+ return Decision{}, errors.New("failed")
+ })
+ got, _ := i.Judge(t.Context(), "Bash", json.RawMessage(`{"command":"echo ok"}`))
+ if calls != tc.wantCalls || got.Action != "deny" || !got.ModelFallback {
+ t.Fatalf("calls=%d out=%+v", calls, got)
+ }
+ })
}
}
diff --git a/web/src/app/(main)/function/schedules/page.tsx b/web/src/app/(main)/function/schedules/page.tsx
index 1365695..245b3c3 100644
--- a/web/src/app/(main)/function/schedules/page.tsx
+++ b/web/src/app/(main)/function/schedules/page.tsx
@@ -715,7 +715,7 @@ export default function SchedulesPage() {
ID
计划名称
- 备注
+ 备注
时间线
运行周期
开始时间
diff --git a/web/src/app/(main)/function/tasks/page.tsx b/web/src/app/(main)/function/tasks/page.tsx
index 5b0562c..bc9ae91 100644
--- a/web/src/app/(main)/function/tasks/page.tsx
+++ b/web/src/app/(main)/function/tasks/page.tsx
@@ -955,7 +955,7 @@ export default function TasksPage() {
onSort={sortTasksBy}
/>
名称
- 备注
+ 备注
描述
目标
({
profile_id: 0,
prompt: "",
timeout_seconds: 15,
- retry_count: 0,
+ retry_count: 3,
retry_interval_ms: 1000,
fail_action: "ask",
ask_timeout_seconds: 300,
diff --git a/web/src/components/remark-editor.tsx b/web/src/components/remark-editor.tsx
index ceea7b1..e329cfd 100644
--- a/web/src/components/remark-editor.tsx
+++ b/web/src/components/remark-editor.tsx
@@ -148,7 +148,7 @@ function InlineTextEditor({