ЮИ - Перенести настройки ассистента в управление автопрогонами и убрать верхний режим Ассистент

This commit is contained in:
2026-04-16 20:18:23 +03:00
parent f1333c457e
commit f3255cb3b8
37 changed files with 2987 additions and 166 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -4,8 +4,8 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>NDC AI Normalizer Playground</title>
<script type="module" crossorigin src="/assets/index-Qq5WpuqR.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-Dcuz1nX5.css">
<script type="module" crossorigin src="/assets/index-VJV2AL7G.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-CaUiKcE3.css">
</head>
<body>
<div id="root"></div>
+54 -8
View File
@@ -31,7 +31,7 @@ const SESSION_CONFIG_KEY = "ndc_normalizer_session_config_v1";
const AUTORUNS_LAYOUT_CONFIG_KEY = "ndc_autoruns_layout_config_v1";
const AUTORUNS_SAVE_EVENT = "ndc-autoruns-save";
const ASSISTANT_STAGES = ["Анализ запроса", "Получение данных", "Подготовка ответа"];
const DEFAULT_UI_MODE: UiMode = "assistant";
const DEFAULT_UI_MODE: UiMode = "autoruns";
const AUTOLOAD_PROMPT_VERSION = "normalizer_v2_0_2";
const ASSISTANT_PROMPT_VERSION = "address_query_runtime_v1";
const TAB_KEYS: TabKey[] = ["normalized", "fragments", "scope", "flags", "route", "raw", "validation", "logs"];
@@ -117,6 +117,8 @@ export default function App() {
const [lastError, setLastError] = useState("");
const [uiMode, setUiMode] = useState<UiMode>(DEFAULT_UI_MODE);
const [showAutorunsSettingsMode, setShowAutorunsSettingsMode] = useState(true);
const [showAutorunsAutoRunsMode, setShowAutorunsAutoRunsMode] = useState(true);
const [showAutorunsAssistantMode, setShowAutorunsAssistantMode] = useState(true);
const [showAutorunsDecompositionMode, setShowAutorunsDecompositionMode] = useState(true);
const [showAutorunsProgressMode, setShowAutorunsProgressMode] = useState(true);
@@ -239,6 +241,8 @@ export default function App() {
const parsed = JSON.parse(cachedAutorunsLayout) as {
uiMode?: UiMode;
activeTab?: TabKey;
showAutorunsSettingsMode?: boolean;
showAutorunsAutoRunsMode?: boolean;
showAutorunsAssistantMode?: boolean;
showAutorunsDecompositionMode?: boolean;
showAutorunsProgressMode?: boolean;
@@ -257,12 +261,20 @@ export default function App() {
showDecompositionRuntimeMode?: boolean;
prompts?: PromptState;
};
if (parsed.uiMode === "assistant" || parsed.uiMode === "decomposition" || parsed.uiMode === "autoruns") {
setUiMode(parsed.uiMode);
if (parsed.uiMode === "decomposition") {
setUiMode("decomposition");
} else if (parsed.uiMode === "assistant" || parsed.uiMode === "autoruns") {
setUiMode("autoruns");
}
if (parsed.activeTab && TAB_KEYS.includes(parsed.activeTab)) {
setActiveTab(parsed.activeTab);
}
if (typeof parsed.showAutorunsSettingsMode === "boolean") {
setShowAutorunsSettingsMode(parsed.showAutorunsSettingsMode);
}
if (typeof parsed.showAutorunsAutoRunsMode === "boolean") {
setShowAutorunsAutoRunsMode(parsed.showAutorunsAutoRunsMode);
}
if (typeof parsed.showAutorunsAssistantMode === "boolean") {
setShowAutorunsAssistantMode(parsed.showAutorunsAssistantMode);
}
@@ -430,6 +442,8 @@ export default function App() {
JSON.stringify({
uiMode,
activeTab,
showAutorunsSettingsMode,
showAutorunsAutoRunsMode,
showAutorunsAssistantMode,
showAutorunsDecompositionMode,
showAutorunsProgressMode,
@@ -946,15 +960,12 @@ export default function App() {
>
<header className="app-topbar">
<div className="mode-switch-row">
<button type="button" className={uiMode === "assistant" ? "tab active" : "tab"} onClick={() => setUiMode("assistant")}>
Ассистент
<button type="button" className={uiMode === "autoruns" ? "tab active" : "tab"} onClick={() => setUiMode("autoruns")}>
Управление ассистентом
</button>
<button type="button" className={uiMode === "decomposition" ? "tab active" : "tab"} onClick={() => setUiMode("decomposition")}>
Декомпозиция
</button>
<button type="button" className={uiMode === "autoruns" ? "tab active" : "tab"} onClick={() => setUiMode("autoruns")}>
История автопрогонов
</button>
<button type="button" className="tab" onClick={saveAutorunsLayout}>
Сохранить
</button>
@@ -1036,6 +1047,20 @@ export default function App() {
</div>
) : uiMode === "autoruns" ? (
<div className="mode-switch-row mode-switch-row-right">
<button
type="button"
className={showAutorunsSettingsMode ? "tab active" : "tab"}
onClick={() => setShowAutorunsSettingsMode((prev) => !prev)}
>
Настройки
</button>
<button
type="button"
className={showAutorunsAutoRunsMode ? "tab active" : "tab"}
onClick={() => setShowAutorunsAutoRunsMode((prev) => !prev)}
>
Автопрогоны
</button>
<button
type="button"
className={showAutorunsAssistantMode ? "tab active" : "tab"}
@@ -1300,9 +1325,30 @@ export default function App() {
<div className="layout-grid layout-grid-autoruns">
<AutoRunsHistoryPanel
connection={connection}
modelOptions={modelOptions}
modelsBusy={modelsBusy}
connectionStatus={connectionStatus}
connectionBusy={busy}
onConnectionChange={setConnection}
onReloadModels={reloadModels}
onSaveLocalConfig={saveLocalConfig}
onTestConnection={testConnection}
prompts={prompts}
onPromptsChange={setPrompts}
promptPresets={presetList}
selectedPresetId={selectedPresetId}
onSelectPreset={setSelectedPresetId}
onLoadPreset={loadSelectedPreset}
onSavePreset={savePreset}
onResetDefaults={resetDefaults}
onDiffPrevious={diffWithPrevious}
presetName={presetName}
onPresetNameChange={setPresetName}
diffSummary={diffSummary}
assistantPromptVersion={ASSISTANT_PROMPT_VERSION}
decompositionPromptVersion={AUTOLOAD_PROMPT_VERSION}
showSettingsMode={showAutorunsSettingsMode}
showAutoRunsMode={showAutorunsAutoRunsMode}
showAssistantMode={showAutorunsAssistantMode}
showDecompositionMode={showAutorunsDecompositionMode}
showProgressMode={showAutorunsProgressMode}
@@ -22,14 +22,46 @@ import type {
PromptState
} from "../state/types";
import { AssistantPanel } from "./AssistantPanel";
import { ConnectionPanel } from "./ConnectionPanel";
import { JsonView } from "./JsonView";
import { PanelFrame } from "./PanelFrame";
import { PromptPanel } from "./PromptPanel";
interface AutoRunsHistoryPanelProps {
connection: ConnectionState;
modelOptions: string[];
modelsBusy: boolean;
connectionStatus: string;
connectionBusy: boolean;
onConnectionChange: (next: ConnectionState) => void;
onReloadModels: () => Promise<void> | void;
onSaveLocalConfig: () => void;
onTestConnection: () => Promise<void> | void;
prompts: PromptState;
onPromptsChange: (next: PromptState) => void;
promptPresets: Array<{
id: string;
name: string;
prompt_version: string;
systemPrompt: string;
developerPrompt: string;
domainPrompt: string;
schemaNotes?: string;
fewShotExamples?: string;
}>;
selectedPresetId: string;
onSelectPreset: (id: string) => void;
onLoadPreset: () => void;
onSavePreset: () => void;
onResetDefaults: () => void;
onDiffPrevious: () => void;
presetName: string;
onPresetNameChange: (name: string) => void;
diffSummary: string;
assistantPromptVersion: string;
decompositionPromptVersion: string;
showSettingsMode: boolean;
showAutoRunsMode: boolean;
showAssistantMode: boolean;
showDecompositionMode: boolean;
showProgressMode: boolean;
@@ -470,9 +502,30 @@ function CopyOutlineIcon() {
export function AutoRunsHistoryPanel({
connection,
modelOptions,
modelsBusy,
connectionStatus,
connectionBusy,
onConnectionChange,
onReloadModels,
onSaveLocalConfig,
onTestConnection,
prompts,
onPromptsChange,
promptPresets,
selectedPresetId,
onSelectPreset,
onLoadPreset,
onSavePreset,
onResetDefaults,
onDiffPrevious,
presetName,
onPresetNameChange,
diffSummary,
assistantPromptVersion,
decompositionPromptVersion,
showSettingsMode,
showAutoRunsMode,
showAssistantMode,
showDecompositionMode,
showProgressMode,
@@ -1726,9 +1779,47 @@ export function AutoRunsHistoryPanel({
hideHeader
>
<div className="autoruns-columns">
<section className="autoruns-col">
{showSettingsMode ? (
<section className="autoruns-col autoruns-settings-col">
<div className="autoruns-col-header">
<h3>Настройки</h3>
</div>
<div className="autoruns-settings-stack">
<ConnectionPanel
embedded
value={connection}
modelOptions={modelOptions}
modelsBusy={modelsBusy}
onChange={onConnectionChange}
onReloadModels={onReloadModels}
onSaveLocalConfig={onSaveLocalConfig}
onTestConnection={onTestConnection}
lastStatus={connectionStatus}
busy={connectionBusy}
/>
<PromptPanel
embedded
value={prompts}
onChange={onPromptsChange}
presets={promptPresets}
selectedPresetId={selectedPresetId}
onSelectPreset={onSelectPreset}
onLoadPreset={onLoadPreset}
onSavePreset={onSavePreset}
onResetDefaults={onResetDefaults}
onDiffPrevious={onDiffPrevious}
presetName={presetName}
onPresetNameChange={onPresetNameChange}
diffSummary={diffSummary}
/>
</div>
</section>
) : null}
{showAutoRunsMode ? (
<section className="autoruns-col">
<div className="autoruns-col-header">
<h3>Настройки</h3>
<h3>Автопрогоны</h3>
</div>
<h4>Настройки выборки</h4>
@@ -2086,6 +2177,7 @@ export function AutoRunsHistoryPanel({
{errorText ? <p className="error-text">{errorText}</p> : null}
</section>
) : null}
<section className="autoruns-col">
<div className="autoruns-col-header">
@@ -63,6 +63,7 @@ interface ConnectionPanelProps {
onSaveLocalConfig: () => void;
lastStatus: string;
busy: boolean;
embedded?: boolean;
}
export function ConnectionPanel({
@@ -74,7 +75,8 @@ export function ConnectionPanel({
onTestConnection,
onSaveLocalConfig,
lastStatus,
busy
busy,
embedded = false
}: ConnectionPanelProps) {
const isLocal = value.llmProvider === "local";
const providerPreset = deriveProviderPreset(value);
@@ -121,12 +123,8 @@ export function ConnectionPanel({
setMaxOutputTokensInput(String(parsed));
};
return (
<PanelFrame
title="LLM Connection"
subtitle="Switch between OpenAI cloud and local OpenAI-compatible server."
actions={<span className="status-chip">{lastStatus || "Status: not checked"}</span>}
>
const content = (
<>
<div className="grid-two">
<label>
Provider
@@ -269,6 +267,31 @@ export function ConnectionPanel({
{busy ? "Checking..." : "Test connection"}
</button>
</div>
</>
);
if (embedded) {
return (
<section className="embedded-panel-section">
<div className="embedded-panel-section-header">
<div>
<h4>LLM Connector</h4>
<p>Switch between OpenAI cloud and local OpenAI-compatible server.</p>
</div>
<span className="status-chip">{lastStatus || "Status: not checked"}</span>
</div>
{content}
</section>
);
}
return (
<PanelFrame
title="LLM Connector"
subtitle="Switch between OpenAI cloud and local OpenAI-compatible server."
actions={<span className="status-chip">{lastStatus || "Status: not checked"}</span>}
>
{content}
</PanelFrame>
);
}
@@ -25,6 +25,7 @@ interface PromptPanelProps {
presetName: string;
onPresetNameChange: (name: string) => void;
diffSummary: string;
embedded?: boolean;
}
export function PromptPanel({
@@ -39,10 +40,11 @@ export function PromptPanel({
onDiffPrevious,
presetName,
onPresetNameChange,
diffSummary
diffSummary,
embedded = false
}: PromptPanelProps) {
return (
<PanelFrame title="Prompt Manager" subtitle="Системный, developer и domain уровни управляются отдельно.">
const content = (
<>
<div className="prompt-manager-grid">
<label>
Системный prompt
@@ -101,6 +103,26 @@ export function PromptPanel({
</button>
</div>
{diffSummary ? <p className="diff-summary">{diffSummary}</p> : null}
</>
);
if (embedded) {
return (
<section className="embedded-panel-section">
<div className="embedded-panel-section-header">
<div>
<h4>Prompt Manager</h4>
<p>Системный, developer и domain уровни управляются отдельно.</p>
</div>
</div>
{content}
</section>
);
}
return (
<PanelFrame title="Prompt Manager" subtitle="Системный, developer и domain уровни управляются отдельно.">
{content}
</PanelFrame>
);
}
+38
View File
@@ -966,6 +966,44 @@ button:disabled {
scrollbar-gutter: stable;
}
.autoruns-settings-col {
display: flex;
flex-direction: column;
}
.autoruns-settings-stack {
display: grid;
gap: 12px;
}
.embedded-panel-section {
display: grid;
gap: 12px;
border-radius: 12px;
background: rgb(var(--rgb-surface-horizontal));
padding: 12px;
}
.embedded-panel-section-header {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 12px;
}
.embedded-panel-section-header h4 {
margin: 0;
color: var(--text-main);
font-size: 0.92rem;
}
.embedded-panel-section-header p {
margin: 6px 0 0;
color: var(--text-muted);
font-size: 0.78rem;
line-height: 1.4;
}
.autoruns-assistant-live-col {
background: rgb(var(--rgb-surface-main));
padding: 12px;