Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/desktop/src/main/services/agent/flows/review.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export function runReviewForPr(
language: getMainLanguage(),
toolCatalog: buildToolCatalog(agentCfg.autopilot.grants),
plan: effectivePlan,
maxFollowupAsks: agentCfg.autopilot.max_followup_asks,
maxFollowupAsks: agentCfg.strategy.max_followup_asks,
summaryMaxChars: agentCfg.summary_max_chars,
onStep: (sessionId, step) => runtime.emitStep(pr, sessionId, step),
signal,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ export function SettingsModal({
<AgentStrategySection
autoFollowup={s.autoFollowup}
onAutoFollowupChange={s.setAutoFollowup}
maxFollowupAsks={s.maxFollowupAsks}
onMaxFollowupAsksChange={s.setMaxFollowupAsks}
maxCodeSuggestions={s.maxCodeSuggestions}
onMaxCodeSuggestionsChange={s.setMaxCodeSuggestions}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,11 @@ export function useSettingsDraft({
// 原样回传、不被覆盖成默认值;目录经 agentDirInput、策略开关经 autoFollowup 可编辑。
const [agent] = useState<Config['agent']>(config.agent);
const [agentDirInput, setAgentDirInput] = useState(config.agent.dir);
// Agent 策略(自动追问 + 代码建议数量上限)。随 config:setAgent 一并保存。
// Agent 策略(自动追问开关 + 追问数量上限 + 代码建议数量上限)。随 config:setAgent 一并保存。
const [autoFollowup, setAutoFollowupState] = useState(config.agent.strategy.auto_followup);
const [maxFollowupAsks, setMaxFollowupAsksState] = useState(
config.agent.strategy.max_followup_asks,
);
const [maxCodeSuggestions, setMaxCodeSuggestionsState] = useState(
config.agent.strategy.max_code_suggestions,
);
Expand All @@ -69,6 +72,7 @@ export function useSettingsDraft({
reposDir: config.workspace.repos_dir,
agentDir: config.agent.dir,
autoFollowup: config.agent.strategy.auto_followup,
maxFollowupAsks: config.agent.strategy.max_followup_asks,
maxCodeSuggestions: config.agent.strategy.max_code_suggestions,
poller: config.poller.interval_seconds,
concurrency: config.pr_agent.max_concurrency,
Expand Down Expand Up @@ -238,6 +242,10 @@ export function useSettingsDraft({
setAutoFollowupState(v);
setSaved(false);
};
const setMaxFollowupAsks = (n: number): void => {
setMaxFollowupAsksState(n);
setSaved(false);
};
const setMaxCodeSuggestions = (n: number): void => {
setMaxCodeSuggestionsState(n);
setSaved(false);
Expand Down Expand Up @@ -266,6 +274,7 @@ export function useSettingsDraft({
const agentChanged =
agentDirInput.trim() !== base.agentDir ||
autoFollowup !== base.autoFollowup ||
maxFollowupAsks !== base.maxFollowupAsks ||
maxCodeSuggestions !== base.maxCodeSuggestions;
const pollerChanged = pollerInput.trim() !== String(base.poller);
const concurrencyChanged = maxConcurrencyInput !== base.concurrency;
Expand Down Expand Up @@ -306,6 +315,7 @@ export function useSettingsDraft({
strategy: {
...agent.strategy,
auto_followup: autoFollowup,
max_followup_asks: maxFollowupAsks,
max_code_suggestions: maxCodeSuggestions,
},
},
Expand Down Expand Up @@ -333,6 +343,7 @@ export function useSettingsDraft({
reposDir: reposDirInput.trim(),
agentDir: agentDirInput.trim(),
autoFollowup,
maxFollowupAsks,
maxCodeSuggestions,
poller: Number.parseInt(pollerInput, 10),
concurrency: maxConcurrencyInput,
Expand Down Expand Up @@ -390,6 +401,8 @@ export function useSettingsDraft({
pickAgentDir,
autoFollowup,
setAutoFollowup,
maxFollowupAsks,
setMaxFollowupAsks,
maxCodeSuggestions,
setMaxCodeSuggestions,
reposDirInput,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
import { useTranslation } from 'react-i18next';
import { Switch } from '../../../common';

// 自动追问数量上限可选档位(1~5)。开关已独立控制启停,故不给 0(0 在 schema 等同关闭,仅手改 config 可达)。
const MAX_FOLLOWUP_ASKS_OPTIONS = [1, 2, 3, 4, 5];
// 代码建议数量上限可选档位(2~8)。
const MAX_CODE_SUGGESTIONS_OPTIONS = [2, 3, 4, 5, 6, 7, 8];

/**
* Agent 策略:扩展 Agent 行为控制的分区,子项以缩进的「功能列表」逐行展示(行首圆点 + 标题 + 说明,
* 右侧控件)。右侧控件不限于开关——自动追问用 Switch,代码建议数量用下拉(同一通用 .settings-sublist-*)。
* 后续策略项在此追加一行即可。
* 右侧控件)。右侧控件不限于开关——自动追问用 Switch,追问数量 / 代码建议数量用下拉(同一通用
* .settings-sublist-*)。追问数量仅在自动追问开启时可调(关闭时下拉禁用)。后续策略项在此追加一行即可。
*/
export function AgentStrategySection({
autoFollowup,
onAutoFollowupChange,
maxFollowupAsks,
onMaxFollowupAsksChange,
maxCodeSuggestions,
onMaxCodeSuggestionsChange,
}: {
autoFollowup: boolean;
onAutoFollowupChange: (next: boolean) => void;
maxFollowupAsks: number;
onMaxFollowupAsksChange: (next: number) => void;
maxCodeSuggestions: number;
onMaxCodeSuggestionsChange: (next: number) => void;
}) {
Expand All @@ -39,6 +45,28 @@ export function AgentStrategySection({
ariaLabel={t('settings.autoFollowupLabel')}
/>
</li>
<li className="settings-sublist-row">
<div className="settings-sublist-text">
<span className="settings-sublist-label">{t('settings.maxFollowupAsksLabel')}</span>
<span className="muted settings-sublist-desc">
{t('settings.maxFollowupAsksHint')}
</span>
</div>
{/* 追问数量仅在自动追问开启时生效 → 关闭时禁用,避免「开关关、数量却可调」的歧义。 */}
<select
className="settings-input settings-sublist-select"
value={maxFollowupAsks}
disabled={!autoFollowup}
onChange={(e) => onMaxFollowupAsksChange(Number.parseInt(e.target.value, 10))}
aria-label={t('settings.maxFollowupAsksLabel')}
>
{MAX_FOLLOWUP_ASKS_OPTIONS.map((n) => (
<option key={n} value={n}>
{n}
</option>
))}
</select>
</li>
<li className="settings-sublist-row">
<div className="settings-sublist-text">
<span className="settings-sublist-label">{t('settings.maxCodeSuggestionsLabel')}</span>
Expand Down
2 changes: 2 additions & 0 deletions apps/desktop/src/renderer/src/i18n/locales/de-DE.json
Original file line number Diff line number Diff line change
Expand Up @@ -712,6 +712,8 @@
"llmTitle": "LLM-Modelle",
"maxCodeSuggestionsHint": "Max. Code-Vorschläge pro /review, /improve oder /ask.",
"maxCodeSuggestionsLabel": "Code-Vorschläge",
"maxFollowupAsksHint": "Maximale Anzahl bedingter Rückfragen pro Review, wenn die automatische Rückfrage aktiv ist.",
"maxFollowupAsksLabel": "Rückfragen",
"openAgentDir": "Aktuelles Verzeichnis öffnen",
"openDevTools": "DevTools öffnen",
"openDevToolsTitle": "Electron DevTools öffnen (separates Fenster)",
Expand Down
2 changes: 2 additions & 0 deletions apps/desktop/src/renderer/src/i18n/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -712,6 +712,8 @@
"llmTitle": "LLM Models",
"maxCodeSuggestionsHint": "Max code suggestions per /review, /improve, or /ask.",
"maxCodeSuggestionsLabel": "Code suggestions",
"maxFollowupAsksHint": "Maximum conditional follow-up questions per review when auto follow-up is on.",
"maxFollowupAsksLabel": "Follow-up questions",
"openAgentDir": "Open current directory",
"openDevTools": "Open DevTools",
"openDevToolsTitle": "Open Electron DevTools (detached window)",
Expand Down
2 changes: 2 additions & 0 deletions apps/desktop/src/renderer/src/i18n/locales/ja-JP.json
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,8 @@
"llmTitle": "LLM モデル",
"maxCodeSuggestionsHint": "/review・/improve・/ask が一度に生成するコード提案数の上限。",
"maxCodeSuggestionsLabel": "コード提案数",
"maxFollowupAsksHint": "自動追問が有効なとき、1 回のレビューで行う条件付き追問の数の上限。",
"maxFollowupAsksLabel": "追問の数",
"openAgentDir": "現在のディレクトリを開く",
"openDevTools": "DevTools を開く",
"openDevToolsTitle": "Electron DevTools を開く(分離ウィンドウ)",
Expand Down
2 changes: 2 additions & 0 deletions apps/desktop/src/renderer/src/i18n/locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,8 @@
"llmTitle": "LLM 模型",
"maxCodeSuggestionsHint": "单次 /review、/improve、/ask 生成的代码建议数量上限。",
"maxCodeSuggestionsLabel": "代码建议数量",
"maxFollowupAsksHint": "自动追问启用时,单次评审条件性追问的数量上限。",
"maxFollowupAsksLabel": "追问数量",
"openAgentDir": "打开当前目录",
"openDevTools": "打开 DevTools",
"openDevToolsTitle": "打开 Electron 开发者工具(分离窗口)",
Expand Down
5 changes: 3 additions & 2 deletions docs/arch/06-agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ flowchart TD
2. **仅对严重问题条件性追问** —— **默认不追问**。该 PR 的 agent 读 §1 工具输出(findings 及其
`severity`,见 [05](05-review-workflow.md)),仅当出现**特别恶性 /
高严重度**的疑点(例如疑似安全漏洞、数据损坏、严重逻辑缺陷且需核实上下文)才考虑就该点补跑
`/ask`。**硬上限 ≤2 个问题**(`agent.autopilot.max_followup_asks`,默认 2):
`/ask`。**硬上限 ≤2 个问题**(`agent.strategy.max_followup_asks`,默认 2):
没有严重问题就一个都不问,绝不为追问而追问。`/ask` 是只读工具,属红线放行范围(见 §4)。
3. **逐 PR 收尾总结(严格限长)** —— **由该 PR 的 agent 在本 PR 子任务(describe / review / 追问)
全部结束后**产出一段**严格限长**的总结(综合本 PR 的产出,受 `agent.summary_max_chars` 约束,
Expand Down Expand Up @@ -479,7 +479,8 @@ AutoPilot 可执行自动发布 comment、自动 `approve` / `needswork`。**默
- `agent.autopilot.enabled`:AutoPilot 开关(默认 `false`)。评估节奏对齐轮询(每个 poller tick 一遍),
不再单设最小间隔配置。
- `agent.autopilot.batch_size`:单批判定的 PR 上限(默认 10)。
- `agent.autopilot.max_followup_asks`:自动评审微流程中条件性追问 `/ask` 的硬上限(默认 2)。
- `agent.strategy.max_followup_asks`:自动评审微流程中条件性追问 `/ask` 的硬上限(默认 2;手动自动评审与
AutoPilot 共用,故归 `strategy` 而非 `autopilot`)。
- `agent.autopilot.max_steps`:每个 PR 的子 agent 的结构化步数 backstop(默认按微流程模板推导:≈
`3 + max_followup_asks` + 少量开销)。
- `agent.autopilot.grants`:逐项写权限授权(默认全空 = 全拒)。
Expand Down
17 changes: 15 additions & 2 deletions docs/guide/04-config-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ agent:
autopilot:
enabled: false
batch_size: 10
max_followup_asks: 2
grants: []
strategy:
auto_followup: true
max_followup_asks: 2
max_code_suggestions: 4

poller:
interval_seconds: 300
Expand Down Expand Up @@ -116,6 +119,7 @@ Agent **无独立启用开关**——配置了 LLM 且 pr-agent 就绪即可用
| `max_steps` | integer | `8` | 单次会话的 Agent 规划步数上限,`1`–`50`。 |
| `summary_max_chars` | integer | `800` | 收尾总结的严格篇幅上限(字符),`100`–`4000`。 |
| `autopilot` | object | — | AutoPilot 预评审设置,见下。 |
| `strategy` | object | — | Agent 行为策略(作用于手动自动评审与 AutoPilot),见下。 |

### `agent.autopilot` — AutoPilot 预评审

Expand All @@ -125,9 +129,18 @@ Agent **无独立启用开关**——配置了 LLM 且 pr-agent 就绪即可用
| --- | --- | --- | --- |
| `enabled` | boolean | `false` | AutoPilot 总开关。状态栏可切换;`false` 时调度逻辑完全不跑。 |
| `batch_size` | integer | `10` | 单批 LLM 判定的 PR 上限,`1`–`50`。 |
| `max_followup_asks` | integer | `2` | 自动评审中针对严重问题条件性追问 `/ask` 的硬上限,`0`–`5`。 |
| `grants` | array | `[]` | 逐项写权限授权(默认空 = 全拒),如 `approve` / `needs_work` / `publish_comment`;运行期按红线硬校验放行。 |

### `agent.strategy` — Agent 行为策略

作用于自动评审微流程(手动「自动评审」与 AutoPilot 共用),非 AutoPilot 专属。

| 字段 | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `auto_followup` | boolean | `true` | 评审阶段是否启用**自动追问**(条件性 `/ask`)。关闭则跳过判读 + 追问、直接总结,省一次 LLM 调用与追问开销。 |
| `max_followup_asks` | integer | `2` | 自动追问数量上限(条件性 `/ask` 的硬上限),`0`–`5`。仅 `auto_followup` 开启时生效;`0` 等同关闭。 |
| `max_code_suggestions` | integer | `4` | 单次 `/review`、`/improve`、`/ask` 生成的代码建议数量上限,`2`–`8`。 |

## `poller` — PR 轮询

| 字段 | 类型 | 默认 | 说明 |
Expand Down
11 changes: 8 additions & 3 deletions packages/shared/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,6 @@ export const ConfigSchema = z.object({
// 评估节奏对齐轮询(每个 poller tick 评估一遍),不再单设最小间隔;准入门控 + 台账去重防重复。
/** 单批 LLM 判定的 PR 上限。 */
batch_size: z.number().int().min(1).max(50).default(10),
/** 自动评审微流程中条件性追问 /ask 的硬上限。 */
max_followup_asks: z.number().int().min(0).max(5).default(2),
/**
* 逐项写权限授权(默认空 = 全拒)。如 'approve' / 'needs_work' /
* 'publish_comment';运行期按红线硬校验放行(见「工具修改红线」)。
Expand All @@ -239,14 +237,21 @@ export const ConfigSchema = z.object({
})
.default({}),
/**
* Agent 行为策略开关(扩展位,后续行为开关并入此处)。当前一项:
* Agent 行为策略(扩展位,后续行为开关并入此处)。作用于自动评审微流程(手动自动评审 +
* AutoPilot 共用),非 AutoPilot 专属。当前各项:
* - auto_followup:评审运行阶段是否启用**自动追问**(条件性 /ask)。关闭则评审微流程跳过
* judge + asks 两步、直接总结,省一次 judge LLM 调用与潜在追问开销(省 token)。默认开,
* 与历史行为一致。
* - max_followup_asks:自动追问数量上限(条件性 /ask 的硬上限)。
*/
strategy: z
.object({
auto_followup: z.boolean().default(true),
/**
* 自动追问数量上限(条件性 /ask 的硬上限,0~5,默认 2)。仅 auto_followup 开启时生效;
* 0 等同关闭(开关已独立控制启停,故 UI 下拉只提供 1~5、不给 0 以免歧义)。
*/
max_followup_asks: z.number().int().min(0).max(5).default(2),
/**
* 单次任务生成的代码建议 / 评审发现数量上限(2~8,默认 4)。统一约束三处:
* - /review:pr-agent `pr_reviewer.num_max_findings`(硬上限);
Expand Down
Loading