АРЧ ЮИ - остановка прогона через гуй

This commit is contained in:
2026-04-18 18:14:30 +03:00
parent 9710d81676
commit 12550606bb
39 changed files with 1783 additions and 93 deletions
@@ -612,6 +612,14 @@ function CardLaunchIcon() {
);
}
function CardStopIcon() {
return (
<svg className="autoruns-card-stop-svg" viewBox="0 0 16 16" aria-hidden="true" focusable="false">
<rect x="4.2" y="4.2" width="7.6" height="7.6" rx="0.8" />
</svg>
);
}
function GroupChevronIcon({ expanded }: { expanded: boolean }) {
return (
<svg className={expanded ? "autoruns-group-chevron-svg expanded" : "autoruns-group-chevron-svg"} viewBox="0 0 16 16" aria-hidden="true" focusable="false">
@@ -702,6 +710,8 @@ export function AutoRunsHistoryPanel({
const [limitInput, setLimitInput] = useState(String(DEFAULT_FILTERS.limit));
const [autogenCountInput, setAutogenCountInput] = useState(String(DEFAULT_AUTOGEN_SETTINGS.count));
const [autogenPersonalityPromptHeight, setAutogenPersonalityPromptHeight] = useState(160);
const [runningAutogenGenerationId, setRunningAutogenGenerationId] = useState("");
const [autogenStopBusy, setAutogenStopBusy] = useState(false);
const [filtersGroupExpanded, setFiltersGroupExpanded] = useState(true);
const [generationContextGroupExpanded, setGenerationContextGroupExpanded] = useState(true);
const [autogenGroupExpanded, setAutogenGroupExpanded] = useState(true);
@@ -1507,6 +1517,8 @@ export function AutoRunsHistoryPanel({
if (payload.job.status === "completed") {
stopAsyncJobPolling();
setAutogenRunBusy(false);
setAutogenStopBusy(false);
setRunningAutogenGenerationId("");
const finalRunId = payload.job.report_summary?.run_id ?? payload.job.run_id;
await loadHistory({
keepSelection: true,
@@ -1521,11 +1533,25 @@ export function AutoRunsHistoryPanel({
if (payload.job.status === "failed") {
stopAsyncJobPolling();
setAutogenRunBusy(false);
setAutogenStopBusy(false);
setRunningAutogenGenerationId("");
setErrorText(`Запуск прогонов: ${payload.job.error ?? "неизвестная ошибка"}`);
log(`Autogen async run failed: ${payload.job.error ?? "unknown error"}`);
return;
}
if (payload.job.status === "canceled") {
stopAsyncJobPolling();
setAutogenRunBusy(false);
setAutogenStopBusy(false);
setRunningAutogenGenerationId("");
setActiveAsyncJob(null);
await loadHistory({ keepSelection: false });
await loadAutoGenHistory();
log(`Autogen async run canceled: job=${payload.job.job_id}`);
return;
}
stopAsyncJobPolling();
asyncJobPollTimerRef.current = window.setTimeout(() => {
void pollAsyncJobStatus(jobId);
@@ -1533,6 +1559,8 @@ export function AutoRunsHistoryPanel({
} catch (error) {
stopAsyncJobPolling();
setAutogenRunBusy(false);
setAutogenStopBusy(false);
setRunningAutogenGenerationId("");
const message = error instanceof Error ? error.message : String(error);
setErrorText(`Запуск прогонов: ${message}`);
log(`Autogen async status error: ${message}`);
@@ -1579,6 +1607,8 @@ export function AutoRunsHistoryPanel({
});
const liveJob = payload.job;
setRunningAutogenGenerationId(generation.generation_id);
setAutogenStopBusy(false);
setActiveAsyncJob(liveJob);
const liveRunId = toLiveRunId(liveJob.job_id);
const live = buildLiveRunDetail(liveJob, ALL_CASES_ID);
@@ -1602,6 +1632,8 @@ export function AutoRunsHistoryPanel({
setErrorText(`Запуск прогонов: ${message}`);
log(`Autogen run error: ${message}`);
setAutogenRunBusy(false);
setAutogenStopBusy(false);
setRunningAutogenGenerationId("");
}
}, [
analysisDate,
@@ -1616,6 +1648,36 @@ export function AutoRunsHistoryPanel({
stopAsyncJobPolling
]);
const stopAutogenCampaign = useCallback(async () => {
const jobId = activeAsyncJob?.job_id ?? "";
if (!jobId) {
setAutogenRunBusy(false);
setAutogenStopBusy(false);
setRunningAutogenGenerationId("");
setActiveAsyncJob(null);
stopAsyncJobPolling();
return;
}
setAutogenStopBusy(true);
setErrorText("");
try {
const payload = await apiClient.cancelEvalRunAsync(jobId);
stopAsyncJobPolling();
setActiveAsyncJob(null);
setAutogenRunBusy(false);
setAutogenStopBusy(false);
setRunningAutogenGenerationId("");
await loadHistory({ keepSelection: false });
await loadAutoGenHistory();
log(`Autogen async run stopped: job=${payload.job.job_id}`);
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
setAutogenStopBusy(false);
setErrorText(`Остановка прогона: ${message}`);
log(`Autogen stop error: ${message}`);
}
}, [activeAsyncJob, loadAutoGenHistory, loadHistory, log, stopAsyncJobPolling]);
const openCommentModal = useCallback((message: AutoRunDialogMessage) => {
if (message.role !== "assistant") return;
const resolvedCaseId = message.case_id ?? selectedCaseId;
@@ -2750,10 +2812,13 @@ export function AutoRunsHistoryPanel({
type="button"
className="autoruns-run-launch-btn"
style={isSavedUserSessionsMode ? { display: "none" } : undefined}
disabled={autogenRunBusy || editableGeneratedQuestions.length === 0 || !selectedAutogenGeneration}
onClick={() => void runAutogenCampaign()}
disabled={
autogenStopBusy ||
(!autogenRunBusy && (editableGeneratedQuestions.length === 0 || !selectedAutogenGeneration))
}
onClick={() => void (autogenRunBusy ? stopAutogenCampaign() : runAutogenCampaign())}
>
{autogenRunBusy ? "Запускаю..." : "Запустить прогон"}
{autogenRunBusy ? (autogenStopBusy ? "Останавливаю..." : "Остановить прогон") : "Запустить прогон"}
</button>
</div>
@@ -2955,7 +3020,10 @@ export function AutoRunsHistoryPanel({
{isSavedUserSessionsMode ? "Сохраненные пользовательские сессии пока пусты." : "История автогенераций пока пустая."}
</p>
) : null}
{visibleAutoGenHistory.slice(0, 30).map((item) => (
{visibleAutoGenHistory.slice(0, 30).map((item) => {
const isRunningThisGeneration = autogenRunBusy && runningAutogenGenerationId === item.generation_id;
const isAnotherGenerationRunning = autogenRunBusy && runningAutogenGenerationId !== item.generation_id;
return (
<article
key={item.generation_id}
className={[
@@ -2971,20 +3039,24 @@ export function AutoRunsHistoryPanel({
<button
type="button"
className="autoruns-saved-session-icon-btn"
disabled={autogenRunBusy}
disabled={autogenStopBusy || isAnotherGenerationRunning}
onClick={(event) => {
event.preventDefault();
event.stopPropagation();
if (isRunningThisGeneration) {
void stopAutogenCampaign();
return;
}
setSelectedAutogenGenerationId(item.generation_id);
void runAutogenCampaign(
item,
selectedAutogenGenerationId === item.generation_id ? editableGeneratedQuestions : item.questions
);
}}
title="Запустить прогон"
aria-label={`Запустить прогон для ${formatAutoGenGenerationTitle(item)}`}
title={isRunningThisGeneration ? "Остановить прогон" : "Запустить прогон"}
aria-label={`${isRunningThisGeneration ? "Остановить прогон" : "Запустить прогон"} для ${formatAutoGenGenerationTitle(item)}`}
>
<CardLaunchIcon />
{isRunningThisGeneration ? <CardStopIcon /> : <CardLaunchIcon />}
</button>
<button
type="button"
@@ -3182,7 +3254,8 @@ export function AutoRunsHistoryPanel({
</>
) : null}
</article>
))}
);
})}
</div>
) : null}