kingkont 0.17.0 → 0.17.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.
@@ -199,7 +199,17 @@ async function _runLoop(session, system, settingsGetter) {
199
199
  session.busy = true;
200
200
  session.lastError = null;
201
201
  schedulePersist(session);
202
+ // Регистрируем чат как bg-job этого проекта — счётчик «⏳ N в фоне»
203
+ // на welcome-карточке покажет ОБА: генерации нод И активный чат.
204
+ // jobId = 'chat:<sessionKey>' — стабильный, чтобы start был idempotent.
205
+ const jobsHub = require('./jobsHub');
206
+ const projectKey = session.key; // session.key УЖЕ имеет формат 'cloud:..'/'folder:..'
207
+ const chatJobId = 'chat:' + session.key;
208
+ try {
209
+ jobsHub.start({ projectKey, jobId: chatJobId, kind: 'chat', name: 'Чат думает', type: 'chat' });
210
+ } catch {}
202
211
  let iter = 0;
212
+ let lastFinalText = '';
203
213
  try {
204
214
  while (iter < MAX_TOOL_ITERATIONS) {
205
215
  iter++;
@@ -209,7 +219,12 @@ async function _runLoop(session, system, settingsGetter) {
209
219
  const assistantMsg = { role: 'assistant', content: cleanText, tools: [] };
210
220
  session.history.push(assistantMsg);
211
221
  schedulePersist(session);
212
- if (!toolCalls.length) break; // финальный ответ
222
+ if (!toolCalls.length) {
223
+ // Финальный ответ — ни одного tool. Запоминаем чтобы потом
224
+ // notify клиента (separate WS event 'final').
225
+ lastFinalText = cleanText;
226
+ break;
227
+ }
213
228
  // Выставляем pendingToolCalls и ЖДЁМ что клиент пришлёт results.
214
229
  // _waitForToolResults возвращает массив {id, ok, result, error}.
215
230
  const results = await _waitForToolResults(session, toolCalls);
@@ -241,6 +256,19 @@ async function _runLoop(session, system, settingsGetter) {
241
256
  session.pendingToolCalls = null;
242
257
  session.pendingResolve = null;
243
258
  schedulePersist(session);
259
+ // Завершаем chat-job на сервере (welcome-badge -1).
260
+ try { jobsHub.end({ projectKey, jobId: chatJobId }); } catch {}
261
+ // Push 'final'-event ТОЛЬКО для финального ответа (не для intermediate
262
+ // tool-iterations). Renderer слушает 'chat:<key>' и при event.kind='final'
263
+ // показывает toast/system-notification — даже если чат-панель скрыта или
264
+ // юзер на другой сцене.
265
+ if (lastFinalText || session.lastError) {
266
+ wsHub.publish('chat:' + session.key, {
267
+ kind: 'final',
268
+ text: (lastFinalText || '').slice(0, 240),
269
+ error: session.lastError || null,
270
+ });
271
+ }
244
272
  }
245
273
  }
246
274
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kingkont",
3
- "version": "0.17.0",
3
+ "version": "0.17.1",
4
4
  "description": "KingKont · Chatium — нод-редактор сцен с AI-генерацией (картинки/видео/голос/SFX/музыка/текст)",
5
5
  "main": "main.js",
6
6
  "bin": {
package/renderer/chat.js CHANGED
@@ -1213,6 +1213,23 @@
1213
1213
  let m;
1214
1214
  try { m = JSON.parse(e.data); } catch { return; }
1215
1215
  if (m?.type === 'event' && m.channel === 'chat:' + key) {
1216
+ // Финальный ответ — показать toast + system notification
1217
+ // (даже если чат-панель скрыта).
1218
+ if (m.event?.kind === 'final') {
1219
+ if (m.event.error) {
1220
+ if (typeof showToast === 'function') showToast(`💬 KingKont: ⚠ ${m.event.error.slice(0, 80)}`, 'error');
1221
+ if (typeof systemNotify === 'function' && document.hidden) {
1222
+ systemNotify('KingKont chat', '⚠ ' + m.event.error.slice(0, 100), { tag: 'chat-final' }).catch(() => {});
1223
+ }
1224
+ } else if (m.event.text) {
1225
+ const preview = m.event.text.length > 100 ? m.event.text.slice(0, 100) + '…' : m.event.text;
1226
+ if (typeof showToast === 'function') showToast(`💬 KingKont: ${preview}`, 'ok');
1227
+ if (typeof systemNotify === 'function' && document.hidden) {
1228
+ systemNotify('KingKont chat', preview, { tag: 'chat-final' }).catch(() => {});
1229
+ }
1230
+ }
1231
+ }
1232
+ // Любой event — refresh state (иначе пропустим обновление history).
1216
1233
  _refreshAndExecute(key).catch(() => {});
1217
1234
  }
1218
1235
  };