Цифровые двойники

Создавайте цифровые копии людей и общайтесь с ними

Создать персону

Загрузите экспорт из Telegram, текстовые файлы или аудиозаписи

📋

Мои персоны

Редактируйте, загружайте данные, запускайте синтез и проверку

💬

Чат

Общайтесь с двойниками — они говорят, думают и молчат как настоящие

📖

Инструкция

Как создать двойника шаг за шагом, какие данные грузить и как выгрузить чат из Telegram

Загрузка руководства...
Загрузка...
{{ (p.name || '?')[0].toUpperCase() }}
{{ p.name }}
{{ statusLabel(p.status) }}
Полнота {{ p.completeness }}%
🎭

У вас ещё нет персон

{{ (currentPersona.name || '?')[0].toUpperCase() }}

{{ currentPersona.name }}

{{ statusLabel(currentPersona.status) }} Полнота: {{ currentPersona.completeness }}% 👤 {{ currentPersona.ownerName }}
📋 Обзор персоны
Полнота
{{ currentPersona.completeness }}%
Статус
{{ statusLabel(currentPersona.status) }}
Точность тестов
{{ analysisData.last_test_accuracy }}%
Чанков
{{ chunksData.stats.total }}

⚡ Быстрые действия

Главные операции с персоной.

📥 Данные и материалы

📤 Загрузка данных

Чем больше данных, тем точнее двойник. Загружайте экспорты из Telegram, тексты, аудио.

📁

Перетащите файлы или нажмите для выбора

Telegram JSON, TXT, MD, MP3, OGG, WAV, JPG, PNG

Файл отправлен. Обработка идёт в фоне...
{{ r.name }} {{ r.completenessAfter || 0 }}%
Полнота: {{ r.completenessBefore }}% → {{ r.completenessAfter }}% (+{{ r.completenessAfter - r.completenessBefore }}%)
{{ layer.label }} +{{ layer.added }} {{ layer.completeness }}%
Фрагментов: {{ r.stats.results || 0 }}, экстракций: {{ r.stats.extractions || 0 }}

📂 Файлы персоны

{{ showFiles ? '▲' : '▼' }}
{{ dir }} ({{ personaFiles[dir] ? personaFiles[dir].length : 0 }})
{{ f.name }} {{ f.sizeHuman }}
{{ f._open ? '▲' : '▼' }}
Загрузка...
{{ f._content }}
Пустой файл
Нет файлов в этой папке
🧠 Слои персоны

⚙️ Настройки персоны

{{ showSettings ? '▲' : '▼' }}
Подмешивать в каждый ответ 3-5 релевантных фрагментов из реальной речи персоны. Требует пройденного чанкинга.
При синтезе добавляет блок «Структурные связи в моём мышлении» с ядром связей, эволюцией взглядов и cross-layer мостами. Требует построенного графа.
Влияет на тон и длину реплик в чате, не меняет позиции и ценности.
Двойник запоминает факты о тебе из предыдущих разговоров (имя, проекты, предпочтения) и использует их в новых чатах. После каждого ответа извлекаются новые факты через мини-LLM-вызов.
Темы — результат TopicClusterer из анализа. Гибрид даёт буст чанкам, найденным несколькими способами.
QMD требует установленного qmd на сервере и автоматической индексации после chunking. TF-IDF — fallback по умолчанию.
Если выбрать — синтез будет динамически собирать промпт по приоритетам слоёв, чтобы уложиться в бюджет. Покажет карту отбора: что попало, что пропущено.
📋 Последняя сборка: {{ analysisData.last_assembly.preset || 'custom' }} ({{ analysisData.last_assembly.total_tokens }} / {{ analysisData.last_assembly.budget }} токенов)
Включено ({{ analysisData.last_assembly.included.length }}):
[{{ b.tokens }}t] {{ b.name }}
Пропущено ({{ analysisData.last_assembly.skipped.length }}):
[{{ b.tokens }}t] {{ b.name }} — {{ b.reason }}
{{ lbl }}
✓ Сохранено

Скопировать настройки с другой персоны

