Initial commit: NetMesh smart ops platform with 3D topology, inspection reports, RCA and AI ops assistant
Some checks failed
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled

This commit is contained in:
2026-10-15 13:53:04 +08:00
commit 2f9f8da48e
3299 changed files with 926841 additions and 0 deletions

View File

@@ -0,0 +1,185 @@
import { Brain, RotateCcw, Save } from "lucide-react";
import React, { useEffect, useState } from "react";
import { Button } from "../../../ui/button";
import { SettingCard, SettingsSection } from "../../settings-ui";
import {
DEFAULT_PHASE1_SYSTEM,
DEFAULT_PHASE2_SYSTEM,
} from "../../../../infrastructure/ai/rcaAgent/rcaRunner";
const STORAGE_KEY = "netcatty_rca_prompts_v1";
interface RcaPromptsConfig {
phase1?: string;
phase2?: string;
}
function loadConfig(): RcaPromptsConfig {
try {
const raw = localStorage.getItem(STORAGE_KEY);
if (raw) return JSON.parse(raw);
} catch (_) {}
return {};
}
function saveConfig(cfg: RcaPromptsConfig) {
localStorage.setItem(STORAGE_KEY, JSON.stringify(cfg));
}
export const RcaPromptSettings: React.FC = () => {
const defaults = {
phase1: DEFAULT_PHASE1_SYSTEM,
phase2: DEFAULT_PHASE2_SYSTEM,
};
const [phase1, setPhase1] = useState("");
const [phase2, setPhase2] = useState("");
const [savedVersion, setSavedVersion] = useState<{ p1: string; p2: string }>({ p1: "", p2: "" });
// 加载 localStorage 中的自定义值(无则空字符串,表示"使用默认")
useEffect(() => {
const cfg = loadConfig();
const p1 = cfg.phase1 ?? "";
const p2 = cfg.phase2 ?? "";
setPhase1(p1);
setPhase2(p2);
setSavedVersion({ p1, p2 });
}, []);
const dirty = phase1 !== savedVersion.p1 || phase2 !== savedVersion.p2;
const phase1IsDefault = !phase1.trim();
const phase2IsDefault = !phase2.trim();
const handleSave = () => {
const cfg: RcaPromptsConfig = {
phase1: phase1.trim() ? phase1 : undefined,
phase2: phase2.trim() ? phase2 : undefined,
};
saveConfig(cfg);
setSavedVersion({ p1: phase1, p2: phase2 });
};
const handleResetAll = () => {
setPhase1("");
setPhase2("");
};
return (
<SettingsSection
anchorId="ai-rca-prompts"
title="RCA 智能诊断提示词"
>
<p className="text-sm text-muted-foreground mb-4">
自定义 AI 根因分析(RCA)的系统提示词。留空表示使用内置默认值。
Phase 1 是诊断命令规划,Phase 2 是根因综合分析。
</p>
<SettingCard divided={false}>
<div className="flex items-center justify-between gap-3 mb-4">
<div className="flex items-center gap-2 text-sm text-muted-foreground">
<Brain size={16} />
<span>自定义提示词会覆盖内置默认值,点击"恢复默认"可清空编辑内容。</span>
</div>
<div className="flex items-center gap-2">
<Button
variant="ghost"
size="sm"
onClick={handleResetAll}
disabled={phase1IsDefault && phase2IsDefault}
>
<RotateCcw size={14} className="mr-1" />
全部恢复默认
</Button>
<Button size="sm" onClick={handleSave} disabled={!dirty}>
<Save size={14} className="mr-1" />
保存
</Button>
</div>
</div>
{/* Phase 1 */}
<div className="space-y-2 mb-5">
<div className="flex items-center justify-between">
<label className="text-sm font-medium">
Phase 1 — 诊断规划 Agent
<span className="ml-2 text-xs text-muted-foreground font-normal">
(AI 根据告警规划要执行的诊断命令)
</span>
</label>
<div className="flex items-center gap-2 text-xs">
{phase1IsDefault ? (
<span className="text-green-600 dark:text-green-400">使用默认</span>
) : (
<span className="text-amber-600 dark:text-amber-400">已自定义</span>
)}
{!phase1IsDefault && (
<Button
variant="ghost"
size="sm"
className="h-7 px-2 text-xs"
onClick={() => setPhase1("")}
>
<RotateCcw size={12} className="mr-1" /> 恢复默认
</Button>
)}
</div>
</div>
<textarea
value={phase1}
onChange={(e) => setPhase1(e.target.value)}
placeholder={defaults.phase1}
className="w-full h-56 rounded-md border border-input bg-background px-3 py-2 text-sm font-mono resize-y focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
spellCheck={false}
/>
{phase1IsDefault && (
<details className="text-xs text-muted-foreground">
<summary className="cursor-pointer hover:text-foreground">预览内置默认提示词</summary>
<pre className="mt-2 p-3 bg-muted/50 rounded text-xs whitespace-pre-wrap max-h-48 overflow-auto font-mono leading-relaxed">{defaults.phase1}</pre>
</details>
)}
</div>
{/* Phase 2 */}
<div className="space-y-2">
<div className="flex items-center justify-between">
<label className="text-sm font-medium">
Phase 2 — 根因综合 Agent
<span className="ml-2 text-xs text-muted-foreground font-normal">
(AI 综合告警 + metrics + 命令输出,生成根因 + 建议)
</span>
</label>
<div className="flex items-center gap-2 text-xs">
{phase2IsDefault ? (
<span className="text-green-600 dark:text-green-400">使用默认</span>
) : (
<span className="text-amber-600 dark:text-amber-400">已自定义</span>
)}
{!phase2IsDefault && (
<Button
variant="ghost"
size="sm"
className="h-7 px-2 text-xs"
onClick={() => setPhase2("")}
>
<RotateCcw size={12} className="mr-1" /> 恢复默认
</Button>
)}
</div>
</div>
<textarea
value={phase2}
onChange={(e) => setPhase2(e.target.value)}
placeholder={defaults.phase2}
className="w-full h-56 rounded-md border border-input bg-background px-3 py-2 text-sm font-mono resize-y focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
spellCheck={false}
/>
{phase2IsDefault && (
<details className="text-xs text-muted-foreground">
<summary className="cursor-pointer hover:text-foreground">预览内置默认提示词</summary>
<pre className="mt-2 p-3 bg-muted/50 rounded text-xs whitespace-pre-wrap max-h-48 overflow-auto font-mono leading-relaxed">{defaults.phase2}</pre>
</details>
)}
</div>
</SettingCard>
</SettingsSection>
);
};