kingkont 0.20.43 → 0.20.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.html +20 -3
- package/package.json +1 -1
- package/renderer/board.js +35 -8
- package/renderer/generate.js +1 -1
- package/renderer/state.js +21 -12
package/index.html
CHANGED
|
@@ -568,11 +568,28 @@
|
|
|
568
568
|
</div>
|
|
569
569
|
</div>
|
|
570
570
|
|
|
571
|
-
<!-- =====
|
|
571
|
+
<!-- ===== Настройки сцены: aspect ratio + дефолтные промпты ===== -->
|
|
572
572
|
<div class="modal hidden" id="defaultPromptsModal">
|
|
573
573
|
<div class="modal-card" style="min-width:600px; max-width:760px;">
|
|
574
|
-
<h3 id="defaultPromptsTitle"
|
|
575
|
-
|
|
574
|
+
<h3 id="defaultPromptsTitle">Настройки сцены</h3>
|
|
575
|
+
<!-- Соотношение сторон по умолчанию для image/video-генераций -->
|
|
576
|
+
<div class="field-row" style="margin-bottom:16px;">Соотношение сторон по умолчанию
|
|
577
|
+
<div class="seg-control" id="bsAspectCtl" style="flex-wrap:wrap;">
|
|
578
|
+
<button class="seg" data-bs-asp="9:16" type="button">9:16</button>
|
|
579
|
+
<button class="seg" data-bs-asp="16:9" type="button">16:9</button>
|
|
580
|
+
<button class="seg" data-bs-asp="1:1" type="button">1:1</button>
|
|
581
|
+
<button class="seg" data-bs-asp="4:5" type="button">4:5</button>
|
|
582
|
+
<button class="seg" data-bs-asp="5:4" type="button">5:4</button>
|
|
583
|
+
<button class="seg" data-bs-asp="4:3" type="button">4:3</button>
|
|
584
|
+
<button class="seg" data-bs-asp="3:4" type="button">3:4</button>
|
|
585
|
+
<button class="seg" data-bs-asp="2:3" type="button">2:3</button>
|
|
586
|
+
<button class="seg" data-bs-asp="3:2" type="button">3:2</button>
|
|
587
|
+
<button class="seg" data-bs-asp="21:9" type="button">21:9</button>
|
|
588
|
+
</div>
|
|
589
|
+
</div>
|
|
590
|
+
<!-- Дефолтные промпты (multi, с тегами kind) -->
|
|
591
|
+
<h4 style="margin:0 0 6px; font-size:13px; color:#bbb;">Дефолтные промпты</h4>
|
|
592
|
+
<div class="hint" style="margin-bottom:10px;">
|
|
576
593
|
Промпты добавляются к каждой генерации соответствующего типа в этой
|
|
577
594
|
сцене (НЕ редактируются в поле промпта — применяются в момент генерации).
|
|
578
595
|
В gen-модалке каждый можно отдельно включать/отключать.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kingkont",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.45",
|
|
4
4
|
"description": "KingKont \u00b7 Chatium \u2014 \u043d\u043e\u0434-\u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440 \u0441\u0446\u0435\u043d \u0441 AI-\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0435\u0439 (\u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438/\u0432\u0438\u0434\u0435\u043e/\u0433\u043e\u043b\u043e\u0441/SFX/\u043c\u0443\u0437\u044b\u043a\u0430/\u0442\u0435\u043a\u0441\u0442)",
|
|
5
5
|
"main": "main.js",
|
|
6
6
|
"bin": {
|
package/renderer/board.js
CHANGED
|
@@ -2486,6 +2486,13 @@ function makeBoardItem(it, kind) {
|
|
|
2486
2486
|
nameSpan.textContent = it.name;
|
|
2487
2487
|
el.appendChild(nameSpan);
|
|
2488
2488
|
el.addEventListener('click', () => selectBoard({ kind, ...it }));
|
|
2489
|
+
// Дабл-клик по названию сцены — настройки сцены (aspect + defaultPrompts).
|
|
2490
|
+
// Юзер: «показывай форму настроек по дабл-клику на название сцены в сайдбаре».
|
|
2491
|
+
el.addEventListener('dblclick', e => {
|
|
2492
|
+
e.preventDefault();
|
|
2493
|
+
if (document.body.classList.contains('view-only-mode')) return;
|
|
2494
|
+
openDefaultPromptsDialog(kind, it);
|
|
2495
|
+
});
|
|
2489
2496
|
el.addEventListener('contextmenu', e => {
|
|
2490
2497
|
e.preventDefault();
|
|
2491
2498
|
// View-only: меню (rename/delete) бесполезно, см. node-comment выше.
|
|
@@ -2518,12 +2525,11 @@ function showBoardContextMenu(kind, item, clientX, clientY) {
|
|
|
2518
2525
|
alert('Не удалось переименовать: ' + (err?.message || err));
|
|
2519
2526
|
}
|
|
2520
2527
|
});
|
|
2521
|
-
//
|
|
2522
|
-
//
|
|
2523
|
-
//
|
|
2524
|
-
//
|
|
2525
|
-
add('
|
|
2526
|
-
add('📝 Дефолтные промпты…', () => openDefaultPromptsDialog(kind, item));
|
|
2528
|
+
// Единая форма «Настройки сцены»: aspectRatio + defaultPrompts.
|
|
2529
|
+
// Раньше было два пункта (▭ Соотношение сторон + 📝 Дефолтные промпты),
|
|
2530
|
+
// юзер: «объедини дефолтные промпты и соотношение сторон в одну форму».
|
|
2531
|
+
// Доступно также по дабл-клику на названии сцены в сайдбаре.
|
|
2532
|
+
add('⚙ Настройки сцены…', () => openDefaultPromptsDialog(kind, item));
|
|
2527
2533
|
if (kind === 'character') {
|
|
2528
2534
|
add('⚙ Свойства персонажа', () => {
|
|
2529
2535
|
// Открываем панель этого персонажа и потом её character-modal
|
|
@@ -2668,10 +2674,25 @@ async function openDefaultPromptsDialog(kind, item) {
|
|
|
2668
2674
|
metaSettings = meta.settings || {};
|
|
2669
2675
|
}
|
|
2670
2676
|
const prompts = (metaSettings.defaultPrompts || []);
|
|
2677
|
+
const currentAspect = metaSettings.aspectRatio || '9:16';
|
|
2671
2678
|
const titleEl = document.getElementById('defaultPromptsTitle');
|
|
2672
2679
|
if (titleEl)
|
|
2673
|
-
titleEl.textContent =
|
|
2674
|
-
//
|
|
2680
|
+
titleEl.textContent = `Настройки сцены «${item.name}»`;
|
|
2681
|
+
// Подсветка текущего aspect ratio.
|
|
2682
|
+
document.querySelectorAll('#bsAspectCtl [data-bs-asp]').forEach(b => {
|
|
2683
|
+
b.classList.toggle('active', b.dataset.bsAsp === currentAspect);
|
|
2684
|
+
});
|
|
2685
|
+
// Wire toggle (один раз достаточно, но click-handlers идемпотентны).
|
|
2686
|
+
document.querySelectorAll('#bsAspectCtl [data-bs-asp]').forEach(b => {
|
|
2687
|
+
if (b.__bsAspWired) return;
|
|
2688
|
+
b.__bsAspWired = true;
|
|
2689
|
+
b.addEventListener('click', () => {
|
|
2690
|
+
document.querySelectorAll('#bsAspectCtl [data-bs-asp]')
|
|
2691
|
+
.forEach(x => x.classList.remove('active'));
|
|
2692
|
+
b.classList.add('active');
|
|
2693
|
+
});
|
|
2694
|
+
});
|
|
2695
|
+
// Рендерим существующие default-prompts.
|
|
2675
2696
|
const list = document.getElementById('dpList');
|
|
2676
2697
|
list.innerHTML = '';
|
|
2677
2698
|
for (const p of prompts)
|
|
@@ -2701,6 +2722,9 @@ async function openDefaultPromptsDialog(kind, item) {
|
|
|
2701
2722
|
};
|
|
2702
2723
|
const onSave = async () => {
|
|
2703
2724
|
const next = _dpReadList();
|
|
2725
|
+
// Aspect ratio из активной кнопки .seg.
|
|
2726
|
+
const aspBtn = document.querySelector('#bsAspectCtl [data-bs-asp].active');
|
|
2727
|
+
const newAspect = aspBtn ? aspBtn.dataset.bsAsp : null;
|
|
2704
2728
|
if (isActive) {
|
|
2705
2729
|
if (!state.currentBoard.metadata.settings)
|
|
2706
2730
|
state.currentBoard.metadata.settings = {};
|
|
@@ -2708,7 +2732,9 @@ async function openDefaultPromptsDialog(kind, item) {
|
|
|
2708
2732
|
state.currentBoard.metadata.settings.defaultPrompts = next;
|
|
2709
2733
|
else
|
|
2710
2734
|
delete state.currentBoard.metadata.settings.defaultPrompts;
|
|
2735
|
+
if (newAspect) state.currentBoard.metadata.settings.aspectRatio = newAspect;
|
|
2711
2736
|
scheduleSave();
|
|
2737
|
+
if (typeof updateTimelineAspectLabel === 'function') updateTimelineAspectLabel();
|
|
2712
2738
|
}
|
|
2713
2739
|
else {
|
|
2714
2740
|
const meta = await loadBoardMetadata(item.handle);
|
|
@@ -2717,6 +2743,7 @@ async function openDefaultPromptsDialog(kind, item) {
|
|
|
2717
2743
|
meta.settings.defaultPrompts = next;
|
|
2718
2744
|
else
|
|
2719
2745
|
delete meta.settings.defaultPrompts;
|
|
2746
|
+
if (newAspect) meta.settings.aspectRatio = newAspect;
|
|
2720
2747
|
await saveBoardMetadata(item.handle, meta);
|
|
2721
2748
|
}
|
|
2722
2749
|
close();
|
package/renderer/generate.js
CHANGED
|
@@ -2142,7 +2142,7 @@ async function startGenerationJob(node, kind, prompt, mediaRefs, boardHandle, bK
|
|
|
2142
2142
|
}).catch(() => {});
|
|
2143
2143
|
}, 5000);
|
|
2144
2144
|
let r, rawText, data;
|
|
2145
|
-
const provider = await plannedProvider(kind);
|
|
2145
|
+
const provider = await plannedProvider(kind, modelKey);
|
|
2146
2146
|
logJob(node.id, `→ POST /api/generate → ${provider} (kind=${kind} model=${modelKey || '—'})`);
|
|
2147
2147
|
try {
|
|
2148
2148
|
r = await fetch('/api/generate', {
|
package/renderer/state.js
CHANGED
|
@@ -711,7 +711,7 @@ function logJob(nodeId, msg) {
|
|
|
711
711
|
// чтобы юзер ВИДЕЛ ДО запроса, на какой провайдер уйдут данные. Если
|
|
712
712
|
// настройки не позволяют ни один путь — возвращает 'none' (запрос либо
|
|
713
713
|
// упадёт 503, либо отработает дефолтом — UI всё равно покажет факт).
|
|
714
|
-
async function plannedProvider(kind) {
|
|
714
|
+
async function plannedProvider(kind, modelKey) {
|
|
715
715
|
let s;
|
|
716
716
|
try { s = await window.appSettings.get(); } catch { s = {}; }
|
|
717
717
|
const hasChatium = !!(s.useChatium && s.chatium?.token && s.chatium?.base);
|
|
@@ -731,23 +731,32 @@ async function plannedProvider(kind) {
|
|
|
731
731
|
if (hasChatium) return 'kingkont';
|
|
732
732
|
if (s.useElevenlabs === true) return 'elevenlabs';
|
|
733
733
|
return 'none';
|
|
734
|
-
case 'video':
|
|
735
|
-
// OR имеет приоритет для
|
|
736
|
-
// OPENROUTER_VIDEO_MODELS).
|
|
737
|
-
//
|
|
738
|
-
|
|
734
|
+
case 'video': {
|
|
735
|
+
// OR имеет приоритет ТОЛЬКО для моделей которые он реально поддерживает
|
|
736
|
+
// (seedance-2/seedance-2-fast, см. lib/providers.js OPENROUTER_VIDEO_MODELS).
|
|
737
|
+
// Юзер: «куда мы последний запрос отправляли? не в чатиум ведь?» —
|
|
738
|
+
// раньше говорили openrouter для ВСЕХ video если useOpenrouter=true,
|
|
739
|
+
// даже для kling-3.0 которая в OR не входит. Теперь честно.
|
|
740
|
+
const orVid = new Set(['seedance-2', 'seedance-2-fast']);
|
|
741
|
+
if (hasOpenrouter && modelKey && orVid.has(modelKey)) return 'openrouter';
|
|
739
742
|
if (hasChatium) return 'kingkont';
|
|
740
743
|
if (s.useKie === true) return 'kie';
|
|
741
744
|
return 'none';
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
//
|
|
745
|
-
//
|
|
746
|
-
//
|
|
747
|
-
|
|
745
|
+
}
|
|
746
|
+
case 'image': {
|
|
747
|
+
// OR — только nano-banana-* (см. providers.js OPENROUTER_IMAGE_MODELS).
|
|
748
|
+
// gpt-image-* / grok / seedream / flux / sdxl — не в OR, идут в
|
|
749
|
+
// Chatium/KIE. Раньше для всех говорили openrouter, что для
|
|
750
|
+
// gpt-image-2 (Chatium-only) было неверно.
|
|
751
|
+
const orImg = new Set(['nano-banana-2', 'nano-banana-pro']);
|
|
752
|
+
if (hasOpenrouter && modelKey && orImg.has(modelKey)) return 'openrouter';
|
|
753
|
+
// gpt-image-* — приоритет Chatium даже если OR включён.
|
|
754
|
+
const isGptImage = modelKey === 'gpt-image-2' || modelKey === 'gpt-image-1.5';
|
|
755
|
+
if (isGptImage && hasChatium) return 'kingkont';
|
|
748
756
|
if (hasChatium) return 'kingkont';
|
|
749
757
|
if (s.useKie === true) return 'kie';
|
|
750
758
|
return 'none';
|
|
759
|
+
}
|
|
751
760
|
default:
|
|
752
761
|
return '?';
|
|
753
762
|
}
|