Настройки исходной персоны перезапишут текущие. Что именно скопировать — выбери ниже.

📊 Грани личности

{{ layer.label }} {{ layer.completeness }}%

Фактов: {{ layer.data ? Object.keys(layer.data).length : 0 }} Пробелов: {{ layer.gaps.length }}
{{ factKey.replace(/_/g, ' ') }}: {{ typeof val === 'object' ? (Array.isArray(val) ? val.join(', ').substring(0,100) : JSON.stringify(val).substring(0,100)) : String(val).substring(0,100) }}{{ (typeof val === 'string' && val.length > 100) || (typeof val === 'object' && JSON.stringify(val).length > 100) ? '…' : '' }}
Все факты ({{ Object.keys(layer.data).length }}) →
Нет данных

🔍 Ревизия данных

Поиск дубликатов, противоречий, мусорных записей и неправильно размещённых данных.

Объединения: {{ reviewResult.stats.merge || 0 }} Исправления: {{ reviewResult.stats.fix || 0 }} Переносы: {{ reviewResult.stats.move || 0 }} Удаления: {{ reviewResult.stats.delete || 0 }}
✓ Данные чистые — проблем не найдено
{{ {merge:'Объединить', fix:'Исправить', move:'Перенести', delete:'Удалить', rename:'Переименовать'}[p.type] || p.type }} {{ p.priority }}
{{ p.reason }}
Сейчас: {{ typeof p.current_value === 'object' ? JSON.stringify(p.current_value).substring(0,200) : String(p.current_value).substring(0,200) }}
Исправить на: {{ typeof p.proposed_value === 'object' ? JSON.stringify(p.proposed_value).substring(0,200) : String(p.proposed_value).substring(0,200) }}
Итого: {{ typeof p.target_value === 'object' ? JSON.stringify(p.target_value).substring(0,200) : String(p.target_value).substring(0,200) }}
Новый ключ: {{ p.target_key }}
{{ k }}: {{ personaLayers[p.layer] && personaLayers[p.layer].data && personaLayers[p.layer].data[k] ? (typeof personaLayers[p.layer].data[k] === 'object' ? JSON.stringify(personaLayers[p.layer].data[k]).substring(0,120) : String(personaLayers[p.layer].data[k]).substring(0,120)) : '—' }}
Новая структура:
{{ key }}: {{ typeof val === 'object' ? JSON.stringify(val).substring(0,200) : String(val).substring(0,200) }}
✓ Применено

🎤 Интервью

Ответьте на вопросы ИИ-интервьюера, чтобы заполнить пробелы в данных персоны.

🎙 Голосовой режим недоступен — не настроен OPENAI_API_KEY на сервере.
Вопрос #{{ interviewQuestionCount }} · Полнота: {{ currentPersona.completeness }}%
{{ m.text }}
{{ playerFormatTime(player.currentTime) }} {{ formatTime(player.duration) }}
✓ Извлечено: {{ interviewLastExtracted.join('; ') }}
{{ voiceRecording ? 'Говорите, потом нажмите «Стоп»' : 'Нажмите и говорите голосом' }}
📦 Чанки корпуса

Разбивка исходных материалов персоны на смысловые чанки с автоматической атрибуцией (кто говорит) и оценкой содержательности. Основа для Этапа 3 архитектуры.

Всего
{{ chunksData.stats.total }}
85+ (отлично)
{{ chunksData.stats.by_score.excellent }}
70-84 (хорошо)
{{ chunksData.stats.by_score.good }}
<70 (слабо)
{{ chunksData.stats.by_score.weak }}
Ср. score
{{ chunksData.stats.avg_score }}
{{ chunkAttributionLabel(attr) }}: {{ count }}
Атрибуция:
Score:
{{ chunkFilterMinScore }}–{{ chunkFilterMaxScore }}
Чанки ещё не созданы. Нажмите «Запустить чанкинг».
{{ c.chunkId }} {{ chunkAttributionLabel(c.attribution) }} {{ c.score }} {{ c.charCount }} симв {{ c.source.file }}
{{ c.text }}
⚠ {{ f }}
{{ ['qa','tests'].includes(analysisTab) ? '🧪' : '🔬' }} {{ ['qa','tests'].includes(analysisTab) ? 'Тестирование' : 'Анализ корпуса' }}

