mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-05-12 06:41:05 +08:00
cc-switch could already persist arbitrary OMO Slim agent keys and top-level fields, but the built-in metadata and UI copy still reflected the pre-council agent set. This made the upstream council feature look unsupported and pushed users toward manual JSON-only setup. Promote council to a built-in OMO Slim agent, add copy that points top-level plugin settings at Other Fields, and lock the behavior with regression tests. Constraint: oh-my-opencode-slim exposes council through both agents.council and top-level council config Rejected: Add a dedicated council editor UI now | too much surface area for issue #1981 Confidence: high Scope-risk: narrow Reversibility: clean Directive: Keep OMO Slim built-in agent metadata aligned with upstream agent additions before shipping UI support Tested: pnpm exec vitest run tests/utils/omoConfig.test.ts tests/components/OmoFormFields.mergeCustomModelsIntoStore.test.ts Tested: pnpm typecheck Not-tested: End-to-end validation against a live oh-my-opencode-slim installation Related: farion1231/cc-switch#1981
This commit is contained in:
@@ -1264,12 +1264,22 @@ export function OmoFormFields({
|
||||
) : undefined,
|
||||
maxHeightClass: "max-h-[500px]",
|
||||
children: (
|
||||
<Textarea
|
||||
value={otherFieldsStr}
|
||||
onChange={(e) => onOtherFieldsStrChange(e.target.value)}
|
||||
placeholder='{ "custom_key": "value" }'
|
||||
className="font-mono text-xs min-h-[60px]"
|
||||
/>
|
||||
<>
|
||||
<Textarea
|
||||
value={otherFieldsStr}
|
||||
onChange={(e) => onOtherFieldsStrChange(e.target.value)}
|
||||
placeholder='{ "custom_key": "value" }'
|
||||
className="font-mono text-xs min-h-[60px]"
|
||||
/>
|
||||
{isSlim && (
|
||||
<p className="mt-1 text-[10px] text-muted-foreground">
|
||||
{t("omo.slimOtherFieldsHint", {
|
||||
defaultValue:
|
||||
"Use this area for top-level OMO Slim config such as council, fallback, multiplexer, disabled_mcps, and todoContinuation.",
|
||||
})}
|
||||
</p>
|
||||
)}
|
||||
</>
|
||||
),
|
||||
})}
|
||||
</div>
|
||||
|
||||
@@ -2277,6 +2277,7 @@
|
||||
"enabledModelsCount": "{{count}} configured models available",
|
||||
"source": "from:",
|
||||
"otherFieldsJson": "Other Fields (JSON)",
|
||||
"slimOtherFieldsHint": "Use this area for top-level OMO Slim config such as council, fallback, multiplexer, disabled_mcps, and todoContinuation.",
|
||||
"searchOrType": "Search or type custom value...",
|
||||
"noMatches": "No matches",
|
||||
"jsonMustBeObject": "{{field}} must be a JSON object",
|
||||
@@ -2353,7 +2354,8 @@
|
||||
"librarian": "Librarian",
|
||||
"explorer": "Explorer",
|
||||
"designer": "Designer",
|
||||
"fixer": "Fixer"
|
||||
"fixer": "Fixer",
|
||||
"council": "Council"
|
||||
},
|
||||
"slimAgentTooltip": {
|
||||
"orchestrator": "Writes executable code, orchestrates multi-agent workflow, summons experts",
|
||||
@@ -2361,7 +2363,8 @@
|
||||
"librarian": "Documentation lookup, GitHub code search (read-only)",
|
||||
"explorer": "Regex search, AST pattern matching, file discovery (read-only)",
|
||||
"designer": "Modern responsive design, CSS/Tailwind expertise",
|
||||
"fixer": "Code implementation, refactoring, testing, verification"
|
||||
"fixer": "Code implementation, refactoring, testing, verification",
|
||||
"council": "Multi-model consensus agent. Runs multiple read-only councillors in parallel, then lets the master synthesize the final answer."
|
||||
}
|
||||
},
|
||||
"openclawConfig": {
|
||||
|
||||
@@ -2277,6 +2277,7 @@
|
||||
"enabledModelsCount": "設定済みモデル {{count}} 件",
|
||||
"source": "出典:",
|
||||
"otherFieldsJson": "その他のフィールド (JSON)",
|
||||
"slimOtherFieldsHint": "council、fallback、multiplexer、disabled_mcps、todoContinuation など、OMO Slim のトップレベル設定はここに記述します。",
|
||||
"searchOrType": "検索またはカスタム値を入力...",
|
||||
"noMatches": "一致する項目がありません",
|
||||
"jsonMustBeObject": "{{field}} は JSON オブジェクトである必要があります",
|
||||
@@ -2353,7 +2354,8 @@
|
||||
"librarian": "ライブラリアン",
|
||||
"explorer": "エクスプローラー",
|
||||
"designer": "デザイナー",
|
||||
"fixer": "フィクサー"
|
||||
"fixer": "フィクサー",
|
||||
"council": "カウンシル"
|
||||
},
|
||||
"slimAgentTooltip": {
|
||||
"orchestrator": "実行コードの作成、マルチエージェントワークフローの調整、エキスパートの召喚",
|
||||
@@ -2361,7 +2363,8 @@
|
||||
"librarian": "ドキュメント検索、GitHubコード検索(読み取り専用)",
|
||||
"explorer": "正規表現検索、ASTパターンマッチング、ファイル検出(読み取り専用)",
|
||||
"designer": "モダンなレスポンシブデザイン、CSS/Tailwindの専門知識",
|
||||
"fixer": "コード実装、リファクタリング、テスト、検証"
|
||||
"fixer": "コード実装、リファクタリング、テスト、検証",
|
||||
"council": "複数モデルの合議エージェント。複数の読み取り専用 councillor を並列実行し、master が最終回答を統合します。"
|
||||
}
|
||||
},
|
||||
"openclawConfig": {
|
||||
|
||||
@@ -2277,6 +2277,7 @@
|
||||
"enabledModelsCount": "可选已配置模型 {{count}} 个",
|
||||
"source": "来源:",
|
||||
"otherFieldsJson": "其他字段 (JSON)",
|
||||
"slimOtherFieldsHint": "OMO Slim 的 council、fallback、multiplexer、disabled_mcps、todoContinuation 等顶层配置请写在这里。",
|
||||
"searchOrType": "搜索或输入自定义值...",
|
||||
"noMatches": "无匹配项",
|
||||
"jsonMustBeObject": "{{field}} 必须是 JSON 对象",
|
||||
@@ -2353,7 +2354,8 @@
|
||||
"librarian": "图书管理员",
|
||||
"explorer": "探索者",
|
||||
"designer": "设计师",
|
||||
"fixer": "修复者"
|
||||
"fixer": "修复者",
|
||||
"council": "议会"
|
||||
},
|
||||
"slimAgentTooltip": {
|
||||
"orchestrator": "编写执行代码,编排多代理工作流,召唤专家",
|
||||
@@ -2361,7 +2363,8 @@
|
||||
"librarian": "文档查询、GitHub 代码搜索(只读)",
|
||||
"explorer": "正则搜索、AST 模式匹配、文件发现(只读)",
|
||||
"designer": "现代响应式设计、CSS/Tailwind 精通",
|
||||
"fixer": "代码实现、重构、测试、验证"
|
||||
"fixer": "代码实现、重构、测试、验证",
|
||||
"council": "多模型共识代理,并行运行多个只读 councillor,再由 master 汇总最终答案。"
|
||||
}
|
||||
},
|
||||
"openclawConfig": {
|
||||
|
||||
@@ -362,6 +362,14 @@ export const OMO_SLIM_BUILTIN_AGENTS: OmoAgentDef[] = [
|
||||
recommended: "gpt-5.4",
|
||||
group: "sub",
|
||||
},
|
||||
{
|
||||
key: "council",
|
||||
display: "Council",
|
||||
descKey: "omo.slimAgentDesc.council",
|
||||
tooltipKey: "omo.slimAgentTooltip.council",
|
||||
recommended: "gpt-5.4-mini",
|
||||
group: "sub",
|
||||
},
|
||||
];
|
||||
|
||||
export const OMO_SLIM_DISABLEABLE_AGENTS = [
|
||||
@@ -371,6 +379,7 @@ export const OMO_SLIM_DISABLEABLE_AGENTS = [
|
||||
{ value: "explorer", label: "Explorer" },
|
||||
{ value: "designer", label: "Designer" },
|
||||
{ value: "fixer", label: "Fixer" },
|
||||
{ value: "council", label: "Council" },
|
||||
] as const;
|
||||
|
||||
export const OMO_SLIM_DISABLEABLE_MCPS = [
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
buildOmoProfilePreview,
|
||||
buildOmoSlimProfilePreview,
|
||||
OMO_SLIM_BUILTIN_AGENTS,
|
||||
OMO_SLIM_DISABLEABLE_AGENTS,
|
||||
parseOmoOtherFieldsObject,
|
||||
} from "@/types/omo";
|
||||
|
||||
@@ -28,3 +31,38 @@ describe("buildOmoProfilePreview", () => {
|
||||
expect(fromObject).toEqual({ foo: "bar" });
|
||||
});
|
||||
});
|
||||
|
||||
describe("buildOmoSlimProfilePreview", () => {
|
||||
it("保留 top-level council 配置,同时写入 council agent 模型", () => {
|
||||
const preview = buildOmoSlimProfilePreview(
|
||||
{
|
||||
council: { model: "openai/gpt-5.4-mini" },
|
||||
},
|
||||
'{ "council": { "default_preset": "default" }, "fallback": { "enabled": true } }',
|
||||
);
|
||||
|
||||
expect(preview).toEqual({
|
||||
council: { default_preset: "default" },
|
||||
fallback: { enabled: true },
|
||||
agents: {
|
||||
council: { model: "openai/gpt-5.4-mini" },
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("OMO Slim metadata", () => {
|
||||
it("将 council 视为内置且可禁用的 agent", () => {
|
||||
expect(OMO_SLIM_BUILTIN_AGENTS).toContainEqual(
|
||||
expect.objectContaining({
|
||||
key: "council",
|
||||
display: "Council",
|
||||
group: "sub",
|
||||
}),
|
||||
);
|
||||
expect(OMO_SLIM_DISABLEABLE_AGENTS).toContainEqual({
|
||||
value: "council",
|
||||
label: "Council",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user