313 lines
17 KiB
Cheetah
313 lines
17 KiB
Cheetah
{{define "connect_ru"}}
|
||
<style>
|
||
html { overflow-y: scroll; }
|
||
.connect-header { display: flex; justify-content: space-between; align-items: flex-start; }
|
||
.ai-tabs { display: flex; border-bottom: 1px solid var(--border); padding: 0 24px; }
|
||
.ai-tab { padding: 16px 24px; cursor: pointer; border: none; background: none; font-family: inherit; font-size: 1rem; color: var(--text-muted); border-bottom: 2px solid transparent; margin-bottom: -1px; }
|
||
.ai-tab:hover { color: var(--text); }
|
||
.ai-tab.active { color: var(--accent); border-bottom-color: var(--accent); font-weight: 500; }
|
||
.ai-content { display: none; padding: 32px; }
|
||
.ai-content.active { display: block; }
|
||
.ai-content > p:first-child { font-size: 1rem; font-weight: 300; color: var(--text-muted); margin-bottom: 24px; }
|
||
.step { margin-bottom: 24px; padding: 24px; background: var(--bg); border-radius: 8px; }
|
||
.step:last-child { margin-bottom: 0; }
|
||
.step-header { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
|
||
.step-num { width: 32px; height: 32px; background: var(--accent); color: white; border-radius: 50%; text-align: center; line-height: 32px; font-weight: 600; font-size: 0.9rem; flex-shrink: 0; }
|
||
.step-num.muted { background: var(--text-muted); }
|
||
.step-num.warning { background: #F59E0B; }
|
||
.step h3 { font-size: 1.1rem; font-weight: 600; color: var(--text); margin: 0; }
|
||
.step p { font-size: 1rem; font-weight: 300; color: var(--text-muted); line-height: 1.8; margin: 0; }
|
||
.step p + p { margin-top: 12px; }
|
||
.step a { color: var(--accent); }
|
||
.step ul { margin: 12px 0 0 0; padding-left: 20px; color: var(--text-muted); font-weight: 300; line-height: 1.8; }
|
||
.code-wrapper { position: relative; margin-top: 16px; }
|
||
.code-wrapper pre { background: #1C1917; color: #F5F5F4; padding: 16px; padding-right: 48px; border-radius: 6px; font-family: "SF Mono", Monaco, monospace; font-size: 0.85rem; white-space: pre-wrap; word-break: break-word; margin: 0; line-height: 1.6; }
|
||
.copy-icon { position: absolute; top: 8px; right: 8px; background: transparent; border: none; cursor: pointer; padding: 6px; border-radius: 4px; opacity: 0.6; }
|
||
.copy-icon:hover { opacity: 1; background: rgba(255,255,255,0.1); }
|
||
.copy-icon svg { width: 18px; height: 18px; stroke: #A8A29E; fill: none; }
|
||
.copy-icon.copied svg { stroke: #10B981; }
|
||
.step-note { margin-top: 12px; font-size: 0.9rem; }
|
||
.login-prompt { background: var(--accent-light); border: 1px solid var(--accent); border-radius: 8px; padding: 16px 24px; margin-bottom: 24px; font-size: 1rem; font-weight: 300; color: var(--text); }
|
||
.login-prompt a { color: var(--accent); font-weight: 500; }
|
||
@media (max-width: 768px) {
|
||
.ai-tabs { padding: 0 16px; overflow-x: auto; }
|
||
.ai-tab { padding: 12px 16px; font-size: 0.9rem; white-space: nowrap; }
|
||
.ai-content { padding: 24px 16px; }
|
||
.step { padding: 20px 16px; }
|
||
}
|
||
@media (max-width: 480px) {
|
||
.ai-tabs { padding: 0 12px; }
|
||
.ai-tab { padding: 10px 12px; font-size: 0.85rem; }
|
||
.ai-content { padding: 20px 12px; }
|
||
.step { padding: 16px 12px; }
|
||
.code-wrapper pre { font-size: 0.8rem; padding: 12px; padding-right: 40px; }
|
||
}
|
||
</style>
|
||
<div class="page-container">
|
||
|
||
<div class="page-card">
|
||
<div class="connect-header">
|
||
<div>
|
||
<h1>Подключи ИИ к своим данным</h1>
|
||
<p class="intro">Выбери ИИ-ассистента и следуй инструкциям по настройке.</p>
|
||
</div>
|
||
{{if and .Dossier .Dossier.DossierID}}<a href="/dashboard" class="btn btn-secondary btn-small">← Назад</a>{{else}}<a href="/" class="btn btn-secondary btn-small">← Главная</a>{{end}}
|
||
</div>
|
||
</div>
|
||
|
||
<div class="page-card" style="padding: 0;">
|
||
<div class="ai-tabs">
|
||
<button class="ai-tab active" onclick="showTab('claude')">Claude Desktop</button>
|
||
<button class="ai-tab" onclick="showTab('grok')">Grok</button>
|
||
<button class="ai-tab" onclick="showTab('chatgpt')">ChatGPT</button>
|
||
<button class="ai-tab" onclick="showTab('other')">Другой ИИ</button>
|
||
</div>
|
||
|
||
<!-- Вкладка Claude Desktop -->
|
||
<div id="tab-claude" class="ai-content active">
|
||
<p>Claude Desktop подключается напрямую к <span class="inou">inou</span> через OAuth — никаких токенов для копирования, никаких расширений для установки.</p>
|
||
|
||
<div class="step">
|
||
<div class="step-header">
|
||
<span class="step-num">1</span>
|
||
<h3>Установи Claude Desktop</h3>
|
||
</div>
|
||
<p>Скачай и установи с <a href="https://claude.ai/download" target="_blank">claude.ai/download</a></p>
|
||
</div>
|
||
|
||
<div class="step">
|
||
<div class="step-header">
|
||
<span class="step-num">2</span>
|
||
<h3>Добавь коннектор Inou</h3>
|
||
</div>
|
||
<p>В Claude Desktop:</p>
|
||
<ol style="margin: 8px 0 12px 20px;">
|
||
<li>Перейди в <strong>Settings → Connectors</strong></li>
|
||
<li>Нажми <strong>Add custom connector</strong></li>
|
||
<li>Заполни поля:</li>
|
||
</ol>
|
||
<table style="margin: 12px 0; border-collapse: collapse; width: 100%;">
|
||
<tr>
|
||
<td style="padding: 8px 12px; border: 1px solid var(--border); background: var(--bg-muted); font-weight: 500;">Name</td>
|
||
<td style="padding: 8px 12px; border: 1px solid var(--border);"><code>Inou Health</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td style="padding: 8px 12px; border: 1px solid var(--border); background: var(--bg-muted); font-weight: 500;">Remote MCP server URL</td>
|
||
<td style="padding: 8px 12px; border: 1px solid var(--border);"><code>https://inou.com/mcp</code></td>
|
||
</tr>
|
||
</table>
|
||
<p>Нажми <strong>Add</strong>, затем <strong>Connect</strong>.</p>
|
||
</div>
|
||
|
||
<div class="step">
|
||
<div class="step-header">
|
||
<span class="step-num">3</span>
|
||
<h3>Войди в аккаунт</h3>
|
||
</div>
|
||
<p>Откроется браузер для входа в <span class="inou">inou</span>. После входа нажми <strong>Open Claude</strong>, чтобы завершить подключение.</p>
|
||
</div>
|
||
|
||
<div class="step">
|
||
<div class="step-header">
|
||
<span class="step-num">4</span>
|
||
<h3>Разреши инструменты</h3>
|
||
</div>
|
||
<p>Чтобы не отвечать на 11 запросов разрешения:</p>
|
||
<ol style="margin: 8px 0 12px 20px;">
|
||
<li>В <strong>Settings → Connectors</strong> найди <strong>Inou Health</strong></li>
|
||
<li>Нажми <strong>Configure</strong> (иконка шестерёнки)</li>
|
||
<li>В разделе <strong>Read-only tools</strong> выбери <strong>Always allow</strong></li>
|
||
</ol>
|
||
<p>Это даёт Claude разрешение читать твои медицинские данные без запроса каждый раз.</p>
|
||
</div>
|
||
|
||
<div class="step">
|
||
<div class="step-header">
|
||
<span class="step-num">5</span>
|
||
<h3>Добавь пользовательские инструкции (рекомендуется)</h3>
|
||
</div>
|
||
<p>Чтобы автоматически загружать контекст медицинских данных семьи в каждом разговоре:</p>
|
||
<ol style="margin: 8px 0 12px 20px;">
|
||
<li>В Claude Desktop перейди в <strong>Settings → Custom Instructions</strong></li>
|
||
<li>В текстовом поле добавь:</li>
|
||
</ol>
|
||
<div class="code-wrapper">
|
||
<pre id="custom-instructions">At the start of health-related conversations, use the family_health_context tracker from the Inou Health connector to understand what health data is available.</pre>
|
||
<button class="copy-icon" onclick="copyCode('custom-instructions', this)" title="Копировать">
|
||
<svg viewBox="0 0 24 24" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
|
||
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
<p>Это говорит Claude проверять, какие медицинские данные доступны для членов твоей семьи в начале каждого разговора, не заполняя контекстное окно реальными медицинскими данными.</p>
|
||
</div>
|
||
|
||
<div class="step">
|
||
<div class="step-header">
|
||
<span class="step-num">6</span>
|
||
<h3>Проверь</h3>
|
||
</div>
|
||
<p>Открой Claude Desktop и попробуй:</p>
|
||
<div class="code-wrapper">
|
||
<pre id="step-test">List my available dossiers.</pre>
|
||
<button class="copy-icon" onclick="copyCode('step-test', this)" title="Копировать">
|
||
<svg viewBox="0 0 24 24" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
|
||
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
<p>Ты должен увидеть свои досье. Всё готово!</p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Вкладка Grok -->
|
||
<div id="tab-grok" class="ai-content">
|
||
<p>Grok может получить доступ к твоим медицинским данным через наш API с помощью HTTP-запросов. Установка не требуется.</p>
|
||
|
||
{{if and .Dossier .Dossier.DossierID}}
|
||
{{if .TempToken}}
|
||
<div class="step">
|
||
<div class="step-header">
|
||
<span class="step-num">1</span>
|
||
<h3>Вставь это в Grok</h3>
|
||
</div>
|
||
<div class="code-wrapper">
|
||
<pre id="grok-code">Access my health data using the Inou API.
|
||
|
||
Fetch https://inou.com/api/v1/dossiers?token={{.TempToken}}
|
||
|
||
Show me the list of dossiers with their details and wait for my instructions.
|
||
|
||
API docs: https://inou.com/api/docs
|
||
|
||
IMPORTANT: This is real medical data. NEVER hallucinate. Only describe what you see.
|
||
|
||
If you get a 401 error with "token expired", ask me to visit https://inou.com/connect?tab=grok for a fresh token.</pre>
|
||
<button class="copy-icon" onclick="copyCode('grok-code', this)" title="Копировать">
|
||
<svg viewBox="0 0 24 24" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
|
||
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
<p class="step-note">Токен истекает {{.TempTokenExpires}}. <a href="/connect?tab=grok">Обнови страницу</a>, чтобы получить новый токен.</p>
|
||
</div>
|
||
{{else}}
|
||
<div class="step">
|
||
<div class="step-header">
|
||
<span class="step-num">1</span>
|
||
<h3>Сгенерируй API-токен</h3>
|
||
</div>
|
||
<p>Тебе нужен API-токен для подключения Grok к твоим данным.</p>
|
||
<form method="POST" action="/api/token/generate?return=grok" style="margin-top: 12px;">
|
||
<button type="submit" class="btn btn-primary">Сгенерировать токен</button>
|
||
</form>
|
||
</div>
|
||
{{end}}
|
||
{{else}}
|
||
<div class="login-prompt">
|
||
<a href="/start">Войди</a>, чтобы сгенерировать API-токен и получить персональные инструкции по настройке.
|
||
</div>
|
||
{{end}}
|
||
|
||
<div class="step">
|
||
<div class="step-header">
|
||
<span class="step-num">→</span>
|
||
<h3>Что умеет Grok</h3>
|
||
</div>
|
||
<p>После подключения попроси Grok:</p>
|
||
<ul>
|
||
<li>Показать все твои исследования визуализации, данные генома и результаты анализов</li>
|
||
<li>Показать серии в конкретном исследовании</li>
|
||
<li>Получить и проанализировать отдельные срезы</li>
|
||
<li>Сравнить изображения из разных последовательностей (T1, T2, FLAIR)</li>
|
||
<li>Перейти к конкретным анатомическим областям</li>
|
||
<li>Запросить варианты генома по гену, категории или rsid</li>
|
||
<li>Просмотреть реакции на лекарства и риски для здоровья</li>
|
||
<li>Отслеживать значения анализов во времени</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<p style="margin-top: 24px;">Смотри <a href="/api/docs" style="color: var(--accent);">полную документацию API</a> для всех доступных эндпоинтов.</p>
|
||
</div>
|
||
|
||
<!-- Вкладка ChatGPT -->
|
||
<div id="tab-chatgpt" class="ai-content">
|
||
<p style="color: var(--text-muted);">Не рекомендуется для медицинской визуализации из-за повышенного риска галлюцинаций в наших тестах.</p>
|
||
|
||
<div class="step">
|
||
<div class="step-header">
|
||
<span class="step-num muted">✗</span>
|
||
<h3>Почему не ChatGPT?</h3>
|
||
</div>
|
||
<p>Медицинская визуализация требует абсолютной точности. В наших тестах ChatGPT выдумывал информацию, даже когда правильные данные были явно предоставлены. Мы не можем рекомендовать его для анализа медицинских данных, где ошибки имеют реальные последствия.</p>
|
||
</div>
|
||
|
||
<div class="step">
|
||
<div class="step-header">
|
||
<span class="step-num">→</span>
|
||
<h3>Рекомендуемые альтернативы</h3>
|
||
</div>
|
||
<p>Используй <a href="#" onclick="showTab('claude'); return false;">Claude Desktop</a> для лучшего опыта с нативным доступом к инструментам или <a href="#" onclick="showTab('grok'); return false;">Grok</a> для веб-доступа без установки.</p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Вкладка Другой ИИ -->
|
||
<div id="tab-other" class="ai-content">
|
||
<p>Другие ИИ-ассистенты могут получить доступ к твоим данным через наш веб-API, хотя возможности варьируются.</p>
|
||
|
||
<div class="step">
|
||
<div class="step-header">
|
||
<span class="step-num warning">⚠</span>
|
||
<h3>Gemini</h3>
|
||
</div>
|
||
<p>Веб-браузинг Gemini в настоящее время ограничен и может не иметь возможности напрямую получать URL inou.com. Варианты обхода:</p>
|
||
<ul>
|
||
<li>Копируй ответы API вручную и вставляй их в Gemini</li>
|
||
<li>Используй Google AI Studio с вызовом функций</li>
|
||
<li>Рассмотри использование Claude Desktop или Grok вместо этого</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="step">
|
||
<div class="step-header">
|
||
<span class="step-num">→</span>
|
||
<h3>Создай своё решение</h3>
|
||
</div>
|
||
<p>Наш API — это простой REST + JSON. Смотри <a href="/api/docs">документацию API</a> для эндпоинтов и аутентификации.</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{{template "footer"}}
|
||
|
||
</div>
|
||
|
||
<script>
|
||
function copyCode(id, btn) {
|
||
const text = document.getElementById(id).textContent;
|
||
navigator.clipboard.writeText(text).then(() => {
|
||
btn.classList.add('copied');
|
||
setTimeout(() => btn.classList.remove('copied'), 1500);
|
||
});
|
||
}
|
||
|
||
function showTab(name) {
|
||
document.querySelectorAll('.ai-tab').forEach(t => t.classList.remove('active'));
|
||
document.querySelectorAll('.ai-content').forEach(c => c.classList.remove('active'));
|
||
document.querySelector('[onclick="showTab(\'' + name + '\')"]').classList.add('active');
|
||
document.getElementById('tab-' + name).classList.add('active');
|
||
}
|
||
|
||
// Check for tab parameter on page load
|
||
(function() {
|
||
const params = new URLSearchParams(window.location.search);
|
||
const tab = params.get('tab');
|
||
if (tab && document.getElementById('tab-' + tab)) {
|
||
showTab(tab);
|
||
}
|
||
})();
|
||
</script>
|
||
{{end}} |