diff --git a/apps/desktop/src/app/settings/model-settings.tsx b/apps/desktop/src/app/settings/model-settings.tsx index 6ae1590c8e..48210fcf95 100644 --- a/apps/desktop/src/app/settings/model-settings.tsx +++ b/apps/desktop/src/app/settings/model-settings.tsx @@ -115,6 +115,7 @@ const AUX_TASKS: readonly AuxTaskMeta[] = [ { key: 'approval' }, { key: 'mcp' }, { key: 'title_generation' }, + { key: 'review' }, { key: 'curator' } ] diff --git a/apps/desktop/src/i18n/ar.ts b/apps/desktop/src/i18n/ar.ts index bb1e3d1bbd..5af5d3809c 100644 --- a/apps/desktop/src/i18n/ar.ts +++ b/apps/desktop/src/i18n/ar.ts @@ -887,6 +887,10 @@ export const ar = defineLocale({ label: 'توليد العناوين', hint: 'عناوين الجلسات' }, + review: { + label: 'المراجعة', + hint: 'وكيل المراجعة الفرعي /review' + }, curator: { label: 'المنسّق', hint: 'مراجعة استخدام المهارات' diff --git a/apps/desktop/src/i18n/en.ts b/apps/desktop/src/i18n/en.ts index 00bc7b6bc4..abf0f72a3c 100644 --- a/apps/desktop/src/i18n/en.ts +++ b/apps/desktop/src/i18n/en.ts @@ -1076,6 +1076,7 @@ export const en: Translations = { approval: { label: 'Approval', hint: 'Smart auto-approve' }, mcp: { label: 'MCP', hint: 'MCP tool routing' }, title_generation: { label: 'Title gen', hint: 'Session titles' }, + review: { label: 'Review', hint: '/review reviewer subagent' }, curator: { label: 'Curator', hint: 'Skill-usage review' } } }, diff --git a/apps/desktop/src/i18n/ja.ts b/apps/desktop/src/i18n/ja.ts index c6c790c57b..a69d06d1eb 100644 --- a/apps/desktop/src/i18n/ja.ts +++ b/apps/desktop/src/i18n/ja.ts @@ -998,6 +998,7 @@ export const ja = defineLocale({ approval: { label: '承認', hint: 'スマート自動承認' }, mcp: { label: 'MCP', hint: 'MCP ツールルーティング' }, title_generation: { label: 'タイトル生成', hint: 'セッションタイトル' }, + review: { label: 'レビュー', hint: '/review レビューサブエージェント' }, curator: { label: 'キュレーター', hint: 'スキル使用レビュー' } } }, diff --git a/apps/desktop/src/i18n/zh-hant.ts b/apps/desktop/src/i18n/zh-hant.ts index 9c16366bfd..fc1a4bdc10 100644 --- a/apps/desktop/src/i18n/zh-hant.ts +++ b/apps/desktop/src/i18n/zh-hant.ts @@ -965,6 +965,7 @@ export const zhHant = defineLocale({ approval: { label: '核准', hint: '智慧自動核准' }, mcp: { label: 'MCP', hint: 'MCP 工具路由' }, title_generation: { label: '標題生成', hint: '工作階段標題' }, + review: { label: '評審', hint: '/review 評審子代理' }, curator: { label: '策展器', hint: '技能使用審查' } } }, diff --git a/apps/desktop/src/i18n/zh.ts b/apps/desktop/src/i18n/zh.ts index 26e8d3ef83..9d6550279e 100644 --- a/apps/desktop/src/i18n/zh.ts +++ b/apps/desktop/src/i18n/zh.ts @@ -1272,6 +1272,7 @@ export const zh: Translations = { approval: { label: '审批', hint: '智能自动批准' }, mcp: { label: 'MCP', hint: 'MCP 工具路由' }, title_generation: { label: '标题生成', hint: '会话标题' }, + review: { label: '评审', hint: '/review 评审子智能体' }, curator: { label: '维护器', hint: '技能使用审查' } } }, diff --git a/hermes_cli/main.py b/hermes_cli/main.py index 7f4c0e9a40..73fc5135b2 100644 --- a/hermes_cli/main.py +++ b/hermes_cli/main.py @@ -4102,6 +4102,7 @@ _AUX_TASKS: list[tuple[str, str, str]] = [ ("approval", "Approval", "smart command approval"), ("mcp", "MCP", "MCP tool reasoning"), ("title_generation", "Title generation", "session titles"), + ("review", "Review", "/review reviewer subagent"), ("memory_query_rewrite", "Memory query rewrite", "memory retrieval queries"), ("tts_audio_tags", "TTS audio tags", "Gemini TTS tag insertion"), ("skills_hub", "Skills hub", "skills search/install"), diff --git a/hermes_cli/web_server.py b/hermes_cli/web_server.py index 244eaa830f..432a72fd5d 100644 --- a/hermes_cli/web_server.py +++ b/hermes_cli/web_server.py @@ -7165,6 +7165,7 @@ _AUX_TASK_SLOTS: Tuple[str, ...] = ( "approval", "mcp", "title_generation", + "review", "triage_specifier", "kanban_decomposer", "profile_describer", diff --git a/tests/agent/test_review_engine.py b/tests/agent/test_review_engine.py index 7a5598aab2..98c5c2510e 100644 --- a/tests/agent/test_review_engine.py +++ b/tests/agent/test_review_engine.py @@ -268,6 +268,35 @@ def test_start_review_requires_agent(): start_review(None, [{"role": "user", "content": "x"}], "") +# --------------------------------------------------------------------------- +# Registry sync: `review` must be a first-class slot in every aux-task surface +# --------------------------------------------------------------------------- + +def test_review_registered_in_every_aux_surface(): + """The /review slot must appear in every aux-model picker registry. + + Same contract as curator's registry test in tests/agent/test_curator.py: + DEFAULT_CONFIG schema, CLI picker (_AUX_TASKS), and dashboard REST + allowlist (_AUX_TASK_SLOTS). The desktop and web AUX_TASKS tsx arrays + mirror _AUX_TASK_SLOTS by convention (shared "Must match" comments). + """ + from hermes_cli.config import DEFAULT_CONFIG + from hermes_cli.main import _AUX_TASKS + from hermes_cli.web_server import _AUX_TASK_SLOTS + + assert "review" in DEFAULT_CONFIG["auxiliary"], \ + "review missing from DEFAULT_CONFIG['auxiliary']" + slot = DEFAULT_CONFIG["auxiliary"]["review"] + assert slot["provider"] == "auto" + assert slot["model"] == "" + + aux_keys = {k for k, _name, _desc in _AUX_TASKS} + assert "review" in aux_keys, "review missing from _AUX_TASKS (CLI picker)" + + assert "review" in _AUX_TASK_SLOTS, \ + "review missing from _AUX_TASK_SLOTS (dashboard REST API)" + + # --------------------------------------------------------------------------- # format_dispatch_note # --------------------------------------------------------------------------- diff --git a/web/src/pages/ModelsPage.tsx b/web/src/pages/ModelsPage.tsx index 8954f8b7e3..6cda5c6dfc 100644 --- a/web/src/pages/ModelsPage.tsx +++ b/web/src/pages/ModelsPage.tsx @@ -58,6 +58,7 @@ const AUX_TASKS: readonly { key: string; label: string; hint: string }[] = [ { key: "approval", label: "Approval", hint: "Smart auto-approve" }, { key: "mcp", label: "MCP", hint: "MCP tool routing" }, { key: "title_generation", label: "Title Gen", hint: "Session titles" }, + { key: "review", label: "Review", hint: "/review subagent" }, { key: "triage_specifier", label: "Triage Specifier", hint: "Kanban spec fleshing" }, { key: "kanban_decomposer", label: "Kanban Decomposer", hint: "Task decomposition" }, { key: "profile_describer", label: "Profile Describer", hint: "Auto profile descriptions" }, diff --git a/website/docs/user-guide/features/fallback-providers.md b/website/docs/user-guide/features/fallback-providers.md index 6f64ee6834..dbd824954d 100644 --- a/website/docs/user-guide/features/fallback-providers.md +++ b/website/docs/user-guide/features/fallback-providers.md @@ -200,6 +200,7 @@ Hermes uses separate lightweight models for side tasks. Each task has its own pr | MCP | MCP helper operations | `auxiliary.mcp` | | Approval | Smart command-approval classification | `auxiliary.approval` | | Title Generation | Session title summaries | `auxiliary.title_generation` | +| Review | `/review` reviewer subagent (full agent, not a single LLM call) | `auxiliary.review` | | Triage Specifier | `hermes kanban specify` / dashboard ✨ button — fleshes out a one-liner triage task into a real spec | `auxiliary.triage_specifier` | ### Auto-Detection Chain diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/features/delegation.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/features/delegation.md index 15793c8d08..835d7d2cfb 100644 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/features/delegation.md +++ b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/features/delegation.md @@ -161,6 +161,38 @@ delegation: 注意此固定是全局的:`delegate_task` 没有按任务指定模型的参数,批处理中的每个子智能体都运行配置的委派模型。对于需要更强模型的质量敏感型子任务,可以在该会话中不设置 `delegation.model`,或者将任务交给[看板](kanban.md)——看板支持按任务覆盖模型。 +## `/review` 命令 + +`/review` 会派生一个独立的、拥有完整工具权限的后台评审子智能体,专门评审对话刚刚产出的工作——PR、diff、代码、文档、设计。它在所有界面均可用:CLI、TUI、桌面应用以及所有网关消息平台。 + +``` +/review # 评审最近 10 条消息中呈现的工作 +/review 重点关注安全性 # 为评审者附加额外指示 +``` + +工作流程: + +1. 最近 10 条用户/助手消息被快照为评审者的起始证据(工具输出和系统消息被排除)。 +2. 评审子智能体在与 `delegate_task` 相同的后台委派通道上派发——它拥有完整的常规子智能体工具集(终端、网络、文件、浏览器等),因此会实际打开 PR、阅读 diff、运行代码,而不是仅凭摘录下判断。 +3. 完成后,完整评审作为常规后台子智能体完成事件重新进入同一会话——你的主智能体可以看到并据此行动(修复问题、推送后续提交、回复你)。 + +典型流程:主智能体开了一个 PR,你输入 `/review`,第二双眼睛在你继续工作的同时对其进行调查;评审结果回到聊天中,交给创建该 PR 的智能体。 + +### 评审模型 + +默认情况下评审者运行在你的主模型上。要固定专用评审模型,请在 `config.yaml` 中设置 `auxiliary.review`: + +```yaml +auxiliary: + review: + provider: openrouter # 或 nous、anthropic、直连 base_url 等 + model: anthropic/claude-opus-4.6 # 一个强力的评审模型 +``` + +凭证解析方式与 `delegation.provider` 固定完全相同(完整运行时提供商凭证包:base_url、API 密钥、api_mode)。`provider: auto` 加空 `model` 表示"继承主智能体的模型"——这是默认值。 + +`/review` 与 `/refine` 刻意分开:`/refine` 评审对话本身以更新记忆和技能,`/review` 评审对话产出的*工作成果*。 + ## 继承的工具访问权限 `delegate_task` 不接受面向模型的 `toolsets` 参数。每个子智能体都会继承父智能体已启用的工具集,因此模型无法授予子智能体父智能体本身没有的能力。如果委派任务需要其他能力,请在开始对话前配置父智能体的工具。 diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/features/fallback-providers.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/features/fallback-providers.md index 1aa55fd846..c0192820aa 100644 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/features/fallback-providers.md +++ b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/features/fallback-providers.md @@ -191,6 +191,7 @@ Hermes 为附属任务使用独立的轻量级模型。每个任务都有自己 | MCP | MCP 辅助操作 | `auxiliary.mcp` | | 审批 | 智能命令审批分类 | `auxiliary.approval` | | 标题生成 | 会话标题摘要 | `auxiliary.title_generation` | +| 评审 | `/review` 评审子智能体(完整智能体,而非单次 LLM 调用) | `auxiliary.review` | | Triage Specifier | `hermes kanban specify` / 看板(kanban)✨ 按钮——将单行 triage 任务扩展为完整规格 | `auxiliary.triage_specifier` | ### 自动检测链