ГЛОБАЛЬНЫЙ РЕФАКТОРИНГ АРХИТЕКТУРЫ - Спека exact-маршрута payables на дату: confirmed_balance без эвристического финала

This commit is contained in:
2026-04-12 13:46:14 +03:00
parent ca2feab893
commit 1b2ee93176
19 changed files with 2453 additions and 252 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -4,7 +4,7 @@
<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-B_Dz87Mp.js"></script>
<script type="module" crossorigin src="/assets/index-CVIU9teH.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-D4dtBq8A.css">
</head>
<body>
@@ -141,6 +141,24 @@ interface AutoRunsUiConfig {
hideResolvedAnnotations?: boolean;
}
type UnifiedCommentListItem =
| {
source: "autorun";
key: string;
updated_at: string;
rating: number;
autorun: AutoRunAnnotationListItem;
assistant: null;
}
| {
source: "assistant_live";
key: string;
updated_at: string;
rating: number;
autorun: null;
assistant: AssistantAnnotationRecord;
};
const DEFAULT_AUTOGEN_SETTINGS: AutoGenSettingsState = {
mode: "codex_creative",
count: 24,
@@ -557,11 +575,31 @@ export function AutoRunsHistoryPanel({
return null;
}, [assistantLiveCommentModal.messageIndex, assistantLiveConversation]);
const unifiedVisibleAnnotations = useMemo<UnifiedCommentListItem[]>(() => {
const autorunItems: UnifiedCommentListItem[] = visibleAnnotations.map((item) => ({
source: "autorun",
key: `autorun:${item.annotation_id}`,
updated_at: item.updated_at,
rating: item.rating,
autorun: item,
assistant: null
}));
const assistantItems: UnifiedCommentListItem[] = assistantLiveAnnotations.map((item) => ({
source: "assistant_live",
key: `assistant:${item.annotation_id}`,
updated_at: item.updated_at,
rating: item.rating,
autorun: null,
assistant: item
}));
return [...autorunItems, ...assistantItems].sort((left, right) => Date.parse(right.updated_at) - Date.parse(left.updated_at));
}, [assistantLiveAnnotations, visibleAnnotations]);
const annotationsAverageRating = useMemo(() => {
if (visibleAnnotations.length === 0) return null;
const avg = visibleAnnotations.reduce((acc, item) => acc + item.rating, 0) / visibleAnnotations.length;
if (unifiedVisibleAnnotations.length === 0) return null;
const avg = unifiedVisibleAnnotations.reduce((acc, item) => acc + item.rating, 0) / unifiedVisibleAnnotations.length;
return Number(avg.toFixed(2));
}, [visibleAnnotations]);
}, [unifiedVisibleAnnotations]);
const runSelectItems = useMemo(() => {
const list = [...(history?.items ?? [])];
@@ -2411,7 +2449,7 @@ export function AutoRunsHistoryPanel({
<div className="autoruns-stats-grid">
<div>
<span>Комментариев</span>
<strong>{visibleAnnotations.length}</strong>
<strong>{unifiedVisibleAnnotations.length}</strong>
</div>
<div>
<span>Средний рейтинг</span>
@@ -2419,7 +2457,9 @@ export function AutoRunsHistoryPanel({
</div>
<div>
<span>Последний</span>
<strong>{visibleAnnotations.length > 0 ? formatDateTime(visibleAnnotations[0].updated_at) : "нет данных"}</strong>
<strong>
{unifiedVisibleAnnotations.length > 0 ? formatDateTime(unifiedVisibleAnnotations[0].updated_at) : "нет данных"}
</strong>
</div>
<div>
<span>Статус</span>
@@ -2438,74 +2478,99 @@ export function AutoRunsHistoryPanel({
<div className="autoruns-comments-list">
{annotationsBusy ? <p className="muted">Загружаю комментарии...</p> : null}
{!annotationsBusy && visibleAnnotations.length === 0 ? (
{!annotationsBusy && unifiedVisibleAnnotations.length === 0 ? (
<p className="muted">
{annotations.length === 0
{annotations.length === 0 && assistantLiveAnnotations.length === 0
? "Пока нет откомментированных ответов."
: "\u041d\u0435\u0442 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u0445 \u043a\u0435\u0439\u0441\u043e\u0432 \u043f\u043e \u0442\u0435\u043a\u0443\u0449\u0435\u043c\u0443 \u0444\u0438\u043b\u044c\u0442\u0440\u0443."}
</p>
) : null}
{visibleAnnotations.map((item) => (
<article
key={item.annotation_id}
className={selectedAnnotationId === item.annotation_id ? "autoruns-comment-item selected" : "autoruns-comment-item"}
onClick={() => void openAnnotationContext(item)}
role="button"
tabIndex={0}
onKeyDown={(event) => {
if (event.key === "Enter" || event.key === " ") {
event.preventDefault();
void openAnnotationContext(item);
}
}}
>
<div className="autoruns-comment-head">
<strong>{renderRatingDots(item.rating)}</strong>
<div className="autoruns-comment-head-actions">
<span>{formatDateTime(item.updated_at)}</span>
<button
type="button"
className={item.resolved ? "autoruns-resolve-toggle resolved" : "autoruns-resolve-toggle"}
onClick={(event) => {
event.preventDefault();
event.stopPropagation();
void toggleAnnotationResolved(item, !item.resolved);
}}
disabled={annotationResolutionBusyId === item.annotation_id}
title={
item.resolved
? "\u041e\u0442\u043c\u0435\u0442\u0438\u0442\u044c \u043a\u0435\u0439\u0441 \u043a\u0430\u043a \u043d\u0435\u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u0439"
: "\u041e\u0442\u043c\u0435\u0442\u0438\u0442\u044c \u043a\u0435\u0439\u0441 \u043a\u0430\u043a \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u0439"
}
aria-label={
item.resolved
? "\u041e\u0442\u043c\u0435\u0442\u0438\u0442\u044c \u043a\u0435\u0439\u0441 \u043a\u0430\u043a \u043d\u0435\u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u0439"
: "\u041e\u0442\u043c\u0435\u0442\u0438\u0442\u044c \u043a\u0435\u0439\u0441 \u043a\u0430\u043a \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u0439"
}
>
<CommentResolvedIcon resolved={item.resolved} />
</button>
{unifiedVisibleAnnotations.map((item) => {
if (item.source === "assistant_live") {
const annotation = item.assistant;
return (
<article key={item.key} className="autoruns-comment-item">
<div className="autoruns-comment-head">
<strong>{renderRatingDots(annotation.rating)}</strong>
<div className="autoruns-comment-head-actions">
<span>{formatDateTime(annotation.updated_at)}</span>
</div>
</div>
<div className="autoruns-run-meta">live-session: {annotation.session_id}</div>
<div className="autoruns-run-meta">msg={annotation.message_index}</div>
<div className="autoruns-run-meta">
source=assistant_live
{annotation.annotation_author ? ` | author=${annotation.annotation_author}` : ""}
</div>
{annotation.context.question_text ? <p>Q: {annotation.context.question_text}</p> : null}
{annotation.context.answer_text ? <p>A: {annotation.context.answer_text}</p> : null}
<p>{annotation.comment}</p>
</article>
);
}
const annotation = item.autorun;
return (
<article
key={item.key}
className={selectedAnnotationId === annotation.annotation_id ? "autoruns-comment-item selected" : "autoruns-comment-item"}
onClick={() => void openAnnotationContext(annotation)}
role="button"
tabIndex={0}
onKeyDown={(event) => {
if (event.key === "Enter" || event.key === " ") {
event.preventDefault();
void openAnnotationContext(annotation);
}
}}
>
<div className="autoruns-comment-head">
<strong>{renderRatingDots(annotation.rating)}</strong>
<div className="autoruns-comment-head-actions">
<span>{formatDateTime(annotation.updated_at)}</span>
<button
type="button"
className={annotation.resolved ? "autoruns-resolve-toggle resolved" : "autoruns-resolve-toggle"}
onClick={(event) => {
event.preventDefault();
event.stopPropagation();
void toggleAnnotationResolved(annotation, !annotation.resolved);
}}
disabled={annotationResolutionBusyId === annotation.annotation_id}
title={
annotation.resolved
? "\u041e\u0442\u043c\u0435\u0442\u0438\u0442\u044c \u043a\u0435\u0439\u0441 \u043a\u0430\u043a \u043d\u0435\u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u0439"
: "\u041e\u0442\u043c\u0435\u0442\u0438\u0442\u044c \u043a\u0435\u0439\u0441 \u043a\u0430\u043a \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u0439"
}
aria-label={
annotation.resolved
? "\u041e\u0442\u043c\u0435\u0442\u0438\u0442\u044c \u043a\u0435\u0439\u0441 \u043a\u0430\u043a \u043d\u0435\u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u0439"
: "\u041e\u0442\u043c\u0435\u0442\u0438\u0442\u044c \u043a\u0435\u0439\u0441 \u043a\u0430\u043a \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u0439"
}
>
<CommentResolvedIcon resolved={annotation.resolved} />
</button>
</div>
</div>
</div>
<div className="autoruns-run-meta">{item.run_id}</div>
<div className="autoruns-run-meta">
case={item.case_id} | msg={item.message_index}
</div>
<div className="autoruns-run-meta">
decision={item.manual_case_decision}
{item.annotation_author ? ` | author=${item.annotation_author}` : ""}
</div>
{item.resolved_at ? (
<div className="autoruns-run-meta">{annotation.run_id}</div>
<div className="autoruns-run-meta">
{"\u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043e"}: {formatDateTime(item.resolved_at)}
{item.resolved_by ? ` | by=${item.resolved_by}` : ""}
case={annotation.case_id} | msg={annotation.message_index}
</div>
) : null}
{item.context.question_text ? <p>Q: {item.context.question_text}</p> : null}
{item.context.answer_text ? <p>A: {item.context.answer_text}</p> : null}
<p>{item.comment}</p>
</article>
))}
<div className="autoruns-run-meta">
decision={annotation.manual_case_decision}
{annotation.annotation_author ? ` | author=${annotation.annotation_author}` : ""}
</div>
{annotation.resolved_at ? (
<div className="autoruns-run-meta">
{"\u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043e"}: {formatDateTime(annotation.resolved_at)}
{annotation.resolved_by ? ` | by=${annotation.resolved_by}` : ""}
</div>
) : null}
{annotation.context.question_text ? <p>Q: {annotation.context.question_text}</p> : null}
{annotation.context.answer_text ? <p>A: {annotation.context.answer_text}</p> : null}
<p>{annotation.comment}</p>
</article>
);
})}
</div>
{selectedAnnotation ? (
@@ -2574,7 +2639,7 @@ export function AutoRunsHistoryPanel({
>
<div className="autoruns-comment-modal">
<h3>Комментарий к ответу ассистента</h3>
<p className="muted">Комментарий сохраняется отдельно от комментариев автопрогонов.</p>
<p className="muted">Комментарий будет добавлен в общий список комментариев справа с меткой `assistant_live`.</p>
{assistantLiveCommentModalQuestion ? (
<details className="autoruns-prompt-details" open>