Извлечение контринтуитивных позиций, речевого стиля, anti-markers и эталонных вопросов. Тестирование двойника с LLM-вердиктами и автоматическими рекомендациями.

🗺 Сущности ({{ entitiesTotal }})
🎯 Темы ({{ analysisData.topics && analysisData.topics.topics ? analysisData.topics.topics.length : 0 }})
⏳ Временная ось ({{ analysisData.temporal && analysisData.temporal.eras ? analysisData.temporal.eras.length : 0 }})
📌 Позиции ({{ analysisData.positions ? analysisData.positions.length : 0 }})
⚡ Контринтуитивные ({{ analysisData.contrarians ? analysisData.contrarians.length : 0 }})
📖 Глоссарий ({{ analysisData.glossary ? analysisData.glossary.length : 0 }})
🎤 Стиль + anti-markers
❓ Reference QA ({{ analysisData.reference_qa && analysisData.reference_qa.qa ? analysisData.reference_qa.qa.length : 0 }})
🧪 Результаты тестов {{ analysisData.last_test_accuracy }}%
🕸 Граф знаний ({{ graphData.nodes.length }}/{{ graphData.edges.length }})
Данные анализа ещё не получены. Нажмите «Запустить анализ».
Карта сущностей ещё не извлечена. Запустите анализ.
{{ cat.label }} ({{ analysisData.entities[cat.key].length }})
{{ e.name }} {{ e.importance }} {{ e.frequency }} {{ e.role }} {{ e.relation }} {{ e.type }}
также: {{ a }}
{{ e.context }}
Временная ось ещё не построена. Запустите анализ.
📅 Интерактивный таймлайн
🗂️ Карточки
Категории: {{ cat.icon }} {{ cat.label }} ({{ temporalCountByCategory(cat.value) }})
🖱️ Перетаскивай для прокрутки · колесо мыши = zoom · клик по элементу = детали
{{ visSelectedItem.label }}
{{ visSelectedItem.kind === 'event' ? '⭐ Событие' : '📅 Период' }} · {{ temporalCategoryLabel(visSelectedItem.category) }} · {{ visSelectedItem.when_hint }}
{{ visSelectedItem.description }}
⭐ Ключевые события-вехи
{{ temporalCategoryIcon(ev.category) }} {{ ev.label }} ●●● ●●
{{ ev.when_hint }}
{{ ev.description }}
🔄 Ключевые переходы (что менялось во мне)
{{ temporalEraLabel(ev.from_era) }} {{ temporalEraLabel(ev.to_era) }}
{{ ev.description }}
Темы корпуса ещё не извлечены. Запустите анализ.
{{ analysisData.topics.empty_reason }}
Кластеризовано {{ analysisData.topics.total_clustered || 0 }} из {{ analysisData.topics.total_sampled || 0 }} репрезентативных чанков в {{ analysisData.topics.topics.length }} смысловых тем
#{{ ti + 1 }} {{ t.label }} {{ t.chunk_count }} чанков ⌀ {{ t.avg_score }}
{{ t.description }}
{{ kw }}
Примеры чанков ({{ t.representative_quotes.length }})
«{{ q }}»
Ядро позиций ещё не извлечено. Запустите анализ.
#{{ pi + 1 }} {{ p.confidence }} ×{{ p.frequency }} {{ p.topic }} {{ p.layer }}
{{ p.position }}
Цитата: «{{ p.source_quote }}»
Контринтуитивные позиции не найдены. Запустите анализ.
{{ contrarianStrengthLabel(c.strength) }} {{ c.confidence }} {{ contrarianCategoryLabel(c.category) }} {{ c.layer }}
Моя позиция: {{ c.expert_position }}
Большинство считает: {{ c.mainstream_view }}
Почему контринтуитивно: {{ c.reasoning }}
Цитата из корпуса: «{{ c.source_quote }}»
Стилевой профиль ещё не извлечён. Запустите анализ.
Характерные обороты:
{{ p.text }} — {{ p.description }}
Как рассуждает:
{{ analysisData.style_profile.argumentation }}
Регистр:
{{ analysisData.style_profile.register }}
🚫 Запрещённые паттерны:
  • {{ f }}
