Files
swarm-assistent/Tabs/Text2Image/Assistent.html
T
mrleo1nidandClaude Opus 5 d67f5e396e Add OpenRouter chat provider; fix Windows load errors (0.17.0).
- OpenRouter as an alternative chat provider: server-side API key
  (settings.json or OPENROUTER_API_KEY), model list with vision marks and
  filter, SSE streaming, images as data URLs. Memory embeddings stay on Ollama;
  park/warm LLM are no-ops for the remote provider.
- AssistentSaveKnowledgeAttach: JArray param is not supported by SwarmUI API
  reflection and aborted registration of every later API call; use string[].
- SQLite bootstrap: preload native e_sqlite3 for the current OS/arch
  (win/osx/linux) and resolve DllImport to it.
- settings.json: shared-read + atomic write with retry to avoid Windows
  sharing violations.
- csproj: fix MSB4012 in the native SQLite copy target.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 06:18:47 +03:00

329 lines
31 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<div class="swarm-assistent-root" id="swarm_assistent_root">
<div class="sa-gate" id="sa_gate" hidden>
<p>Swarm Assistent только для моделей <strong>Krea 2</strong>. Выбери checkpoint Krea 2, чтобы включить чат.</p>
</div>
<header class="sa-appbar" id="sa_appbar">
<div class="sa-appbar-brand">
<span class="sa-appbar-title">Assistent</span>
<span class="sa-live-dot" id="sa_live_dot" hidden></span>
<span class="sa-health" id="sa_ollama_health" role="button" tabindex="0" title="Ollama: проверяю…" hidden>Ollama · …</span>
</div>
<div class="sa-app-tabs" role="tablist" aria-label="Разделы Assistent">
<button type="button" class="sa-app-tab sa-app-tab-active" data-view="chat" id="sa_tab_chat" role="tab" aria-selected="true">Чат</button>
<button type="button" class="sa-app-tab" data-view="settings" id="sa_tab_settings" role="tab" aria-selected="false">Настройки</button>
</div>
</header>
<div class="sa-views" id="sa_views">
<div class="sa-view" id="sa_view_chat">
<div class="sa-layout" id="sa_layout">
<aside class="sa-image-pane" id="sa_image_pane">
<div class="sa-board-head">
<span class="sa-board-title">Доска</span>
<div class="sa-board-tabs" role="tablist" aria-label="Доска">
<button type="button" class="sa-board-tab sa-board-tab-active" data-board="generate" id="sa_board_tab_gen" role="tab" aria-selected="true">Generate</button>
<button type="button" class="sa-board-tab" data-board="refs" id="sa_board_tab_refs" role="tab" aria-selected="false">
Refs
<span class="sa-board-badge" id="sa_refs_badge" hidden></span>
</button>
</div>
<button type="button" class="basic-button sa-icon-btn" id="sa_btn_add_ref" title="Добавить окно референса">+ Ref</button>
</div>
<div class="sa-board" id="sa_board" tabindex="0" title="Перетащи изображение на окно или вставь (Ctrl+V). Кликни, чтобы выбрать."></div>
<div class="sa-live-params" id="sa_live_params" title="Параметры Generate · подсветка = не Exact"></div>
<div class="sa-image-actions" id="sa_image_actions">
<button type="button" class="basic-button sa-primary" id="sa_btn_look_result" title="Критический разбор кадра Generate: дефекты vs промпт, правки prompt/params">Посмотри результат</button>
<button type="button" class="basic-button" id="sa_btn_use_current" title="Скопировать текущий Generate в Ref">Снимок gen</button>
<button type="button" class="basic-button" id="sa_btn_clear_image" title="Очистить выбранный Ref">Очистить слот</button>
<div class="sa-more-wrap" id="sa_board_more_wrap">
<button type="button" class="basic-button sa-icon-btn" id="sa_btn_board_more" title="Init / Mask / Сброс" aria-expanded="false" aria-haspopup="true"></button>
<div class="sa-more-menu" id="sa_board_more_menu" hidden role="menu">
<button type="button" class="sa-more-item" id="sa_btn_as_init" role="menuitem">Как Init (img2img)</button>
<button type="button" class="sa-more-item" id="sa_btn_as_mask" role="menuitem">Как Mask (inpaint)</button>
<button type="button" class="sa-more-item" id="sa_btn_clear_init" role="menuitem">Сброс Init + Mask</button>
</div>
</div>
</div>
</aside>
<div class="sa-splitter" id="sa_splitter" role="separator" aria-orientation="vertical" title="Потяни, чтобы изменить ширину"></div>
<div class="sa-chat-workspace" id="sa_chat_workspace">
<section class="sa-chat-pane">
<header class="sa-chat-header">
<div class="sa-chat-title">
<div class="sa-sessions-bar">
<button type="button" class="sa-chats-icon-btn sa-chats-toggle" id="sa_btn_chats" title="Показать чаты" aria-expanded="false" aria-controls="sa_chats_panel" aria-label="Показать чаты">
<svg width="15" height="15" viewBox="0 0 16 16" fill="none" aria-hidden="true"><rect x="2.2" y="3" width="11.6" height="10" rx="1.4" stroke="currentColor" stroke-width="1.4"/><path d="M10.2 3v10" stroke="currentColor" stroke-width="1.4"/></svg>
<span class="sa-chats-count" id="sa_chats_count" hidden></span>
</button>
<span class="sa-session-label" id="sa_session_label" title="Текущий чат">Новый чат</span>
<button type="button" class="sa-chats-icon-btn" id="sa_btn_new_chat_bar" title="Новый чат" aria-label="Новый чат">
<svg width="14" height="14" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M8 3v10M3 8h10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
</button>
</div>
</div>
<div class="sa-header-right">
<div class="sa-ctx-wrap" id="sa_ctx_wrap">
<button type="button" class="sa-ctx-chip sa-ctx-ok" id="sa_ctx_chip" title="Контекст модели" aria-expanded="false" aria-controls="sa_ctx_panel">
<span class="sa-ctx-dot" hidden aria-hidden="true"></span>
<span class="sa-ctx-chip-text">— / —</span>
</button>
<div class="sa-ctx-panel" id="sa_ctx_panel" hidden role="dialog" aria-label="Бюджет контекста">
<div class="sa-ctx-panel-head">
<strong>Контекст</strong>
<button type="button" class="basic-button sa-icon-btn" id="sa_ctx_close" title="Закрыть" aria-label="Закрыть">×</button>
</div>
<div class="sa-ctx-bar"><div class="sa-ctx-bar-fill" id="sa_ctx_bar_fill"></div></div>
<div id="sa_ctx_panel_body" class="sa-ctx-panel-body"></div>
<label class="sa-check sa-ctx-auto"><input type="checkbox" id="sa_ctx_auto" checked /> Авто перед отправкой</label>
<div class="sa-ctx-actions">
<button type="button" class="basic-button sa-primary" id="sa_ctx_compress">Сжать сейчас</button>
<button type="button" class="basic-button" id="sa_ctx_reset">Сбросить сжатие</button>
</div>
</div>
</div>
<div class="sa-persona-wrap">
<select id="sa_persona" class="sa-select" title="Характер / тон" aria-label="Характер">
<option value="neutral">Нейтральный</option>
</select>
<button type="button" class="basic-button sa-icon-btn" id="sa_persona_delete" title="Удалить overlay-личность" hidden aria-label="Удалить личность"></button>
</div>
<div class="sa-persona-controls" id="sa_persona_controls" hidden></div>
<select id="sa_pack" class="sa-select" title="Пакет промпта" aria-label="Пакет промпта">
<option value="ordinary">Обычный</option>
<option value="write_prompt">Написать промпт</option>
</select>
<span class="sa-mode-badge" id="sa_mode_badge" title="Активный pack">обычный</span>
<select id="sa_model" class="sa-select sa-model-select" title="Модель чата" aria-label="Модель чата">
<option value="">Загрузка моделей…</option>
</select>
</div>
</header>
<div class="sa-chat-body">
<div class="sa-messages" id="sa_messages">
<div class="sa-chat-empty" id="sa_chat_empty">
<div class="sa-chat-empty-title">Совместная работа с Krea 2</div>
<div class="sa-chat-empty-hint">Напиши промпт, кинь refs, выбери персону — у каждого чата свои параметры Generate.</div>
</div>
</div>
<div class="sa-livebar" id="sa_livebar" hidden>
<span class="sa-spinner" aria-hidden="true"></span>
<span class="sa-livebar-text" id="sa_livebar_text">Работаю…</span>
<span class="sa-elapsed" id="sa_elapsed"></span>
</div>
<div class="sa-composer" id="sa_composer">
<div class="sa-chips" id="sa_chips" role="toolbar" aria-label="Быстрые параметры"></div>
<div class="sa-composer-params" id="sa_composer_params" title="Параметры Generate. Подсветка — отличие от Exact/профиля чекпоинта. Чипы меняют без автозапуска — «Собрать + Gen» или /gen."></div>
<div class="sa-lora-chips" id="sa_lora_chips" role="toolbar" aria-label="Активные LoRA"></div>
<div class="sa-slash-wrap">
<textarea id="sa_input" rows="3" placeholder="Промпт, img2img, критика… Enter = отправить (прервёт Writing…) · /help = команды" aria-label="Сообщение Assistent"></textarea>
<div class="sa-slash-menu" id="sa_slash_menu" hidden role="listbox"></div>
</div>
<div class="sa-composer-actions">
<button type="button" class="basic-button sa-primary" id="sa_btn_send">Отправить</button>
<button type="button" class="basic-button sa-btn-gen" id="sa_btn_build_gen" title="Нет патча — Generate с текущим промптом SwarmUI">Собрать + Gen</button>
<button type="button" class="basic-button" id="sa_btn_interrupt" title="Прервать генерацию / чат" hidden>Стоп</button>
<div class="sa-more-wrap" id="sa_clear_more_wrap">
<button type="button" class="basic-button" id="sa_btn_clear" title="Очистить чат">Очистить</button>
<button type="button" class="basic-button sa-icon-btn" id="sa_btn_clear_more" title="Ещё варианты очистки" aria-expanded="false"></button>
<div class="sa-more-menu" id="sa_clear_more_menu" hidden role="menu">
<button type="button" class="sa-more-item" id="sa_btn_clear_confirm" role="menuitem">Очистить весь чат…</button>
<button type="button" class="sa-more-item" id="sa_btn_clear_patches" role="menuitem">Убрать только патчи</button>
</div>
</div>
<span class="sa-status" id="sa_status" role="status" aria-live="polite"></span>
</div>
</div>
</div>
</section>
<aside class="sa-chats-drawer" id="sa_chats_panel" aria-label="Чаты">
<div class="sa-chats-drawer-head">
<span class="sa-chats-drawer-label">Чаты</span>
<div class="sa-chats-drawer-actions">
<button type="button" class="sa-chats-icon-btn" id="sa_btn_new_chat" title="Новый чат" aria-label="Новый чат">
<svg width="14" height="14" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M8 3v10M3 8h10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
</button>
<button type="button" class="sa-chats-icon-btn" id="sa_btn_chats_close" title="Скрыть панель" aria-label="Скрыть чаты">
<svg width="14" height="14" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
</button>
</div>
</div>
<div class="sa-chats-search-wrap">
<svg class="sa-chats-search-ico" width="12" height="12" viewBox="0 0 16 16" fill="none" aria-hidden="true"><circle cx="7" cy="7" r="4.5" stroke="currentColor" stroke-width="1.4"/><path d="M10.5 10.5L14 14" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg>
<input type="search" class="sa-chats-search" id="sa_chats_search" placeholder="Поиск…" autocomplete="off" aria-label="Поиск по чатам" />
</div>
<div class="sa-chats-list" id="sa_chats_list" role="list"></div>
</aside>
</div>
</div>
</div>
<div class="sa-view" id="sa_view_settings" hidden>
<div class="sa-settings" id="sa_settings">
<div class="sa-settings-tabs" role="tablist" aria-label="Разделы настроек">
<button type="button" class="sa-stab sa-stab-active" data-stab="behavior" role="tab" aria-selected="true">Поведение</button>
<button type="button" class="sa-stab" data-stab="models" role="tab" aria-selected="false">Модели</button>
<button type="button" class="sa-stab" data-stab="personas" role="tab" aria-selected="false">Личности</button>
<button type="button" class="sa-stab" data-stab="user" role="tab" aria-selected="false">О пользователе</button>
<button type="button" class="sa-stab" data-stab="craft" role="tab" aria-selected="false">Крафт</button>
<button type="button" class="sa-stab" data-stab="more" role="tab" aria-selected="false">Ещё</button>
</div>
<div class="sa-settings-panes">
<div class="sa-spane" data-spane="behavior">
<p class="sa-settings-hint">Автодействия после ответа модели и скилы текущей личности.</p>
<label class="sa-check" title="По умолчанию выкл. Кадр смотрит по кнопке «Посмотри результат», /look, или когда модель сама шлёт look_at. Эта галка — после каждого Generate."><input type="checkbox" id="sa_auto_vision" /> После Generate — look_at кадра</label>
<label class="sa-check"><input type="checkbox" id="sa_auto_apply" checked /> Авто-применять патч</label>
<label class="sa-check" title="Устарело в 0.14: Generate запускает модель через generate:true или кнопки из сессии чата." hidden><input type="checkbox" id="sa_auto_generate" /> Авто-Generate после патча</label>
<label class="sa-check" title="По умолчанию выкл. Строгий QC кадра — кнопка «Посмотри результат» или /look. Галка шлёт JPEG после каждого Generate."><input type="checkbox" id="sa_auto_critique" /> Авто-критика после Generate</label>
<label class="sa-check" title="Выгружает чат-модель перед Generate (keep_alive:0). По умолчанию выкл. Park — no-op если модель уже выгружена; warm после Generate — no-op если /api/ps ещё держит VL. Включай только если Generate падает по VRAM."><input type="checkbox" id="sa_park_llm" /> Park LLM перед Generate (VRAM)</label>
<label class="sa-check sa-danger" title="Опасно — скачивает без Confirm"><input type="checkbox" id="sa_auto_download" /> Авто-скачивание Civitai (выкл)</label>
<div class="sa-skills-label">Скилы (процедуры)</div>
<div class="sa-skills-box" id="sa_skills_box"></div>
</div>
<div class="sa-spane" data-spane="models" hidden>
<p class="sa-settings-hint">Провайдер чата и модель эмбеддингов для крафт-памяти. Память всегда считается через Ollama.</p>
<label>Провайдер чата
<select id="sa_provider" class="sa-select">
<option value="ollama">Ollama (локально)</option>
<option value="openrouter">OpenRouter</option>
</select>
</label>
<div class="sa-openrouter-box" id="sa_openrouter_box" hidden>
<label>OpenRouter API key
<input type="password" id="sa_openrouter_key" autocomplete="off" spellcheck="false" placeholder="sk-or-v1-…" />
</label>
<div class="sa-settings-row">
<button type="button" class="basic-button sa-primary" id="sa_btn_openrouter_key_save">Сохранить ключ</button>
<button type="button" class="basic-button sa-danger-btn" id="sa_btn_openrouter_key_clear">Удалить ключ</button>
<span class="sa-settings-health" id="sa_openrouter_key_status">Ключ не задан</span>
</div>
<label>Фильтр моделей
<input type="text" id="sa_openrouter_filter" autocomplete="off" spellcheck="false" placeholder="например: claude, gpt, qwen, :free" />
</label>
</div>
<label>Ollama URL <input type="text" id="sa_base_url" value="http://127.0.0.1:11434" /></label>
<label>Модель чата
<select id="sa_settings_chat_model" class="sa-select" title="Синхрон с шапкой">
<option value=""></option>
</select>
</label>
<label>Модель памяти (embed)
<select id="sa_embed_model" class="sa-select" title="Хранение и группировка памяти (use: memory)">
<option value="nomic-embed-text">nomic-embed-text</option>
</select>
</label>
<div class="sa-settings-row">
<button type="button" class="basic-button" id="sa_btn_refresh_models">Обновить модели</button>
<button type="button" class="basic-button" id="sa_btn_refresh_inventory">Обновить inventory</button>
<button type="button" class="basic-button" id="sa_btn_settings_health">Проверить связь</button>
</div>
<div class="sa-settings-health" id="sa_settings_health_line">Ollama · …</div>
</div>
<div class="sa-spane" data-spane="personas" hidden>
<p class="sa-settings-hint">Встроенные личности нельзя удалить. Свои — экспорт / импорт / удаление.</p>
<div class="sa-persona-panel">
<div class="sa-persona-list" id="sa_persona_list"></div>
<div class="sa-persona-preview" id="sa_persona_preview">
<div class="sa-mem-empty">Выбери личность слева</div>
</div>
<div class="sa-knowledge-panel" id="sa_knowledge_panel" hidden>
<div class="sa-mem-head"><span class="sa-skills-label">Знания (books)</span></div>
<p class="sa-settings-hint" id="sa_knowledge_hint">FTS-корпуса для ask:knowledge. Bundled/pack — только просмотр; overlay — редактируемо.</p>
<div class="sa-knowledge-list" id="sa_knowledge_list"></div>
<div class="sa-settings-row">
<button type="button" class="basic-button sa-primary" id="sa_btn_knowledge_save" hidden>Сохранить attach</button>
</div>
</div>
</div>
<div class="sa-settings-row">
<button type="button" class="basic-button" id="sa_btn_persona_export">Экспорт</button>
<button type="button" class="basic-button" id="sa_btn_persona_import">Импорт…</button>
<button type="button" class="basic-button" id="sa_btn_persona_clone">Клонировать</button>
<button type="button" class="basic-button sa-danger-btn" id="sa_btn_persona_delete_panel" disabled title="Только overlay">Удалить</button>
<input type="file" id="sa_persona_import_file" accept=".json,.assistent-persona.json,application/json" hidden />
</div>
</div>
<div class="sa-spane" data-spane="user" hidden>
<p class="sa-settings-hint">Факты о тебе: общие для всех агентов и личные для текущей личности. Вес управляет силой в промпте.</p>
<label>Вес в промпте <span id="sa_user_prefs_weight_val">1.0</span>
<input type="range" id="sa_user_prefs_weight" min="0" max="1.5" step="0.1" value="1" />
</label>
<p class="sa-settings-hint">0 = выкл · 0.5 = кратко · 1 = полный список · &gt;1 = жёстко соблюдать</p>
<div class="sa-user-prefs-cols">
<div>
<div class="sa-mem-head">
<span class="sa-skills-label">Общие</span>
<button type="button" class="basic-button sa-icon-btn" id="sa_btn_pref_add_global" title="Добавить">+</button>
</div>
<div class="sa-mem-list" id="sa_prefs_global"></div>
</div>
<div>
<div class="sa-mem-head">
<span class="sa-skills-label">Для этой личности</span>
<button type="button" class="basic-button sa-icon-btn" id="sa_btn_pref_add_persona" title="Добавить">+</button>
</div>
<div class="sa-mem-list" id="sa_prefs_persona"></div>
</div>
</div>
<div class="sa-settings-row">
<button type="button" class="basic-button" id="sa_btn_prefs_refresh">Обновить</button>
<button type="button" class="basic-button" id="sa_btn_prefs_clear_global">Очистить общие</button>
<button type="button" class="basic-button" id="sa_btn_prefs_clear_persona">Очистить личность</button>
<button type="button" class="basic-button sa-danger-btn" id="sa_btn_prefs_clear_all">Очистить всё</button>
</div>
</div>
<div class="sa-spane" data-spane="craft" hidden>
<p class="sa-settings-hint">Крафт-RAG: LoRA, карточки, pitfalls. Не путать с «О пользователе».</p>
<div class="sa-mem-head">
<span class="sa-skills-label">Крафт-память</span>
<select id="sa_mem_scope" class="sa-select sa-mem-kind" title="Слой">
<option value="all">Все слои</option>
<option value="shared">Общая</option>
<option value="personal">Эта личность</option>
</select>
<select id="sa_mem_kind" class="sa-select sa-mem-kind" title="Фильтр по типу">
<option value="all">Все типы</option>
</select>
<input type="search" id="sa_mem_search" class="sa-mem-search" placeholder="Поиск…" autocomplete="off" />
<button type="button" class="basic-button sa-icon-btn" id="sa_btn_mem_refresh" title="Перечитать память"></button>
</div>
<div class="sa-mem-list" id="sa_mem_list"></div>
<div class="sa-mem-foot">
<span class="sa-mem-total" id="sa_mem_total">Всего: —</span>
</div>
<label>memory_top_k <input type="number" id="sa_memory_top_k" min="1" max="30" step="1" value="10" /></label>
<div class="sa-settings-row">
<button type="button" class="basic-button" id="sa_btn_mem_clear_kind">Очистить тип</button>
<button type="button" class="basic-button" id="sa_btn_mem_clear_persona">Очистить личность</button>
<button type="button" class="basic-button" id="sa_btn_mem_clear_shared">Очистить общую</button>
<button type="button" class="basic-button sa-danger-btn" id="sa_btn_mem_clear_all">Очистить всё крафт</button>
</div>
</div>
<div class="sa-spane" data-spane="more" hidden>
<p class="sa-settings-hint">Контекст Ollama и Exact Turbo/RAW (пишется в overlay).</p>
<label>num_ctx <input type="number" id="sa_num_ctx" min="2048" max="131072" step="1024" value="16384" /></label>
<label>history_keep_turns <input type="number" id="sa_history_keep" min="1" max="32" step="1" value="4" /></label>
<label>compress_at <input type="number" id="sa_compress_at" min="0.4" max="0.95" step="0.05" value="0.7" title="Доля от (num_ctx num_predict)" /></label>
<label>chars_per_token <input type="number" id="sa_chars_per_token" min="1.5" max="8" step="0.1" value="3.2" /></label>
<label class="sa-check"><input type="checkbox" id="sa_compress_auto" checked /> Автосжатие перед отправкой</label>
<div class="sa-skills-label">Exact · Turbo</div>
<div class="sa-settings-row sa-knob-row">
<label>steps <input type="number" id="sa_exact_turbo_steps" min="1" max="64" step="1" /></label>
<label>cfg <input type="number" id="sa_exact_turbo_cfg" min="0.1" max="30" step="0.1" /></label>
<label>σ <input type="number" id="sa_exact_turbo_sigma" min="0.1" max="10" step="0.05" /></label>
</div>
<div class="sa-skills-label">Exact · RAW</div>
<div class="sa-settings-row sa-knob-row">
<label>steps <input type="number" id="sa_exact_raw_steps" min="1" max="64" step="1" /></label>
<label>cfg <input type="number" id="sa_exact_raw_cfg" min="0.1" max="30" step="0.1" /></label>
<label>σ <input type="number" id="sa_exact_raw_sigma" min="0.1" max="10" step="0.05" /></label>
</div>
<div class="sa-settings-row">
<button type="button" class="basic-button sa-primary" id="sa_btn_knobs_save">Сохранить knobs</button>
<button type="button" class="basic-button" id="sa_btn_reset_ui">Сброс UI-state</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>