Restore model interactions viewer (#10205)

Co-authored-by: Douwe M Osinga <douwe@sidewalklabs.com>
This commit is contained in:
Douwe Osinga
2026-07-17 13:21:43 +02:00
committed by GitHub
parent d3f170f188
commit b7c78623f4
17 changed files with 317 additions and 11 deletions
@@ -1,8 +1,17 @@
import { useCallback, useEffect, useMemo, useState, type KeyboardEvent } from 'react';
import { ChevronDown, ChevronRight, Copy, Edit2, FileJson, LoaderCircle } from 'lucide-react';
import { useCallback, useEffect, useMemo, useRef, useState, type KeyboardEvent } from 'react';
import {
Activity,
ChevronDown,
ChevronRight,
Copy,
Edit2,
FileJson,
LoaderCircle,
} from 'lucide-react';
import { toast } from 'react-toastify';
import { AppEvents } from '../constants/events';
import { defineMessages, useIntl } from '../i18n';
import { getDiagnosticsReport } from '../acp/diagnostics';
import { acpExportSession, acpForkSession, acpRenameSession } from '../acp/sessions';
import { getSessionDisplayName } from '../sessions';
import type { Session } from '../types/session';
@@ -34,6 +43,10 @@ const i18n = defineMessages({
id: 'sessionActionsHeader.viewJson',
defaultMessage: 'View session JSON',
},
viewModelInteractions: {
id: 'sessionActionsHeader.viewModelInteractions',
defaultMessage: 'View recent model interactions',
},
renameTitle: {
id: 'sessionActionsHeader.renameTitle',
defaultMessage: 'Rename Session',
@@ -74,6 +87,10 @@ const i18n = defineMessages({
id: 'sessionActionsHeader.jsonTitle',
defaultMessage: 'Session JSON',
},
modelInteractionsTitle: {
id: 'sessionActionsHeader.modelInteractionsTitle',
defaultMessage: 'Recent model interactions',
},
loadingJson: {
id: 'sessionActionsHeader.loadingJson',
defaultMessage: 'Loading JSON...',
@@ -82,6 +99,10 @@ const i18n = defineMessages({
id: 'sessionActionsHeader.jsonFailed',
defaultMessage: 'Failed to load session JSON: {error}',
},
modelInteractionsFailed: {
id: 'sessionActionsHeader.modelInteractionsFailed',
defaultMessage: 'Failed to load model interactions: {error}',
},
close: {
id: 'sessionActionsHeader.close',
defaultMessage: 'Close',
@@ -94,6 +115,10 @@ const i18n = defineMessages({
id: 'sessionActionsHeader.copiedJson',
defaultMessage: 'Session JSON copied',
},
copiedModelInteractions: {
id: 'sessionActionsHeader.copiedModelInteractions',
defaultMessage: 'Recent model interactions copied',
},
fullTextTitle: {
id: 'sessionActionsHeader.fullTextTitle',
defaultMessage: 'Text value',
@@ -128,6 +153,8 @@ interface FullTextSelection {
value: string;
}
type JsonDialogKind = 'session' | 'modelInteractions';
function parseSessionJson(json: string): ParsedSessionJson {
const value = JSON.parse(json) as unknown;
return {
@@ -136,6 +163,14 @@ function parseSessionJson(json: string): ParsedSessionJson {
};
}
function parseJsonLine(line: string): unknown {
try {
return JSON.parse(line) as unknown;
} catch {
return line;
}
}
function isJsonRecord(value: unknown): value is Record<string, unknown> {
return typeof value === 'object' && value !== null && !Array.isArray(value);
}
@@ -319,11 +354,14 @@ export default function SessionActionsHeader({
const [renameValue, setRenameValue] = useState('');
const [isRenaming, setIsRenaming] = useState(false);
const [isJsonOpen, setIsJsonOpen] = useState(false);
const [jsonDialogKind, setJsonDialogKind] = useState<JsonDialogKind>('session');
const [jsonValue, setJsonValue] = useState<unknown>(null);
const [jsonText, setJsonText] = useState('');
const [isJsonLoading, setIsJsonLoading] = useState(false);
const [isModelInteractionsLoading, setIsModelInteractionsLoading] = useState(false);
const [isDuplicating, setIsDuplicating] = useState(false);
const [fullTextSelection, setFullTextSelection] = useState<FullTextSelection | null>(null);
const jsonLoadRequestId = useRef(0);
const title = useMemo(() => (session ? getSessionDisplayName(session) : ''), [session]);
@@ -388,16 +426,21 @@ export default function SessionActionsHeader({
const handleViewJson = useCallback(async () => {
if (!session) return;
const loadRequestId = ++jsonLoadRequestId.current;
setIsJsonOpen(true);
setJsonDialogKind('session');
setJsonValue(null);
setJsonText('');
setIsModelInteractionsLoading(false);
setIsJsonLoading(true);
try {
const json = await acpExportSession(session.id);
const parsed = parseSessionJson(json);
if (jsonLoadRequestId.current !== loadRequestId) return;
setJsonValue(parsed.value);
setJsonText(parsed.pretty);
} catch (error) {
if (jsonLoadRequestId.current !== loadRequestId) return;
setIsJsonOpen(false);
toast.error(
intl.formatMessage(i18n.jsonFailed, {
@@ -405,15 +448,60 @@ export default function SessionActionsHeader({
})
);
} finally {
setIsJsonLoading(false);
if (jsonLoadRequestId.current === loadRequestId) {
setIsJsonLoading(false);
}
}
}, [intl, session]);
const handleViewModelInteractions = useCallback(async () => {
if (!session) return;
const loadRequestId = ++jsonLoadRequestId.current;
setIsJsonOpen(true);
setJsonDialogKind('modelInteractions');
setJsonValue(null);
setJsonText('');
setIsJsonLoading(false);
setIsModelInteractionsLoading(true);
try {
const report = await getDiagnosticsReport(session.id, 'full');
const interactions = report.logs.llm.map((log) => ({
path: log.path,
truncated: log.truncated,
entries: log.content
.split('\n')
.filter((line) => line.trim().length > 0)
.map(parseJsonLine),
}));
const text = JSON.stringify(interactions, null, 2);
if (jsonLoadRequestId.current !== loadRequestId) return;
setJsonValue(interactions);
setJsonText(text);
} catch (error) {
if (jsonLoadRequestId.current !== loadRequestId) return;
setIsJsonOpen(false);
toast.error(
intl.formatMessage(i18n.modelInteractionsFailed, {
error: errorMessage(error, 'Unknown error'),
})
);
} finally {
if (jsonLoadRequestId.current === loadRequestId) {
setIsModelInteractionsLoading(false);
}
}
}, [intl, session]);
const handleCopyJson = useCallback(async () => {
if (!jsonText) return;
await navigator.clipboard.writeText(jsonText);
toast.success(intl.formatMessage(i18n.copiedJson));
}, [intl, jsonText]);
toast.success(
intl.formatMessage(
jsonDialogKind === 'modelInteractions' ? i18n.copiedModelInteractions : i18n.copiedJson
)
);
}, [intl, jsonDialogKind, jsonText]);
const handleCopyFullText = useCallback(async () => {
if (!fullTextSelection) return;
@@ -424,6 +512,9 @@ export default function SessionActionsHeader({
const handleJsonOpenChange = useCallback((open: boolean) => {
setIsJsonOpen(open);
if (!open) {
jsonLoadRequestId.current += 1;
setIsJsonLoading(false);
setIsModelInteractionsLoading(false);
setFullTextSelection(null);
}
}, []);
@@ -441,11 +532,14 @@ export default function SessionActionsHeader({
return null;
}
const isDialogOpen = isRenameOpen || isJsonOpen || fullTextSelection !== null;
return (
<>
<div
className={cn(
'no-drag absolute top-[14px] left-1/2 z-30 max-w-[min(36rem,calc(100vw-13rem))] -translate-x-1/2',
'no-drag absolute top-[14px] left-1/2 max-w-[min(36rem,calc(100vw-13rem))] -translate-x-1/2',
isDialogOpen ? 'z-30' : 'z-50',
className
)}
>
@@ -453,7 +547,7 @@ export default function SessionActionsHeader({
<DropdownMenuTrigger asChild>
<button
type="button"
className="flex h-7 max-w-full items-center gap-1 rounded-md px-2.5 text-text-primary transition-colors hover:bg-background-secondary focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border-active"
className="no-drag flex h-7 max-w-full items-center gap-1 rounded-md px-2.5 text-text-primary transition-colors hover:bg-background-secondary focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border-active"
aria-label={intl.formatMessage(i18n.actionsLabel)}
>
<span className="truncate text-xs font-medium">{title}</span>
@@ -481,6 +575,14 @@ export default function SessionActionsHeader({
)}
{intl.formatMessage(i18n.viewJson)}
</DropdownMenuItem>
<DropdownMenuItem onSelect={() => void handleViewModelInteractions()}>
{isModelInteractionsLoading ? (
<LoaderCircle className="size-4 animate-spin" />
) : (
<Activity className="size-4" />
)}
{intl.formatMessage(i18n.viewModelInteractions)}
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
@@ -505,7 +607,10 @@ export default function SessionActionsHeader({
<Button variant="outline" onClick={() => setIsRenameOpen(false)} disabled={isRenaming}>
{intl.formatMessage(i18n.cancel)}
</Button>
<Button onClick={() => void handleRename()} disabled={isRenaming || !renameValue.trim()}>
<Button
onClick={() => void handleRename()}
disabled={isRenaming || !renameValue.trim()}
>
{isRenaming ? intl.formatMessage(i18n.saving) : intl.formatMessage(i18n.save)}
</Button>
</DialogFooter>
@@ -515,10 +620,16 @@ export default function SessionActionsHeader({
<Dialog open={isJsonOpen} onOpenChange={handleJsonOpenChange}>
<DialogContent className="grid max-h-[85vh] grid-rows-[auto_minmax(0,1fr)_auto] sm:max-w-4xl">
<DialogHeader>
<DialogTitle>{intl.formatMessage(i18n.jsonTitle)}</DialogTitle>
<DialogTitle>
{intl.formatMessage(
jsonDialogKind === 'modelInteractions'
? i18n.modelInteractionsTitle
: i18n.jsonTitle
)}
</DialogTitle>
</DialogHeader>
<div className="min-h-0 overflow-hidden rounded-lg border border-border-primary bg-background-secondary">
{isJsonLoading ? (
{isJsonLoading || isModelInteractionsLoading ? (
<div className="flex h-64 items-center justify-center gap-2 text-sm text-text-secondary">
<LoaderCircle className="size-4 animate-spin" />
{intl.formatMessage(i18n.loadingJson)}
@@ -533,7 +644,10 @@ export default function SessionActionsHeader({
<Button variant="outline" onClick={() => setIsJsonOpen(false)}>
{intl.formatMessage(i18n.close)}
</Button>
<Button onClick={() => void handleCopyJson()} disabled={!jsonText || isJsonLoading}>
<Button
onClick={() => void handleCopyJson()}
disabled={!jsonText || isJsonLoading || isModelInteractionsLoading}
>
{intl.formatMessage(i18n.copyJson)}
</Button>
</DialogFooter>
+12
View File
@@ -3662,6 +3662,9 @@
"sessionActionsHeader.copiedJson": {
"defaultMessage": "Sitzungs-JSON kopiert"
},
"sessionActionsHeader.copiedModelInteractions": {
"defaultMessage": "Recent model interactions copied"
},
"sessionActionsHeader.copiedText": {
"defaultMessage": "Text kopiert"
},
@@ -3692,6 +3695,12 @@
"sessionActionsHeader.loadingJson": {
"defaultMessage": "JSON wird geladen..."
},
"sessionActionsHeader.modelInteractionsFailed": {
"defaultMessage": "Failed to load model interactions: {error}"
},
"sessionActionsHeader.modelInteractionsTitle": {
"defaultMessage": "Recent model interactions"
},
"sessionActionsHeader.renameFailed": {
"defaultMessage": "Sitzung konnte nicht umbenannt werden: {error}"
},
@@ -3716,6 +3725,9 @@
"sessionActionsHeader.viewJson": {
"defaultMessage": "Sitzungs-JSON anzeigen"
},
"sessionActionsHeader.viewModelInteractions": {
"defaultMessage": "View recent model interactions"
},
"sessionIndicators.error": {
"defaultMessage": "In der Sitzung ist ein Fehler aufgetreten"
},
+12
View File
@@ -3662,6 +3662,9 @@
"sessionActionsHeader.copiedJson": {
"defaultMessage": "Session JSON copied"
},
"sessionActionsHeader.copiedModelInteractions": {
"defaultMessage": "Recent model interactions copied"
},
"sessionActionsHeader.copiedText": {
"defaultMessage": "Text copied"
},
@@ -3692,6 +3695,12 @@
"sessionActionsHeader.loadingJson": {
"defaultMessage": "Loading JSON..."
},
"sessionActionsHeader.modelInteractionsFailed": {
"defaultMessage": "Failed to load model interactions: {error}"
},
"sessionActionsHeader.modelInteractionsTitle": {
"defaultMessage": "Recent model interactions"
},
"sessionActionsHeader.renameFailed": {
"defaultMessage": "Failed to rename session: {error}"
},
@@ -3716,6 +3725,9 @@
"sessionActionsHeader.viewJson": {
"defaultMessage": "View session JSON"
},
"sessionActionsHeader.viewModelInteractions": {
"defaultMessage": "View recent model interactions"
},
"sessionIndicators.error": {
"defaultMessage": "Session encountered an error"
},
+12
View File
@@ -3662,6 +3662,9 @@
"sessionActionsHeader.copiedJson": {
"defaultMessage": "JSON de la sesión copiado"
},
"sessionActionsHeader.copiedModelInteractions": {
"defaultMessage": "Recent model interactions copied"
},
"sessionActionsHeader.copiedText": {
"defaultMessage": "Texto copiado"
},
@@ -3692,6 +3695,12 @@
"sessionActionsHeader.loadingJson": {
"defaultMessage": "Cargando JSON..."
},
"sessionActionsHeader.modelInteractionsFailed": {
"defaultMessage": "Failed to load model interactions: {error}"
},
"sessionActionsHeader.modelInteractionsTitle": {
"defaultMessage": "Recent model interactions"
},
"sessionActionsHeader.renameFailed": {
"defaultMessage": "No se pudo renombrar la sesión: {error}"
},
@@ -3716,6 +3725,9 @@
"sessionActionsHeader.viewJson": {
"defaultMessage": "Ver el JSON de la sesión"
},
"sessionActionsHeader.viewModelInteractions": {
"defaultMessage": "View recent model interactions"
},
"sessionIndicators.error": {
"defaultMessage": "La sesión encontró un error"
},
+12
View File
@@ -3662,6 +3662,9 @@
"sessionActionsHeader.copiedJson": {
"defaultMessage": "JSON de la session copié"
},
"sessionActionsHeader.copiedModelInteractions": {
"defaultMessage": "Recent model interactions copied"
},
"sessionActionsHeader.copiedText": {
"defaultMessage": "Texte copié"
},
@@ -3692,6 +3695,12 @@
"sessionActionsHeader.loadingJson": {
"defaultMessage": "Chargement du JSON..."
},
"sessionActionsHeader.modelInteractionsFailed": {
"defaultMessage": "Failed to load model interactions: {error}"
},
"sessionActionsHeader.modelInteractionsTitle": {
"defaultMessage": "Recent model interactions"
},
"sessionActionsHeader.renameFailed": {
"defaultMessage": "Échec du renommage de la session : {error}"
},
@@ -3716,6 +3725,9 @@
"sessionActionsHeader.viewJson": {
"defaultMessage": "Afficher le JSON de la session"
},
"sessionActionsHeader.viewModelInteractions": {
"defaultMessage": "View recent model interactions"
},
"sessionIndicators.error": {
"defaultMessage": "La session a rencontré une erreur"
},
+12
View File
@@ -3662,6 +3662,9 @@
"sessionActionsHeader.copiedJson": {
"defaultMessage": "Session JSON copied"
},
"sessionActionsHeader.copiedModelInteractions": {
"defaultMessage": "Recent model interactions copied"
},
"sessionActionsHeader.copiedText": {
"defaultMessage": "Text copied"
},
@@ -3692,6 +3695,12 @@
"sessionActionsHeader.loadingJson": {
"defaultMessage": "Loading JSON..."
},
"sessionActionsHeader.modelInteractionsFailed": {
"defaultMessage": "Failed to load model interactions: {error}"
},
"sessionActionsHeader.modelInteractionsTitle": {
"defaultMessage": "Recent model interactions"
},
"sessionActionsHeader.renameFailed": {
"defaultMessage": "Failed to rename session: {error}"
},
@@ -3716,6 +3725,9 @@
"sessionActionsHeader.viewJson": {
"defaultMessage": "View session JSON"
},
"sessionActionsHeader.viewModelInteractions": {
"defaultMessage": "View recent model interactions"
},
"sessionIndicators.error": {
"defaultMessage": "सत्र में एक त्रुटि आई"
},
+12
View File
@@ -3662,6 +3662,9 @@
"sessionActionsHeader.copiedJson": {
"defaultMessage": "JSON sesi disalin"
},
"sessionActionsHeader.copiedModelInteractions": {
"defaultMessage": "Recent model interactions copied"
},
"sessionActionsHeader.copiedText": {
"defaultMessage": "Teks disalin"
},
@@ -3692,6 +3695,12 @@
"sessionActionsHeader.loadingJson": {
"defaultMessage": "Memuat JSON..."
},
"sessionActionsHeader.modelInteractionsFailed": {
"defaultMessage": "Failed to load model interactions: {error}"
},
"sessionActionsHeader.modelInteractionsTitle": {
"defaultMessage": "Recent model interactions"
},
"sessionActionsHeader.renameFailed": {
"defaultMessage": "Gagal mengganti nama sesi: {error}"
},
@@ -3716,6 +3725,9 @@
"sessionActionsHeader.viewJson": {
"defaultMessage": "Lihat JSON sesi"
},
"sessionActionsHeader.viewModelInteractions": {
"defaultMessage": "View recent model interactions"
},
"sessionIndicators.error": {
"defaultMessage": "Sesi mengalami kesalahan"
},
+12
View File
@@ -3662,6 +3662,9 @@
"sessionActionsHeader.copiedJson": {
"defaultMessage": "JSON della sessione copiato"
},
"sessionActionsHeader.copiedModelInteractions": {
"defaultMessage": "Recent model interactions copied"
},
"sessionActionsHeader.copiedText": {
"defaultMessage": "Testo copiato"
},
@@ -3692,6 +3695,12 @@
"sessionActionsHeader.loadingJson": {
"defaultMessage": "Caricamento JSON..."
},
"sessionActionsHeader.modelInteractionsFailed": {
"defaultMessage": "Failed to load model interactions: {error}"
},
"sessionActionsHeader.modelInteractionsTitle": {
"defaultMessage": "Recent model interactions"
},
"sessionActionsHeader.renameFailed": {
"defaultMessage": "Impossibile rinominare la sessione: {error}"
},
@@ -3716,6 +3725,9 @@
"sessionActionsHeader.viewJson": {
"defaultMessage": "Visualizza JSON della sessione"
},
"sessionActionsHeader.viewModelInteractions": {
"defaultMessage": "View recent model interactions"
},
"sessionIndicators.error": {
"defaultMessage": "La sessione ha riscontrato un errore"
},
+12
View File
@@ -3662,6 +3662,9 @@
"sessionActionsHeader.copiedJson": {
"defaultMessage": "セッションJSONをコピーしました"
},
"sessionActionsHeader.copiedModelInteractions": {
"defaultMessage": "Recent model interactions copied"
},
"sessionActionsHeader.copiedText": {
"defaultMessage": "テキストをコピーしました"
},
@@ -3692,6 +3695,12 @@
"sessionActionsHeader.loadingJson": {
"defaultMessage": "JSONを読み込み中..."
},
"sessionActionsHeader.modelInteractionsFailed": {
"defaultMessage": "Failed to load model interactions: {error}"
},
"sessionActionsHeader.modelInteractionsTitle": {
"defaultMessage": "Recent model interactions"
},
"sessionActionsHeader.renameFailed": {
"defaultMessage": "セッションの名前を変更できませんでした: {error}"
},
@@ -3716,6 +3725,9 @@
"sessionActionsHeader.viewJson": {
"defaultMessage": "セッションJSONを表示"
},
"sessionActionsHeader.viewModelInteractions": {
"defaultMessage": "View recent model interactions"
},
"sessionIndicators.error": {
"defaultMessage": "セッションでエラーが発生しました"
},
+12
View File
@@ -3662,6 +3662,9 @@
"sessionActionsHeader.copiedJson": {
"defaultMessage": "세션 JSON 복사됨"
},
"sessionActionsHeader.copiedModelInteractions": {
"defaultMessage": "Recent model interactions copied"
},
"sessionActionsHeader.copiedText": {
"defaultMessage": "텍스트가 복사되었습니다."
},
@@ -3692,6 +3695,12 @@
"sessionActionsHeader.loadingJson": {
"defaultMessage": "JSON 불러오는 중..."
},
"sessionActionsHeader.modelInteractionsFailed": {
"defaultMessage": "Failed to load model interactions: {error}"
},
"sessionActionsHeader.modelInteractionsTitle": {
"defaultMessage": "Recent model interactions"
},
"sessionActionsHeader.renameFailed": {
"defaultMessage": "세션 이름 변경 실패: {error}"
},
@@ -3716,6 +3725,9 @@
"sessionActionsHeader.viewJson": {
"defaultMessage": "세션 JSON 보기"
},
"sessionActionsHeader.viewModelInteractions": {
"defaultMessage": "View recent model interactions"
},
"sessionIndicators.error": {
"defaultMessage": "세션에 오류가 발생했습니다."
},
+12
View File
@@ -3662,6 +3662,9 @@
"sessionActionsHeader.copiedJson": {
"defaultMessage": "JSON sesi disalin"
},
"sessionActionsHeader.copiedModelInteractions": {
"defaultMessage": "Recent model interactions copied"
},
"sessionActionsHeader.copiedText": {
"defaultMessage": "Teks disalin"
},
@@ -3692,6 +3695,12 @@
"sessionActionsHeader.loadingJson": {
"defaultMessage": "Memuatkan JSON..."
},
"sessionActionsHeader.modelInteractionsFailed": {
"defaultMessage": "Failed to load model interactions: {error}"
},
"sessionActionsHeader.modelInteractionsTitle": {
"defaultMessage": "Recent model interactions"
},
"sessionActionsHeader.renameFailed": {
"defaultMessage": "Gagal menamakan semula sesi: {error}"
},
@@ -3716,6 +3725,9 @@
"sessionActionsHeader.viewJson": {
"defaultMessage": "Lihat JSON sesi"
},
"sessionActionsHeader.viewModelInteractions": {
"defaultMessage": "View recent model interactions"
},
"sessionIndicators.error": {
"defaultMessage": "Sesi mengalami ralat"
},
+12
View File
@@ -3662,6 +3662,9 @@
"sessionActionsHeader.copiedJson": {
"defaultMessage": "JSON da sessão copiado"
},
"sessionActionsHeader.copiedModelInteractions": {
"defaultMessage": "Recent model interactions copied"
},
"sessionActionsHeader.copiedText": {
"defaultMessage": "Texto copiado"
},
@@ -3692,6 +3695,12 @@
"sessionActionsHeader.loadingJson": {
"defaultMessage": "A carregar JSON..."
},
"sessionActionsHeader.modelInteractionsFailed": {
"defaultMessage": "Failed to load model interactions: {error}"
},
"sessionActionsHeader.modelInteractionsTitle": {
"defaultMessage": "Recent model interactions"
},
"sessionActionsHeader.renameFailed": {
"defaultMessage": "Falha ao renomear a sessão: {error}"
},
@@ -3716,6 +3725,9 @@
"sessionActionsHeader.viewJson": {
"defaultMessage": "Ver JSON da sessão"
},
"sessionActionsHeader.viewModelInteractions": {
"defaultMessage": "View recent model interactions"
},
"sessionIndicators.error": {
"defaultMessage": "A sessão encontrou um erro"
},
+12
View File
@@ -3662,6 +3662,9 @@
"sessionActionsHeader.copiedJson": {
"defaultMessage": "Session JSON copied"
},
"sessionActionsHeader.copiedModelInteractions": {
"defaultMessage": "Recent model interactions copied"
},
"sessionActionsHeader.copiedText": {
"defaultMessage": "Text copied"
},
@@ -3692,6 +3695,12 @@
"sessionActionsHeader.loadingJson": {
"defaultMessage": "Loading JSON..."
},
"sessionActionsHeader.modelInteractionsFailed": {
"defaultMessage": "Failed to load model interactions: {error}"
},
"sessionActionsHeader.modelInteractionsTitle": {
"defaultMessage": "Recent model interactions"
},
"sessionActionsHeader.renameFailed": {
"defaultMessage": "Failed to rename session: {error}"
},
@@ -3716,6 +3725,9 @@
"sessionActionsHeader.viewJson": {
"defaultMessage": "View session JSON"
},
"sessionActionsHeader.viewModelInteractions": {
"defaultMessage": "View recent model interactions"
},
"sessionIndicators.error": {
"defaultMessage": "В сеансе возникла ошибка"
},
+12
View File
@@ -3662,6 +3662,9 @@
"sessionActionsHeader.copiedJson": {
"defaultMessage": "Session JSON copied"
},
"sessionActionsHeader.copiedModelInteractions": {
"defaultMessage": "Recent model interactions copied"
},
"sessionActionsHeader.copiedText": {
"defaultMessage": "Text copied"
},
@@ -3692,6 +3695,12 @@
"sessionActionsHeader.loadingJson": {
"defaultMessage": "Loading JSON..."
},
"sessionActionsHeader.modelInteractionsFailed": {
"defaultMessage": "Failed to load model interactions: {error}"
},
"sessionActionsHeader.modelInteractionsTitle": {
"defaultMessage": "Recent model interactions"
},
"sessionActionsHeader.renameFailed": {
"defaultMessage": "Failed to rename session: {error}"
},
@@ -3716,6 +3725,9 @@
"sessionActionsHeader.viewJson": {
"defaultMessage": "View session JSON"
},
"sessionActionsHeader.viewModelInteractions": {
"defaultMessage": "View recent model interactions"
},
"sessionIndicators.error": {
"defaultMessage": "Oturum bir hatayla karşılaştı"
},
+12
View File
@@ -3662,6 +3662,9 @@
"sessionActionsHeader.copiedJson": {
"defaultMessage": "Đã sao chép JSON của phiên"
},
"sessionActionsHeader.copiedModelInteractions": {
"defaultMessage": "Recent model interactions copied"
},
"sessionActionsHeader.copiedText": {
"defaultMessage": "Đã sao chép văn bản"
},
@@ -3692,6 +3695,12 @@
"sessionActionsHeader.loadingJson": {
"defaultMessage": "Đang tải JSON..."
},
"sessionActionsHeader.modelInteractionsFailed": {
"defaultMessage": "Failed to load model interactions: {error}"
},
"sessionActionsHeader.modelInteractionsTitle": {
"defaultMessage": "Recent model interactions"
},
"sessionActionsHeader.renameFailed": {
"defaultMessage": "Không thể đổi tên phiên: {error}"
},
@@ -3716,6 +3725,9 @@
"sessionActionsHeader.viewJson": {
"defaultMessage": "Xem JSON của phiên"
},
"sessionActionsHeader.viewModelInteractions": {
"defaultMessage": "View recent model interactions"
},
"sessionIndicators.error": {
"defaultMessage": "Phiên gặp lỗi"
},
+12
View File
@@ -3662,6 +3662,9 @@
"sessionActionsHeader.copiedJson": {
"defaultMessage": "Session JSON copied"
},
"sessionActionsHeader.copiedModelInteractions": {
"defaultMessage": "Recent model interactions copied"
},
"sessionActionsHeader.copiedText": {
"defaultMessage": "Text copied"
},
@@ -3692,6 +3695,12 @@
"sessionActionsHeader.loadingJson": {
"defaultMessage": "Loading JSON..."
},
"sessionActionsHeader.modelInteractionsFailed": {
"defaultMessage": "Failed to load model interactions: {error}"
},
"sessionActionsHeader.modelInteractionsTitle": {
"defaultMessage": "Recent model interactions"
},
"sessionActionsHeader.renameFailed": {
"defaultMessage": "Failed to rename session: {error}"
},
@@ -3716,6 +3725,9 @@
"sessionActionsHeader.viewJson": {
"defaultMessage": "View session JSON"
},
"sessionActionsHeader.viewModelInteractions": {
"defaultMessage": "View recent model interactions"
},
"sessionIndicators.error": {
"defaultMessage": "会话发生错误"
},
+12
View File
@@ -3662,6 +3662,9 @@
"sessionActionsHeader.copiedJson": {
"defaultMessage": "工作階段 JSON 已複製"
},
"sessionActionsHeader.copiedModelInteractions": {
"defaultMessage": "Recent model interactions copied"
},
"sessionActionsHeader.copiedText": {
"defaultMessage": "文字已複製"
},
@@ -3692,6 +3695,12 @@
"sessionActionsHeader.loadingJson": {
"defaultMessage": "正在載入 JSON…"
},
"sessionActionsHeader.modelInteractionsFailed": {
"defaultMessage": "Failed to load model interactions: {error}"
},
"sessionActionsHeader.modelInteractionsTitle": {
"defaultMessage": "Recent model interactions"
},
"sessionActionsHeader.renameFailed": {
"defaultMessage": "重新命名工作階段失敗:{error}"
},
@@ -3716,6 +3725,9 @@
"sessionActionsHeader.viewJson": {
"defaultMessage": "檢視工作階段 JSON"
},
"sessionActionsHeader.viewModelInteractions": {
"defaultMessage": "View recent model interactions"
},
"sessionIndicators.error": {
"defaultMessage": "工作階段發生錯誤"
},