⛔ Anti-markers (никогда не произносить):
«{{ a }}»
Глоссарий ещё не извлечён. Запустите анализ.
{{ glossaryCategoryLabel(cat) }}
{{ g.term }} ×{{ g.frequency }}
{{ g.definition }}
«{{ g.usage_example }}»
Эталонные Q/A ещё не сгенерированы. Запустите анализ.
Всего: {{ analysisData.reference_qa.counts.total || 0 }} Core: {{ analysisData.reference_qa.counts.core_position || 0 }} Contrarian: {{ analysisData.reference_qa.counts.contrarian || 0 }} Boundary: {{ analysisData.reference_qa.counts.boundary || 0 }}
{{ qi + 1 }}. {{ q.question }} {{ q.category }}
{{ q.expected_answer }}
Keywords: {{ q.expected_keywords.join(', ') }}
Тестовые прогоны ещё не выполнялись. Нажмите «Прогнать тесты».
Точность
{{ analysisData.last_test.metrics.accuracy_pct }}%
GOOD
{{ analysisData.last_test.metrics.good }}
PARTIAL
{{ analysisData.last_test.metrics.partial }}
POOR
{{ analysisData.last_test.metrics.poor }}
META LEAKS
{{ analysisData.last_test.metrics.meta_leaks }}
STYLOMETRY
{{ (analysisData.last_test.metrics.stylometry_avg * 100).toFixed(0) }}%
📌 Регрессионные снимки:
Снимков: {{ regressionSnapshots.length }}
{{ s.created_at ? new Date(s.created_at * 1000).toLocaleString('ru') : '—' }} · точность {{ s.metrics?.accuracy_pct }}% · {{ s.items_count }} вопросов
📊 Сравнение со снимком {{ regressionDiff.snapshot_at ? new Date(regressionDiff.snapshot_at * 1000).toLocaleDateString('ru') : '' }}
Точность: {{ regressionDiff.accuracy_delta > 0 ? '+' : '' }}{{ regressionDiff.accuracy_delta }}% Stylometry: {{ regressionDiff.stylometry_delta > 0 ? '+' : '' }}{{ (regressionDiff.stylometry_delta * 100).toFixed(1) }}% Улучшено: {{ regressionDiff.improved_count }} Ухудшено: {{ regressionDiff.regressed_count }} Без изменений: {{ regressionDiff.same_count }}
Регрессии ({{ regressionDiff.regressed_qas.length }})
Q: {{ rq.question }}
Было: {{ rq.old_verdict }}
Стало: {{ rq.new_verdict }}
✓ {{ recsAppliedSummary }}
📋 Диагноз:
{{ analysisData.last_test.recommendations.diagnosis }}
🔥 Приоритетные правки:
  • {{ p }}
💡 Рекомендации:
  • {{ r }}
✓ Сильные стороны:
  • {{ s }}
Детали по вопросам ({{ analysisData.last_test.results.length }})
{{ ri + 1 }}. {{ r.question }} {{ r.verdict }}
⚠ META LEAK: «{{ r.meta_leak.phrase }}»
Ожидалось: {{ r.expected_answer }}
Ответ двойника: {{ r.twin_answer }}
{{ r.reason }}
Загрузка графа...

Граф знаний ещё не построен.

Процесс занимает 30-90 секунд и делает ~10 LLM-вызовов.
📤 Экспорт graph.json Построен: {{ new Date(graphData.generated_at * 1000).toLocaleString('ru') }}
🔵 Узлов: {{ graphData.nodes.length }} ↔ Связей: {{ graphData.edges.length }} ✏️ Ручных: {{ graphManualCount }} ⚠️ Несостыковок: {{ graphData.consistency_issues.length }}
🌐 Визуализация
📄 Узлы ({{ graphData.nodes.length }})
🔗 Связи ({{ graphData.edges.length }})
⚠️ Несостыковки ({{ graphData.consistency_issues.length }})
Подграф
Типы узлов
Типы связей
Минимальная уверенность
≥ {{ graphMinConfidence.toFixed(2) }}
{{ selectedNode.label }}
{{ nodeTypeLabel(selectedNode.type) }} · {{ selectedNode.layer }} · {{ selectedNode.when_hint }}
{{ selectedNode.content }}
Связи ({{ selectedNodeEdges.length }}):
{{ edgeTypeLabel(e.type) }} ✏️ {{ e.confidence.toFixed(2) }}
{{ e.from_node === selectedNode.nodeId ? '→ ' : '← ' }} {{ nodeLabelById(e.from_node === selectedNode.nodeId ? e.to_node : e.from_node) }}
{{ e.reasoning }}
ТипСлойLabelКогдаСвязей
{{ nodeTypeLabel(n.type) }} {{ n.layer || '—' }} {{ n.label }} {{ n.when_hint || '—' }} {{ nodeDegree(n.nodeId) }}
ТипОтКConfidenceОбоснованиеИсточник
{{ edgeTypeLabel(e.type) }} {{ nodeLabelById(e.from_node) }} {{ nodeLabelById(e.to_node) }} {{ e.confidence.toFixed(2) }} {{ e.reasoning || '—' }} ✏️ LLM
Несостыковок не найдено. Нажми «🧠 Проверить на несостыковки» выше.
{{ issueTypeLabel(iss.issue_type) }} [{{ iss.severity }}]
{{ iss.reasoning }}
💡 {{ iss.resolution_hint }}

Добавить ручную связь

🔮 Синтез и промпт

🧬 Синтез и проверка

Синтез создаёт цифрового двойника на основе собранных данных. После синтеза можно сразу прогнать тесты и посмотреть в чат.

Последняя точность тестов: {{ analysisData.last_test_accuracy }}%
✓ Синтез завершён
📝 Системный промпт — создан
📋 Метаданные — созданы
📚 База знаний — построена
Персона готова — можно начать чат!

📝 Системный промпт

✓ Сохранено

Откройте предпросмотр vexpert.md чтобы посмотреть текст, которым «говорит» двойник. Или редактируйте вручную, чтобы добавить детали, стиль речи, особые инструкции.

Загрузка...
vexpert.md пуст или не найден.
📄 vexpert.md · {{ promptContent.length }} символов · ~{{ Math.round(promptContent.length / 3.2) }} токенов
Загрузка...
Этот текст используется как системный промпт при общении с цифровым двойником. Изменения сохраняются в vexpert.md.
{{ promptContent ? promptContent.length + ' символов · ~' + Math.round(promptContent.length / 3.2) + ' токенов' : '' }}
⚙️ Правила персоны (ручные корректировки)

Это ручной корректировочный слой поверх автоматического анализа. Задавай здесь то, что LLM не смог понять сам: синонимы проектов, явные запреты, темы для игнора, свободные заметки. Применяются при следующем синтезе персоны.

🔗 Синонимы
Если автоматика не поймала, что «Trend Detector» = «Тренды» — задайте вручную
🚫 Запретные темы для советов
Где персона не даёт экспертных рекомендаций, даже если тема близка (по одной на строку)
🙈 Темы для игнора
Темы, которые персоне не интересны — она отмахивается коротко и переводит разговор (по одной на строку)
📝 Дополнительные заметки
Свободный текст — любые указания, которые не вписываются в другие категории
✓ Сохранено — применятся при следующем синтезе
✏️ Новый чат
{{ (c.personaName || '?')[0] }}
{{ c.personaName || c.title }}
{{ c.lastMessage || 'Нет сообщений' }}
{{ formatTime(c.updatedAt) }}

{{ chats.length ? 'Ничего не найдено' : 'Нет чатов' }}

{{ (currentChatData.chat.personaName || '?')[0] }}

{{ currentChatData.chat.personaName }}

печатает...
{{ currentChatData.chat.title }}
💰 ${{ chatCosts.cost_usd.toFixed(4) }} · {{ formatTokens(chatCosts.total_tokens) }}
Найдено: {{ chatSearchResults.length }}
{{ m.role === 'user' ? 'Я' : 'Двойник' }} {{ m.createdAt ? new Date(m.createdAt * 1000).toLocaleString('ru') : '' }}
{{ m.excerpt }}
Модель
Reasoning
Тема
↩ {{ replyToMsg.role === 'user' ? 'Вы' : currentChatData.chat.personaName }}: {{ replyToMsg.content.substring(0, 80) }}
💬

Выберите чат или создайте новый

📊 Дашборд
👥 Пользователи
✉️ Инвайты
🔑 Сессии
⚙️ Задачи
🧑 Все персоны
💾 Хранилище
💬 Все чаты
📋 Активность
💰 LLM
🔍 Аудит
ЛогинИмяРольСозданПоследний вход
{{ u.username }} {{ u.displayName }} {{ u.role }} {{ u.createdAt ? new Date(u.createdAt * 1000).toLocaleDateString('ru') : '—' }} {{ u.lastLogin ? new Date(u.lastLogin * 1000).toLocaleDateString('ru') : 'Никогда' }}
Ссылка для регистрации нового пользователя с предустановленной ролью
Заметка Роль Статус Создан Истекает Использован
{{ inv.note }}
{{ inv.code.substring(0,10) }}…
{{ inv.role }} Активен Использован Истёк {{ inv.createdAt ? new Date(inv.createdAt * 1000).toLocaleDateString('ru') : '—' }} {{ inv.expiresAt ? new Date(inv.expiresAt * 1000).toLocaleDateString('ru') : 'никогда' }} {{ inv.usedByUsername }}

Инвайтов пока нет

ПерсонаВладелецСтатусПолнотаСозданаДействия
{{ p.name }} {{ p.ownerName }} Удалена {{ statusLabel(p.status) }} {{ p.completeness }}% {{ p.createdAt ? new Date(p.createdAt * 1000).toLocaleDateString('ru') : '—' }}
ЧатВладелецПерсонаСообщенийСтатусОбновлён
{{ c.title || '—' }} {{ c.ownerName }} {{ c.personaName }} {{ c.messages }} Удалён Активен {{ c.updatedAt ? new Date(c.updatedAt * 1000).toLocaleDateString('ru') : '—' }}

Нет чатов

Загрузка...
Сгенерировано: {{ new Date(adminDashboard.generated_at * 1000).toLocaleString('ru') }}
Пользователи
{{ adminDashboard.counts.users }}
Персоны
{{ adminDashboard.counts.personas_active }} / {{ adminDashboard.counts.personas_total }}
Чанки
{{ adminDashboard.counts.chunks.toLocaleString('ru') }}
Узлы графа
{{ adminDashboard.counts.graph_nodes.toLocaleString('ru') }}
Связи графа
{{ adminDashboard.counts.graph_edges.toLocaleString('ru') }}
Чаты / сообщения
{{ adminDashboard.counts.chats }} / {{ adminDashboard.counts.messages.toLocaleString('ru') }}
Активные сессии
{{ adminDashboard.counts.sessions_active }}
Активные инвайты
{{ adminDashboard.counts.invites_active }}

Задачи

В очереди / выполняются
{{ adminDashboard.tasks.running }}
Готово за 24ч
{{ adminDashboard.tasks.done_24h }}
Упало за 24ч
{{ adminDashboard.tasks.failed_24h }}

Активность

Сообщений
1ч: {{ adminDashboard.activity.messages_1h }} · 24ч: {{ adminDashboard.activity.messages_24h }} · 7д: {{ adminDashboard.activity.messages_7d }}
Активные пользователи
1ч: {{ adminDashboard.activity.users_active_1h }} · 24ч: {{ adminDashboard.activity.users_active_24h }} · 7д: {{ adminDashboard.activity.users_active_7d }}
Удалённые персоны
{{ adminDashboard.counts.personas_deleted }} (soft-deleted)

Хранилище

