Упростить фронтенд сохранённых сессий ассистента
This commit is contained in:
parent
43ae3237ce
commit
a14eee4976
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -4,7 +4,7 @@
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>NDC AI Normalizer Playground</title>
|
<title>NDC AI Normalizer Playground</title>
|
||||||
<script type="module" crossorigin src="/assets/index-BdTHVNKv.js"></script>
|
<script type="module" crossorigin src="/assets/index-B26u5hxP.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-D-Jp8Dx0.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-D-Jp8Dx0.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
||||||
|
|
@ -312,7 +312,6 @@ export const apiClient = {
|
||||||
|
|
||||||
async sendAssistantMessage(input: {
|
async sendAssistantMessage(input: {
|
||||||
connection: ConnectionState;
|
connection: ConnectionState;
|
||||||
prompts: PromptState;
|
|
||||||
userMessage: string;
|
userMessage: string;
|
||||||
sessionId?: string;
|
sessionId?: string;
|
||||||
promptVersion?: string;
|
promptVersion?: string;
|
||||||
|
|
@ -336,10 +335,6 @@ export const apiClient = {
|
||||||
temperature: input.connection.temperature,
|
temperature: input.connection.temperature,
|
||||||
maxOutputTokens: input.connection.maxOutputTokens,
|
maxOutputTokens: input.connection.maxOutputTokens,
|
||||||
promptVersion: input.promptVersion ?? "address_query_runtime_v1",
|
promptVersion: input.promptVersion ?? "address_query_runtime_v1",
|
||||||
systemPrompt: input.prompts.systemPrompt,
|
|
||||||
developerPrompt: input.prompts.developerPrompt,
|
|
||||||
domainPrompt: input.prompts.domainPrompt,
|
|
||||||
fewShotExamples: input.prompts.fewShotExamples,
|
|
||||||
context: {
|
context: {
|
||||||
period_hint: input.context?.periodHint ?? "",
|
period_hint: input.context?.periodHint ?? "",
|
||||||
business_context: input.context?.businessContext ?? ""
|
business_context: input.context?.businessContext ?? ""
|
||||||
|
|
@ -362,7 +357,6 @@ export const apiClient = {
|
||||||
model?: string;
|
model?: string;
|
||||||
assistant_prompt_version?: string;
|
assistant_prompt_version?: string;
|
||||||
decomposition_prompt_version?: string;
|
decomposition_prompt_version?: string;
|
||||||
prompt_fingerprint?: string;
|
|
||||||
};
|
};
|
||||||
}): Promise<{ ok: boolean; generation: AutoGenHistoryRecord }> {
|
}): Promise<{ ok: boolean; generation: AutoGenHistoryRecord }> {
|
||||||
return request("/autoruns/autogen/save-assistant-session", {
|
return request("/autoruns/autogen/save-assistant-session", {
|
||||||
|
|
@ -534,35 +528,5 @@ export const apiClient = {
|
||||||
return request(`/autoruns/autogen/history/${encodeURIComponent(generationId)}`, {
|
return request(`/autoruns/autogen/history/${encodeURIComponent(generationId)}`, {
|
||||||
method: "DELETE"
|
method: "DELETE"
|
||||||
});
|
});
|
||||||
},
|
|
||||||
|
|
||||||
async generateAutoRunQuestions(input: {
|
|
||||||
mode: AutoGenMode;
|
|
||||||
count: number;
|
|
||||||
domain?: string;
|
|
||||||
persist_to_eval_cases?: boolean;
|
|
||||||
generated_by?: string;
|
|
||||||
llm?: {
|
|
||||||
llm_provider?: "openai" | "local";
|
|
||||||
api_key?: string;
|
|
||||||
model?: string;
|
|
||||||
base_url?: string;
|
|
||||||
temperature?: number;
|
|
||||||
max_output_tokens?: number;
|
|
||||||
};
|
|
||||||
context?: {
|
|
||||||
llm_provider?: string;
|
|
||||||
model?: string;
|
|
||||||
assistant_prompt_version?: string;
|
|
||||||
decomposition_prompt_version?: string;
|
|
||||||
prompt_fingerprint?: string;
|
|
||||||
autogen_personality_id?: string;
|
|
||||||
autogen_personality_prompt?: string;
|
|
||||||
};
|
|
||||||
}): Promise<{ ok: boolean; generation: AutoGenHistoryRecord }> {
|
|
||||||
return request("/autoruns/autogen/generate", {
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify(input)
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -244,7 +244,7 @@ type UnifiedCommentListItem =
|
||||||
};
|
};
|
||||||
|
|
||||||
const DEFAULT_AUTOGEN_SETTINGS: AutoGenSettingsState = {
|
const DEFAULT_AUTOGEN_SETTINGS: AutoGenSettingsState = {
|
||||||
mode: "codex_creative",
|
mode: "saved_user_sessions",
|
||||||
count: 24,
|
count: 24,
|
||||||
personalityId: "general",
|
personalityId: "general",
|
||||||
personalityPrompts: buildDefaultPersonalityPrompts(),
|
personalityPrompts: buildDefaultPersonalityPrompts(),
|
||||||
|
|
@ -723,7 +723,6 @@ export function AutoRunsHistoryPanel({
|
||||||
const [dragOverQuestionIndex, setDragOverQuestionIndex] = useState<number | null>(null);
|
const [dragOverQuestionIndex, setDragOverQuestionIndex] = useState<number | null>(null);
|
||||||
const [activeAsyncJob, setActiveAsyncJob] = useState<AsyncEvalRunJob | null>(null);
|
const [activeAsyncJob, setActiveAsyncJob] = useState<AsyncEvalRunJob | null>(null);
|
||||||
const [postAnalysis, setPostAnalysis] = useState<AutoRunPostAnalysisResponse | null>(null);
|
const [postAnalysis, setPostAnalysis] = useState<AutoRunPostAnalysisResponse | null>(null);
|
||||||
const [autoGenBusy, setAutoGenBusy] = useState(false);
|
|
||||||
const [autogenRunBusy, setAutogenRunBusy] = useState(false);
|
const [autogenRunBusy, setAutogenRunBusy] = useState(false);
|
||||||
const [postAnalysisBusy, setPostAnalysisBusy] = useState(false);
|
const [postAnalysisBusy, setPostAnalysisBusy] = useState(false);
|
||||||
const [autogenHistoryBusy, setAutogenHistoryBusy] = useState(false);
|
const [autogenHistoryBusy, setAutogenHistoryBusy] = useState(false);
|
||||||
|
|
@ -801,10 +800,6 @@ export function AutoRunsHistoryPanel({
|
||||||
const asyncJobPollTimerRef = useRef<number | null>(null);
|
const asyncJobPollTimerRef = useRef<number | null>(null);
|
||||||
const questionEditorRef = useRef<HTMLInputElement | null>(null);
|
const questionEditorRef = useRef<HTMLInputElement | null>(null);
|
||||||
const isSavedUserSessionsMode = autoGenSettings.mode === "saved_user_sessions";
|
const isSavedUserSessionsMode = autoGenSettings.mode === "saved_user_sessions";
|
||||||
const selectedPersonality = useMemo(
|
|
||||||
() => autogenPersonalities.find((item) => item.id === autoGenSettings.personalityId) ?? autogenPersonalities[0] ?? AUTOGEN_PERSONALITIES[0],
|
|
||||||
[autoGenSettings.personalityId, autogenPersonalities]
|
|
||||||
);
|
|
||||||
const visibleAutoGenHistory = useMemo(
|
const visibleAutoGenHistory = useMemo(
|
||||||
() => autoGenHistory.filter((item) => item.mode === autoGenSettings.mode),
|
() => autoGenHistory.filter((item) => item.mode === autoGenSettings.mode),
|
||||||
[autoGenHistory, autoGenSettings.mode]
|
[autoGenHistory, autoGenSettings.mode]
|
||||||
|
|
@ -1104,7 +1099,6 @@ export function AutoRunsHistoryPanel({
|
||||||
try {
|
try {
|
||||||
const response = await apiClient.sendAssistantMessage({
|
const response = await apiClient.sendAssistantMessage({
|
||||||
connection,
|
connection,
|
||||||
prompts,
|
|
||||||
userMessage,
|
userMessage,
|
||||||
sessionId: assistantLiveSessionId || undefined,
|
sessionId: assistantLiveSessionId || undefined,
|
||||||
promptVersion: assistantPromptVersion,
|
promptVersion: assistantPromptVersion,
|
||||||
|
|
@ -1132,8 +1126,7 @@ export function AutoRunsHistoryPanel({
|
||||||
assistantPromptVersion,
|
assistantPromptVersion,
|
||||||
connection,
|
connection,
|
||||||
loadAssistantLiveAnnotationsForSession,
|
loadAssistantLiveAnnotationsForSession,
|
||||||
log,
|
log
|
||||||
prompts
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const openAssistantLiveSaveModal = useCallback(() => {
|
const openAssistantLiveSaveModal = useCallback(() => {
|
||||||
|
|
@ -1164,13 +1157,6 @@ export function AutoRunsHistoryPanel({
|
||||||
|
|
||||||
setAssistantLiveSaveModal((prev) => ({ ...prev, saving: true, error: "" }));
|
setAssistantLiveSaveModal((prev) => ({ ...prev, saving: true, error: "" }));
|
||||||
try {
|
try {
|
||||||
const promptFingerprint = [
|
|
||||||
prompts.systemPrompt,
|
|
||||||
prompts.developerPrompt,
|
|
||||||
prompts.domainPrompt,
|
|
||||||
prompts.schemaNotes,
|
|
||||||
prompts.fewShotExamples
|
|
||||||
].join("||");
|
|
||||||
const payload = await apiClient.saveAutoRunAssistantSession({
|
const payload = await apiClient.saveAutoRunAssistantSession({
|
||||||
session_id: sessionId,
|
session_id: sessionId,
|
||||||
title,
|
title,
|
||||||
|
|
@ -1179,8 +1165,7 @@ export function AutoRunsHistoryPanel({
|
||||||
llm_provider: connection.llmProvider,
|
llm_provider: connection.llmProvider,
|
||||||
model: connection.model,
|
model: connection.model,
|
||||||
assistant_prompt_version: assistantPromptVersion,
|
assistant_prompt_version: assistantPromptVersion,
|
||||||
decomposition_prompt_version: decompositionPromptVersion,
|
decomposition_prompt_version: decompositionPromptVersion
|
||||||
prompt_fingerprint: promptFingerprint
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
setAutoGenHistory((prev) => [payload.generation, ...prev.filter((item) => item.generation_id !== payload.generation.generation_id)]);
|
setAutoGenHistory((prev) => [payload.generation, ...prev.filter((item) => item.generation_id !== payload.generation.generation_id)]);
|
||||||
|
|
@ -1202,12 +1187,7 @@ export function AutoRunsHistoryPanel({
|
||||||
connection.llmProvider,
|
connection.llmProvider,
|
||||||
connection.model,
|
connection.model,
|
||||||
decompositionPromptVersion,
|
decompositionPromptVersion,
|
||||||
log,
|
log
|
||||||
prompts.developerPrompt,
|
|
||||||
prompts.domainPrompt,
|
|
||||||
prompts.fewShotExamples,
|
|
||||||
prompts.schemaNotes,
|
|
||||||
prompts.systemPrompt
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const commitLimitInput = useCallback(
|
const commitLimitInput = useCallback(
|
||||||
|
|
@ -1363,87 +1343,6 @@ export function AutoRunsHistoryPanel({
|
||||||
}
|
}
|
||||||
}, [filters.fromLocal, filters.mode, filters.promptContains, filters.target, filters.toLocal, filters.useMock, log, selectedRunId]);
|
}, [filters.fromLocal, filters.mode, filters.promptContains, filters.target, filters.toLocal, filters.useMock, log, selectedRunId]);
|
||||||
|
|
||||||
const generateAutogenBatch = useCallback(async () => {
|
|
||||||
setAutoGenBusy(true);
|
|
||||||
setErrorText("");
|
|
||||||
try {
|
|
||||||
if (autoGenSettings.mode === "saved_user_sessions") {
|
|
||||||
throw new Error("Пользовательские сессии сохраняются из живого чата, а не генерируются автоматически.");
|
|
||||||
}
|
|
||||||
const activePersonalityPrompt = autoGenSettings.personalityPrompts[autoGenSettings.personalityId] ?? "";
|
|
||||||
const promptFingerprint = [
|
|
||||||
prompts.systemPrompt,
|
|
||||||
prompts.developerPrompt,
|
|
||||||
prompts.domainPrompt,
|
|
||||||
prompts.schemaNotes,
|
|
||||||
prompts.fewShotExamples
|
|
||||||
]
|
|
||||||
.join("\n")
|
|
||||||
.slice(0, 900);
|
|
||||||
const payload = await apiClient.generateAutoRunQuestions({
|
|
||||||
mode: autoGenSettings.mode,
|
|
||||||
count: autoGenSettings.count,
|
|
||||||
domain: selectedPersonality.domain || undefined,
|
|
||||||
persist_to_eval_cases: autoGenSettings.persistToEvalCases,
|
|
||||||
generated_by: autoGenSettings.generatedBy.trim() || undefined,
|
|
||||||
llm: {
|
|
||||||
llm_provider: connection.llmProvider,
|
|
||||||
api_key: connection.apiKey,
|
|
||||||
model: connection.model,
|
|
||||||
base_url: connection.baseUrl,
|
|
||||||
temperature: connection.temperature,
|
|
||||||
max_output_tokens: connection.maxOutputTokens
|
|
||||||
},
|
|
||||||
context: {
|
|
||||||
llm_provider: connection.llmProvider,
|
|
||||||
model: connection.model,
|
|
||||||
assistant_prompt_version: assistantPromptVersion,
|
|
||||||
decomposition_prompt_version: decompositionPromptVersion,
|
|
||||||
prompt_fingerprint: promptFingerprint,
|
|
||||||
autogen_personality_id: selectedPersonality.id,
|
|
||||||
autogen_personality_prompt: activePersonalityPrompt.trim() || undefined
|
|
||||||
}
|
|
||||||
});
|
|
||||||
log(
|
|
||||||
`Generated ${payload.generation.count} questions (${payload.generation.mode}) id=${payload.generation.generation_id}` +
|
|
||||||
(payload.generation.saved_case_set_file ? ` saved=${payload.generation.saved_case_set_file}` : "")
|
|
||||||
);
|
|
||||||
setSelectedAutogenGenerationId(payload.generation.generation_id);
|
|
||||||
setEditableGeneratedQuestions([...(payload.generation.questions ?? [])]);
|
|
||||||
await loadAutoGenHistory();
|
|
||||||
} catch (error) {
|
|
||||||
const message = error instanceof Error ? error.message : String(error);
|
|
||||||
setErrorText(`Автогенерация: ${message}`);
|
|
||||||
log(`Autogen generate error: ${message}`);
|
|
||||||
} finally {
|
|
||||||
setAutoGenBusy(false);
|
|
||||||
}
|
|
||||||
}, [
|
|
||||||
assistantPromptVersion,
|
|
||||||
autoGenSettings.count,
|
|
||||||
autoGenSettings.generatedBy,
|
|
||||||
autoGenSettings.mode,
|
|
||||||
autoGenSettings.personalityId,
|
|
||||||
autoGenSettings.personalityPrompts,
|
|
||||||
autoGenSettings.persistToEvalCases,
|
|
||||||
connection.apiKey,
|
|
||||||
connection.baseUrl,
|
|
||||||
connection.llmProvider,
|
|
||||||
connection.maxOutputTokens,
|
|
||||||
connection.model,
|
|
||||||
connection.temperature,
|
|
||||||
decompositionPromptVersion,
|
|
||||||
loadAutoGenHistory,
|
|
||||||
log,
|
|
||||||
prompts.developerPrompt,
|
|
||||||
prompts.domainPrompt,
|
|
||||||
prompts.fewShotExamples,
|
|
||||||
prompts.schemaNotes,
|
|
||||||
prompts.systemPrompt,
|
|
||||||
selectedPersonality.domain,
|
|
||||||
selectedPersonality.id
|
|
||||||
]);
|
|
||||||
|
|
||||||
const loadCaseDialog = useCallback(
|
const loadCaseDialog = useCallback(
|
||||||
async (runId: string, caseId: string) => {
|
async (runId: string, caseId: string) => {
|
||||||
if (isLiveRunId(runId)) {
|
if (isLiveRunId(runId)) {
|
||||||
|
|
@ -2477,12 +2376,7 @@ export function AutoRunsHistoryPanel({
|
||||||
: prev.personalityId;
|
: prev.personalityId;
|
||||||
return {
|
return {
|
||||||
...prev,
|
...prev,
|
||||||
mode:
|
mode: "saved_user_sessions",
|
||||||
parsed.autoGenSettings?.mode === "codex_creative" ||
|
|
||||||
parsed.autoGenSettings?.mode === "qwen_seed" ||
|
|
||||||
parsed.autoGenSettings?.mode === "saved_user_sessions"
|
|
||||||
? parsed.autoGenSettings.mode
|
|
||||||
: prev.mode,
|
|
||||||
count:
|
count:
|
||||||
typeof parsed.autoGenSettings?.count === "number"
|
typeof parsed.autoGenSettings?.count === "number"
|
||||||
? Math.max(1, Math.min(200, parsed.autoGenSettings.count))
|
? Math.max(1, Math.min(200, parsed.autoGenSettings.count))
|
||||||
|
|
@ -2767,7 +2661,7 @@ export function AutoRunsHistoryPanel({
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<div className="autoruns-group-heading">
|
<div className="autoruns-group-heading">
|
||||||
<h4>Автопрогоны</h4>
|
<h4>Сохранённые сессии</h4>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="autoruns-group-toggle"
|
className="autoruns-group-toggle"
|
||||||
|
|
@ -2782,13 +2676,12 @@ export function AutoRunsHistoryPanel({
|
||||||
<>
|
<>
|
||||||
<div className="autoruns-form-grid">
|
<div className="autoruns-form-grid">
|
||||||
<label>
|
<label>
|
||||||
Режимы
|
Режим
|
||||||
<select
|
<select
|
||||||
value={autoGenSettings.mode}
|
value={autoGenSettings.mode}
|
||||||
|
disabled
|
||||||
onChange={(event) => setAutoGenSettings((prev) => ({ ...prev, mode: event.target.value as AutoGenMode }))}
|
onChange={(event) => setAutoGenSettings((prev) => ({ ...prev, mode: event.target.value as AutoGenMode }))}
|
||||||
>
|
>
|
||||||
<option value="codex_creative">codex_creative</option>
|
|
||||||
<option value="qwen_seed">qwen_seed</option>
|
|
||||||
<option value="saved_user_sessions">Пользовательские сессии</option>
|
<option value="saved_user_sessions">Пользовательские сессии</option>
|
||||||
</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
|
|
@ -2892,20 +2785,13 @@ export function AutoRunsHistoryPanel({
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<div className="button-row">
|
<div className="button-row">
|
||||||
{!isSavedUserSessionsMode ? (
|
|
||||||
<>
|
|
||||||
<button type="button" disabled={autoGenBusy} onClick={() => void generateAutogenBatch()}>
|
|
||||||
{autoGenBusy ? "Генерирую..." : "Сгенерировать пачку"}
|
|
||||||
</button>
|
|
||||||
<button type="button" className="tab" disabled={autogenHistoryBusy} onClick={() => void loadAutoGenHistory()}>
|
<button type="button" className="tab" disabled={autogenHistoryBusy} onClick={() => void loadAutoGenHistory()}>
|
||||||
{autogenHistoryBusy ? "Обновляю..." : "Обновить историю"}
|
{autogenHistoryBusy ? "Обновляю..." : "Обновить историю"}
|
||||||
</button>
|
</button>
|
||||||
</>
|
{!isSavedUserSessionsMode ? (
|
||||||
) : null}
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="autoruns-run-launch-btn"
|
className="autoruns-run-launch-btn"
|
||||||
style={isSavedUserSessionsMode ? { display: "none" } : undefined}
|
|
||||||
disabled={
|
disabled={
|
||||||
autogenStopBusy ||
|
autogenStopBusy ||
|
||||||
(!autogenRunBusy && (editableGeneratedQuestions.length === 0 || !selectedAutogenGeneration))
|
(!autogenRunBusy && (editableGeneratedQuestions.length === 0 || !selectedAutogenGeneration))
|
||||||
|
|
@ -2914,6 +2800,7 @@ export function AutoRunsHistoryPanel({
|
||||||
>
|
>
|
||||||
{autogenRunBusy ? (autogenStopBusy ? "Останавливаю..." : "Остановить прогон") : "Запустить прогон"}
|
{autogenRunBusy ? (autogenStopBusy ? "Останавливаю..." : "Остановить прогон") : "Запустить прогон"}
|
||||||
</button>
|
</button>
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="autoruns-form-grid">
|
<div className="autoruns-form-grid">
|
||||||
|
|
|
||||||
|
|
@ -111,8 +111,8 @@ export function PromptPanel({
|
||||||
<section className="embedded-panel-section">
|
<section className="embedded-panel-section">
|
||||||
<div className="embedded-panel-section-header">
|
<div className="embedded-panel-section-header">
|
||||||
<div>
|
<div>
|
||||||
<h4>Prompt Manager</h4>
|
<h4>Normalizer / eval prompts</h4>
|
||||||
<p>Системный, developer и domain уровни управляются отдельно.</p>
|
<p>Эти поля управляют декомпозицией и eval-прогонами, а не live-ответом ассистента.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{content}
|
{content}
|
||||||
|
|
@ -121,7 +121,7 @@ export function PromptPanel({
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PanelFrame title="Prompt Manager" subtitle="Системный, developer и domain уровни управляются отдельно.">
|
<PanelFrame title="Normalizer / eval prompts" subtitle="Эти поля управляют декомпозицией и eval-прогонами, а не live-ответом ассистента.">
|
||||||
{content}
|
{content}
|
||||||
</PanelFrame>
|
</PanelFrame>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue