kingkont 0.10.1 → 0.10.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kingkont",
3
- "version": "0.10.1",
3
+ "version": "0.10.2",
4
4
  "description": "KingKont · Chatium — нод-редактор сцен с AI-генерацией (картинки/видео/голос/SFX/музыка/текст)",
5
5
  "main": "main.js",
6
6
  "bin": {
package/renderer/board.js CHANGED
@@ -213,8 +213,10 @@ async function renderWelcomeIdentity() {
213
213
  let status = null;
214
214
  try { status = await window.appChatium?.status?.(); } catch {}
215
215
  if (status?.connected) {
216
- // Имя: предпочитаем display-name (login/name из auth~me), fallback — userId.
217
- const name = status.login || status.name || status.userId || 'KingKont';
216
+ // Имя: предпочитаем email (наиболее узнаваемый), затем login/name,
217
+ // в крайнем случае userId. Subtitle = userId-обрезок если он
218
+ // отличается от показываемого имени.
219
+ const name = status.email || status.login || status.fullName || status.name || status.userId || 'KingKont';
218
220
  const sub = status.userId && status.userId !== name ? `· ${status.userId.slice(0, 8)}` : '';
219
221
  wrap.innerHTML = `
220
222
  <span style="color:#5c5; font-size:13px; line-height:1;">●</span>
package/renderer/chat.js CHANGED
@@ -225,6 +225,7 @@
225
225
  // ============== TOOL-CALL PARSER ==============
226
226
  function parseToolCalls(text) {
227
227
  const out = [];
228
+ if (typeof text !== 'string' || !text) return out;
228
229
  const re = /<tool>\s*([\s\S]*?)\s*<\/tool>/g;
229
230
  let m;
230
231
  while ((m = re.exec(text)) !== null) {
@@ -238,6 +239,7 @@
238
239
  return out;
239
240
  }
240
241
  function stripToolCalls(text) {
242
+ if (typeof text !== 'string') return '';
241
243
  return text.replace(/<tool>[\s\S]*?<\/tool>/g, '').trim();
242
244
  }
243
245
 
@@ -293,29 +295,41 @@
293
295
 
294
296
  // ============== LLM call + tool-loop ==============
295
297
  async function callLLM(messages, system) {
298
+ const body = {
299
+ messages, system,
300
+ model: 'anthropic/claude-sonnet-4.6',
301
+ };
302
+ console.log('[chat] → POST /api/text', { messages: messages.length, hasSystem: !!system });
296
303
  const r = await fetch('/api/text', {
297
304
  method: 'POST',
298
305
  headers: { 'Content-Type': 'application/json' },
299
- body: JSON.stringify({
300
- messages, system,
301
- model: 'anthropic/claude-sonnet-4.6',
302
- }),
306
+ body: JSON.stringify(body),
303
307
  });
308
+ const respText = await r.text();
309
+ let d; try { d = JSON.parse(respText); } catch { d = { _raw: respText }; }
304
310
  if (!r.ok) {
305
- const err = await r.json().catch(() => ({}));
306
- throw new Error(err.error || `HTTP ${r.status}`);
311
+ console.error('[chat] /api/text failed', r.status, d);
312
+ throw new Error(d?.error || d?._raw?.slice(0, 200) || `HTTP ${r.status}`);
307
313
  }
308
- const d = await r.json();
309
- return d.text || '';
314
+ console.log('[chat] /api/text ok', { textLen: (d?.text || '').length });
315
+ return d?.text || '';
310
316
  }
311
317
 
312
- // Превращает internal history → массив для /api/text. tool_results
313
- // объединяем в user-message (модель видит их как ответы юзера на её запрос).
318
+ // Превращает internal history → массив для /api/text. Используем
319
+ // Anthropic-формат content-blocks (`[{type:'text', text:...}]`), потому
320
+ // что Chatium-side @start/sdk требует именно его — со строкой content
321
+ // падает «Cannot read properties of undefined (reading 'length')».
322
+ // OpenRouter этот формат тоже принимает (универсальный путь).
314
323
  function historyToMessages() {
315
324
  const out = [];
316
325
  for (const m of history) {
317
326
  if (m.role === 'system') continue;
318
- out.push({ role: m.role, content: m.content });
327
+ const content = String(m.content || '');
328
+ if (!content) continue; // Anthropic не любит пустые messages
329
+ out.push({
330
+ role: m.role,
331
+ content: [{ type: 'text', text: content }],
332
+ });
319
333
  }
320
334
  return out;
321
335
  }
@@ -243,8 +243,8 @@
243
243
  .welcome-status-identity button:hover { background: rgba(255,255,255,0.06); color: #cde; }
244
244
  .welcome-status-balances {
245
245
  pointer-events: auto;
246
- display: flex; flex-direction: row; gap: 6px; flex-wrap: wrap;
247
- justify-content: flex-end;
246
+ display: flex; flex-direction: column; gap: 6px;
247
+ align-items: flex-end;
248
248
  }
249
249
  /* Используем те же .balance-info pill'ы что и в sidebar-footer'е. */
250
250