Файлы персон на диске
{{ formatBytes(adminDashboard.storage.personas_disk_bytes) }}
MongoDB
data: {{ formatBytes(adminDashboard.storage.mongo_data_bytes || 0) }} · storage: {{ formatBytes(adminDashboard.storage.mongo_storage_bytes || 0) }} · indexes: {{ formatBytes(adminDashboard.storage.mongo_indexes_bytes || 0) }}
Всего: {{ adminTasks.length }}
ТипСтатусПрогрессШагЧто обрабатывалосьМодельПерсонаВладелецСоздано
{{ t.type }} {{ t.status }} {{ t.progress }}% {{ t.currentStep }}
{{ t.error }}
📄 {{ t.fileName }}
{{ t.fileName ? t.details.text.replace(t.fileName, '').trim() : t.details.text }}
{{ t.model || '—' }} {{ t.personaId || '—' }} {{ t.ownerName || t.userId.substring(0,8) + '…' }} {{ t.createdAt ? new Date(t.createdAt * 1000).toLocaleString('ru') : '—' }}
Нет задач
Активных: {{ adminSessions.length }}
ПользовательЛогинТокенСозданаИстекает
{{ s.displayName }} {{ s.username }} {{ s.token_preview }} {{ s.createdAt ? new Date(s.createdAt * 1000).toLocaleString('ru') : '—' }} {{ s.expiresAt ? new Date(s.expiresAt * 1000).toLocaleString('ru') : '—' }}
Нет активных сессий
Подсчёт размеров... Сортировка: по размеру на диске убывание
ПерсонаВладелецСтатусПолнотаДискЧанкиУзлыСвязи
{{ s.name }} {{ s.ownerName }} Удалена {{ statusLabel(s.status) }} {{ s.completeness }}% {{ formatBytes(s.disk_bytes) }} {{ s.chunks_count.toLocaleString('ru') }} {{ s.nodes_count.toLocaleString('ru') }} {{ s.edges_count.toLocaleString('ru') }}
Итого ({{ adminStorage.length }} персон) {{ formatBytes(adminStorageTotals.disk) }} {{ adminStorageTotals.chunks.toLocaleString('ru') }} {{ adminStorageTotals.nodes.toLocaleString('ru') }} {{ adminStorageTotals.edges.toLocaleString('ru') }}
Нет персон
{{ activityKindLabel(ev.kind) }} {{ ev.subkind }} {{ ev.subject }} {{ ev.at ? new Date(ev.at * 1000).toLocaleString('ru') : '—' }}
{{ ev.detail }}
Лента пуста
Загрузка...
Кеш: {{ adminLLM.cache.entries }} записей · {{ adminLLM.cache.total_hits }} попаданий

Сводка по периодам

{{ period }}
${{ t.cost_usd.toFixed(4) }}
Вызовов: {{ t.calls }} · из кеша: {{ t.cached }} · упало: {{ t.failed }}
{{ t.input_tokens.toLocaleString('ru') }} in / {{ t.output_tokens.toLocaleString('ru') }} out

По моделям (30 дней)

МодельВызововТокенов$
{{ m.model || 'unknown' }} {{ m.calls }} {{ m.tokens.toLocaleString('ru') }} ${{ m.cost.toFixed(4) }}

По задачам (30 дней)

ТипВызовов$
{{ t.taskType || 'unknown' }} {{ t.calls }} ${{ t.cost.toFixed(4) }}

По пользователям (30 дней)

ПользовательВызовов$
{{ u.name || u.userId.substring(0,8) + '…' }} {{ u.calls }} ${{ u.cost.toFixed(4) }}
Записей: {{ adminAudit.length }}
КогдаКтоIPДействиеОбъектДетали
{{ e.at ? new Date(e.at * 1000).toLocaleString('ru') : '—' }} {{ e.actorName || e.actorId.substring(0,8) + '…' }} [{{ e.actorRole }}] {{ e.ip || '—' }} {{ e.action }} {{ e.target_type }}{{ e.target_id ? ': ' + e.target_id.substring(0,16) + '…' : '' }} {{ JSON.stringify(e.extra).substring(0,80) }}
Записей нет
Выбрано: {{ bulkSelected.length }}