Merge pull request #27 from RuoJi6/codex/review-default-retries

fix: 默认审查重试 3 次并收紧任务备注列
This commit is contained in:
RuoJi6 authored and GitHub committed 2026-10-20 13:23:00 +08:00
commit 0007bba3c1
7 files changed
+38 -19

No files matched your search

+2 -1
View File
@@ -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),
+31 -13
View File
@@ -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)
}
})
}
}
@@ -715,7 +715,7 @@ export default function SchedulesPage() {
</TableHead>
<TableHead className="font-mono">ID</TableHead>
<TableHead className="min-w-44">计划名称</TableHead>
<TableHead>备注</TableHead>
<TableHead className="w-px">备注</TableHead>
<TableHead className="w-28">时间线</TableHead>
<TableHead className="min-w-48">运行周期</TableHead>
<TableHead className="min-w-40">开始时间</TableHead>
+1 -1
View File
@@ -955,7 +955,7 @@ export default function TasksPage() {
onSort={sortTasksBy}
/>
<TableHead>名称</TableHead>
<TableHead>备注</TableHead>
<TableHead className="w-px">备注</TableHead>
<TableHead>描述</TableHead>
<TableHead>目标</TableHead>
<SortableTaskHead
+1 -1
View File
@@ -201,7 +201,7 @@ const defaultJudge = (): JudgeConfig => ({
profile_id: 0,
prompt: "",
timeout_seconds: 15,
retry_count: 0,
retry_count: 3,
retry_interval_ms: 1000,
fail_action: "ask",
ask_timeout_seconds: 300,
+1 -1
View File
@@ -148,7 +148,7 @@ function InlineTextEditor({
<div
className={cn(
"group/inline-editor flex min-w-0 items-center gap-1 font-medium",
multiline ? "w-32 sm:w-48" : "max-w-xs",
multiline ? "w-fit max-w-32 sm:max-w-48" : "max-w-xs",
)}
>
<button
+1 -1
View File
@@ -2512,7 +2512,7 @@ function route(m: string, path: string, seg: string[], q: URLSearchParams, b: Re
profile_id: 0,
prompt: "",
timeout_seconds: 15,
retry_count: 0,
retry_count: 3,
retry_interval_ms: 1000,
fail_action: "ask",
ask_timeout_seconds: 300,