kingkont 0.9.0 → 0.9.1
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/lib/providers.js +12 -0
- package/package.json +1 -1
- package/renderer/board.js +1 -0
- package/renderer/settings.js +32 -24
package/lib/providers.js
CHANGED
|
@@ -712,6 +712,18 @@ async function fetchBalances(s) {
|
|
|
712
712
|
}
|
|
713
713
|
} catch {}
|
|
714
714
|
}
|
|
715
|
+
if (s.useKie && process.env.KIE_API_KEY) {
|
|
716
|
+
try {
|
|
717
|
+
// KIE: GET /api/v1/chat/credit → { code: 200, msg: 'success', data: <number> }
|
|
718
|
+
const r = await fetch(`${KIE_BASE}/api/v1/chat/credit`, {
|
|
719
|
+
headers: { 'Authorization': `Bearer ${process.env.KIE_API_KEY}` },
|
|
720
|
+
});
|
|
721
|
+
const d = await r.json().catch(() => ({}));
|
|
722
|
+
if (r.ok && d.code === 200 && typeof d.data === 'number') {
|
|
723
|
+
out.kie = { unit: 'credits', amount: d.data };
|
|
724
|
+
}
|
|
725
|
+
} catch {}
|
|
726
|
+
}
|
|
715
727
|
return out;
|
|
716
728
|
}
|
|
717
729
|
|
package/package.json
CHANGED
package/renderer/board.js
CHANGED
|
@@ -174,6 +174,7 @@ async function refreshBalance() {
|
|
|
174
174
|
// API не дал баланс) — pill не рендерим.
|
|
175
175
|
const pills = [
|
|
176
176
|
{ key: 'kingkont', label: 'KingKont', onClick: () => window.openTxLog?.(), low: 100, fmt: (a) => `<b>${a.toLocaleString('ru-RU')}</b> credits` },
|
|
177
|
+
{ key: 'kie', label: 'KIE', low: 5, fmt: (a) => `<b>${a.toLocaleString('ru-RU', { maximumFractionDigits: 2 })}</b> credits` },
|
|
177
178
|
{ key: 'openrouter', label: 'OpenRouter', low: 0.5, fmt: (a) => `<b>$${a.toFixed(2)}</b>` },
|
|
178
179
|
{ key: 'elevenlabs', label: 'ElevenLabs', low: 1000, fmt: (a) => `<b>${a.toLocaleString('ru-RU')}</b> chars` },
|
|
179
180
|
];
|
package/renderer/settings.js
CHANGED
|
@@ -239,25 +239,33 @@ async function renderNodeBody(node, body) {
|
|
|
239
239
|
if (node.status === 'draft') {
|
|
240
240
|
const wrap = document.createElement('div');
|
|
241
241
|
wrap.className = 'gen-pending';
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
: node.type === 'image' ? '🖼' : '📝';
|
|
247
|
-
const st = document.createElement('div');
|
|
248
|
-
st.className = 'state-text';
|
|
249
|
-
st.textContent = 'Черновик: подведи входы и запусти';
|
|
250
|
-
const pp = document.createElement('div');
|
|
251
|
-
pp.className = 'prompt-preview';
|
|
252
|
-
pp.textContent = node.generated?.rawPrompt || node.generated?.prompt || '';
|
|
253
|
-
wrap.append(ic, st, pp);
|
|
242
|
+
// Для image — кнопка наверху, без декоративных 🖼/«Черновик» (юзер
|
|
243
|
+
// и так видит ноду пустой). Для audio/video оставляем — у них
|
|
244
|
+
// меньше визуального контекста и иконка помогает идентифицировать тип.
|
|
245
|
+
const isImage = node.type === 'image';
|
|
254
246
|
const runBtn = document.createElement('button');
|
|
255
247
|
runBtn.textContent = '▶ Запустить генерацию';
|
|
256
248
|
runBtn.className = 'primary';
|
|
257
|
-
runBtn.style.cssText =
|
|
249
|
+
runBtn.style.cssText = isImage
|
|
250
|
+
? 'font-size:12px; padding:6px 10px; align-self:stretch;'
|
|
251
|
+
: 'margin-top:8px; font-size:12px; padding:6px 10px;';
|
|
258
252
|
runBtn.addEventListener('mousedown', e => e.stopPropagation());
|
|
259
253
|
runBtn.addEventListener('click', e => { e.stopPropagation(); regenerateNode(node); });
|
|
260
|
-
|
|
254
|
+
const pp = document.createElement('div');
|
|
255
|
+
pp.className = 'prompt-preview';
|
|
256
|
+
pp.textContent = node.generated?.rawPrompt || node.generated?.prompt || '';
|
|
257
|
+
if (isImage) {
|
|
258
|
+
wrap.append(runBtn, pp);
|
|
259
|
+
} else {
|
|
260
|
+
const ic = document.createElement('div');
|
|
261
|
+
ic.style.cssText = 'font-size:36px; opacity:0.7;';
|
|
262
|
+
ic.textContent = node.type === 'audio' ? '🎙'
|
|
263
|
+
: node.type === 'video' ? '🎬' : '📝';
|
|
264
|
+
const st = document.createElement('div');
|
|
265
|
+
st.className = 'state-text';
|
|
266
|
+
st.textContent = 'Черновик: подведи входы и запусти';
|
|
267
|
+
wrap.append(ic, st, pp, runBtn);
|
|
268
|
+
}
|
|
261
269
|
body.appendChild(wrap);
|
|
262
270
|
return;
|
|
263
271
|
}
|
|
@@ -520,21 +528,21 @@ async function renderNodeBody(node, body) {
|
|
|
520
528
|
body.appendChild(playRow);
|
|
521
529
|
}
|
|
522
530
|
} else if (node.type === 'image' && !node.file && (node.generated?.rawPrompt || node.generated?.prompt)) {
|
|
523
|
-
//
|
|
524
|
-
//
|
|
525
|
-
//
|
|
531
|
+
// Image-нода с промптом, но без файла (ещё не генерилась).
|
|
532
|
+
// Кнопка ▶ Запустить — сверху (без декоративной 🖼-иконки и
|
|
533
|
+
// подписи «Не сгенерировано» — они только занимают место).
|
|
526
534
|
const wrap = document.createElement('div');
|
|
527
535
|
wrap.className = 'gen-pending';
|
|
528
|
-
const
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
536
|
+
const runBtn = document.createElement('button');
|
|
537
|
+
runBtn.textContent = '▶ Запустить генерацию';
|
|
538
|
+
runBtn.className = 'primary';
|
|
539
|
+
runBtn.style.cssText = 'font-size:12px; padding:6px 10px; align-self:stretch;';
|
|
540
|
+
runBtn.addEventListener('mousedown', e => e.stopPropagation());
|
|
541
|
+
runBtn.addEventListener('click', e => { e.stopPropagation(); regenerateNode(node); });
|
|
534
542
|
const pp = document.createElement('div');
|
|
535
543
|
pp.className = 'prompt-preview';
|
|
536
544
|
pp.textContent = node.generated?.rawPrompt || node.generated?.prompt || '';
|
|
537
|
-
wrap.append(
|
|
545
|
+
wrap.append(runBtn, pp);
|
|
538
546
|
body.appendChild(wrap);
|
|
539
547
|
}
|
|
540
548
|
}
|