nothumanallowed 15.1.49 → 15.1.51

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": "nothumanallowed",
3
- "version": "15.1.49",
3
+ "version": "15.1.51",
4
4
  "description": "NotHumanAllowed — 38 AI agents, 80 tools, Studio (visual agentic workflows). Email, calendar, browser automation, screen capture, canvas, cron/heartbeat, Alexandria E2E messaging, GitHub, Notion, Slack, voice chat, free AI (Liara), 28 languages. Zero-dependency CLI.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/constants.mjs CHANGED
@@ -5,7 +5,7 @@ import { fileURLToPath } from 'url';
5
5
  const __filename = fileURLToPath(import.meta.url);
6
6
  const __dirname = path.dirname(__filename);
7
7
 
8
- export const VERSION = '15.1.49';
8
+ export const VERSION = '15.1.51';
9
9
  export const BASE_URL = 'https://nothumanallowed.com/cli';
10
10
  export const API_BASE = 'https://nothumanallowed.com/api/v1';
11
11
 
@@ -302,17 +302,47 @@ export function register(router) {
302
302
  semanticBag = 'proposal';
303
303
  }
304
304
 
305
- if ((wantsReadEmail || semanticBag) && !actions.some(a => a.action?.startsWith('imap_') || a.action === 'list_emails')) {
305
+ // "allegato / attachment / PDF" user wants to read the content of
306
+ // an attachment of a specific email. We extract identifier tokens from
307
+ // the message (capitalized phrases, alphanumeric codes with dots/slashes
308
+ // like "NCSARMEMAIL.08/05", PO numbers, etc.) and search the local DB
309
+ // for matching subjects, then chain imap_read + imap_attachment_read
310
+ // server-side. This bypasses the LLM's habit of saying "Let me read..."
311
+ // without actually emitting the tool.
312
+ const wantsReadAttachment = /\b(allegato|attachment|allegata|allegat[oi]|pdf|documento\s+allegato|file\s+allegato|enclosed|attached)\b/i.test(msg);
313
+
314
+ if ((wantsReadEmail || semanticBag || wantsReadAttachment) && !actions.some(a => a.action?.startsWith('imap_') || a.action === 'list_emails')) {
306
315
  try {
307
316
  const { listAccounts: _la } = await import('../../services/email-db.mjs');
308
317
  const imapAccs = _la();
309
318
  if (imapAccs.length > 0) {
310
319
  const firstAcc = imapAccs[0];
311
- if (semanticBag) {
320
+ if (wantsReadAttachment) {
321
+ // Extract subject identifiers from the user message. Heuristic:
322
+ // - Quoted substrings ("..." or «...»)
323
+ // - Alphanumeric codes ≥4 chars with dot/slash/dash (PO/RDA codes)
324
+ // - Capitalized multi-word phrases ("Purchase Order", "Tagliando BMW")
325
+ // - Standalone uppercase tokens ≥4 chars (NCSARMEMAIL)
326
+ const ids = new Set();
327
+ const quoted = msg.match(/["«""']([^"«»""'\n]{3,80})["»""']/g) || [];
328
+ quoted.forEach(q => ids.add(q.replace(/^["«""']|["»""']$/g, '').trim()));
329
+ const codes = msg.match(/\b[A-Z0-9][A-Z0-9._/\-]{3,}\b/g) || [];
330
+ codes.forEach(c => ids.add(c));
331
+ const phrases = msg.match(/\b([A-Z][a-zà-ÿ]+(?:\s+[A-Za-zà-ÿ0-9]+){1,3})\b/g) || [];
332
+ phrases.filter(p => p.length >= 6).forEach(p => ids.add(p));
333
+ const tokens = [...ids].slice(0, 5);
334
+ if (tokens.length === 0) {
335
+ // No specific identifier — fall back to a broad list of recent
336
+ // messages with attachments.
337
+ actions.push({ action: 'imap_list', params: { accountId: firstAcc.id, limit: 30 } });
338
+ } else {
339
+ for (const q of tokens) {
340
+ actions.push({ action: 'imap_search', params: { accountId: firstAcc.id, query: q, limit: 10 } });
341
+ }
342
+ }
343
+ } else if (semanticBag) {
312
344
  // Push one imap_search per keyword variant in the bag. The
313
- // synthesis step will dedupe overlapping hits. We default to a
314
- // 60-day window (limit=80 per query) — much wider than the
315
- // 5-email peek the old branch did.
345
+ // synthesis step will dedupe overlapping hits.
316
346
  const bag = QUOTE_KEYWORDS[semanticBag] || [];
317
347
  const variants = [
318
348
  ...(QUOTE_KEYWORDS.offerta || []).slice(0, 3),
@@ -395,6 +425,75 @@ export function register(router) {
395
425
  }
396
426
  }
397
427
 
428
+ // ── Auto-chain: search → read → attachment_read ──────────────────────
429
+ // When the user wants to read an attachment of a specific email, the
430
+ // model often emits the first search but then gets stuck saying "Let
431
+ // me read the full email" without actually emitting the follow-up
432
+ // tool. We chain them server-side: parse the imap_search results,
433
+ // pick the best subject match, fetch it with imap_read, then read
434
+ // the first attachment if wantsReadAttachment is on.
435
+ if (wantsReadAttachment) {
436
+ try {
437
+ // Collect candidate messages from all imap_search results we already
438
+ // executed in this turn. Format of imap_search output:
439
+ // [id_xxx] [UNREAD] From: name | Subject | date\n preview...
440
+ const candidates = new Map(); // id → { id, subject }
441
+ for (const tr of toolResults) {
442
+ if (tr.action !== 'imap_search' || typeof tr.result !== 'string') continue;
443
+ const lineRe = /\[([a-zA-Z0-9_-]{6,})\][^\n]*?\|\s*([^|]{2,200})\s*\|/g;
444
+ let m;
445
+ while ((m = lineRe.exec(tr.result)) !== null) {
446
+ if (!candidates.has(m[1])) candidates.set(m[1], { id: m[1], subject: m[2].trim() });
447
+ }
448
+ }
449
+ if (candidates.size > 0) {
450
+ // Rank by token-overlap with the identifiers we extracted from
451
+ // the user message.
452
+ const norm = (s) => String(s || '').toLowerCase()
453
+ .normalize('NFD').replace(/[̀-ͯ]/g, '')
454
+ .replace(/[^a-z0-9\s./_-]/g, ' ')
455
+ .split(/\s+/).filter(t => t.length > 2);
456
+ const userTokens = norm(msg);
457
+ const ranked = [...candidates.values()].map(c => {
458
+ const subjTokens = new Set(norm(c.subject));
459
+ const score = userTokens.filter(t => subjTokens.has(t)).length;
460
+ return { ...c, score };
461
+ }).sort((a, b) => b.score - a.score);
462
+ const best = ranked[0];
463
+ if (best && best.score >= 1) {
464
+ sse('tool', { action: 'imap_read', status: 'executing' });
465
+ try {
466
+ const readResult = await executeTool('imap_read', { messageId: best.id }, config);
467
+ toolResults.push({ action: 'imap_read', result: readResult });
468
+ sse('tool', { action: 'imap_read', status: 'done', result: String(readResult).slice(0, 500) });
469
+ // If the read result lists at least one attachment, fetch it.
470
+ const attMatch = String(readResult).match(/ATTACHMENTS \(\d+\)/);
471
+ if (attMatch) {
472
+ sse('tool', { action: 'imap_attachment_read', status: 'executing' });
473
+ try {
474
+ const attResult = await executeTool('imap_attachment_read', { messageId: best.id, index: 1 }, config);
475
+ toolResults.push({ action: 'imap_attachment_read', result: attResult });
476
+ sse('tool', { action: 'imap_attachment_read', status: 'done', result: String(attResult).slice(0, 500) });
477
+ } catch (e) {
478
+ toolResults.push({ action: 'imap_attachment_read', result: `Error: ${e.message}` });
479
+ sse('tool', { action: 'imap_attachment_read', status: 'error', error: e.message });
480
+ }
481
+ }
482
+ } catch (e) {
483
+ toolResults.push({ action: 'imap_read', result: `Error: ${e.message}` });
484
+ sse('tool', { action: 'imap_read', status: 'error', error: e.message });
485
+ }
486
+ }
487
+ }
488
+ } catch { /* chain best-effort — fall through to synthesis */ }
489
+ }
490
+
491
+ // Capture the pre-synthesis prose (what the model said in Round 1).
492
+ // We will combine this with the synthesis output so the user keeps
493
+ // BOTH — currently the UI was overwriting Round 1 with Round 2 alone,
494
+ // which made long prose disappear and leave only "Let me read…".
495
+ const round1Prose = fullResponse;
496
+
398
497
  // Synthesis round if tools ran
399
498
  if (toolResults.length > 0) {
400
499
  // Strip raw JSON from tool results — present as clean prose summaries
@@ -422,8 +521,8 @@ export function register(router) {
422
521
  }
423
522
  };
424
523
  const toolContext = toolResults.map(t => `[${t.action} result]:\n${cleanResult(t.action, t.result)}`).join('\n\n---\n\n');
425
- const synthesisPrompt = `${enrichedPrompt}\n\n## DATA FROM TOOLS:\n${toolContext}\n\n## STRICT OUTPUT RULES:\n- Write ONLY plain prose or markdown (headers, bullets, bold)\n- NEVER use \`\`\`json, \`\`\`data, or any fenced code block containing data\n- NEVER output raw JSON, arrays, or objects\n- Format numbers/prices as plain text (e.g. "Bitcoin: $103,000")\n- Be concise and human-readable`;
426
- const synthesisMsg = `${effectiveMsg}\n\nAnswer using ONLY the data above. Plain text/markdown only — zero JSON, zero code blocks.`;
524
+ const synthesisPrompt = `${enrichedPrompt}\n\n## DATA FROM TOOLS (already executed — do NOT plan to call them again):\n${toolContext}\n\n## STRICT OUTPUT RULES:\n- The tools above HAVE ALREADY RUN. Their output is the ground truth.\n- NEVER say "Let me read…", "I'll search…", "I will fetch…", "leggerò", "cercherò", "ti dirò" — those tools are already done.\n- Answer the user's question DIRECTLY using the data above. If a specific detail (delivery date, item, total, etc.) is in the data, quote it verbatim.\n- If the data does not contain the answer, state plainly what is missing — do not announce intent to look further.\n- Write ONLY plain prose or markdown (headers, bullets, bold). NEVER use \`\`\`json or any fenced code block.\n- Format numbers/prices as plain text. Be concise and human-readable.`;
525
+ const synthesisMsg = `${effectiveMsg}\n\nThe tools have already been executed and their results are in the system prompt. Answer the question DIRECTLY using that data. Do NOT announce further actions ("Let me…", "I'll…", "leggerò", "cercherò"). Plain prose/markdown — zero JSON, zero code blocks.`;
427
526
  sse('tool_synthesis', {});
428
527
  // Keep the pre-synthesis prose around. If the synthesis call returns
429
528
  // empty (provider error, content filter, model bailed), we fall back
@@ -453,14 +552,56 @@ export function register(router) {
453
552
  // Strip orphan tool-fence blocks that the LLM may have emitted as
454
553
  // a "no-more-tools" marker (e.g. empty ```json ``` or '''json ''').
455
554
  // They leaked into the chat panel as visible noise.
456
- const cleanFullResponse = stripOrphanFences(fullResponse);
555
+ //
556
+ // Also combine Round 1 prose with synthesis output when a synthesis
557
+ // round actually happened, so the user sees BOTH the model's intro
558
+ // ("Leggerò l'email…") AND the synthesized result, instead of one
559
+ // overwriting the other.
560
+ const round1Clean = stripOrphanFences(round1Prose || '');
561
+ const synthClean = stripOrphanFences(fullResponse || '');
562
+ let cleanFullResponse;
563
+ if (toolResults.length > 0 && round1Clean && synthClean && round1Clean !== synthClean) {
564
+ cleanFullResponse = `${round1Clean}\n\n${synthClean}`;
565
+ } else {
566
+ cleanFullResponse = synthClean || round1Clean;
567
+ }
457
568
 
458
- // Persist to conversation
569
+ // Persist to conversation. Honour retry/edit flags so the tree forks
570
+ // correctly instead of duplicating the user message in the active path.
571
+ // - isRetry: add the new response as a sibling of the last assistant
572
+ // under the same user node (no new user node).
573
+ // - isEdit: add the new user message as a sibling of an existing
574
+ // user node, then chain the assistant under the new branch.
575
+ // - default: addMessages (creates user+assistant pair).
459
576
  if (body.conversationId) {
460
577
  try {
461
578
  const conv = loadConversation(body.conversationId);
462
579
  if (conv) {
463
- addMessages(conv, msg, cleanFullResponse);
580
+ if (body.isRetry) {
581
+ // Find the most recent user node in the active path — that's
582
+ // the parent we're regenerating from.
583
+ const path = getHistory(conv, 100);
584
+ const lastUser = [...path].reverse().find(n => n.role === 'user');
585
+ if (lastUser?.id) {
586
+ addRetryResponse(conv, lastUser.id, cleanFullResponse);
587
+ } else {
588
+ addMessages(conv, msg, cleanFullResponse);
589
+ }
590
+ } else if (body.isEdit && typeof body.editFromIdx === 'number') {
591
+ // Active path is a flat list; index editFromIdx in the UI maps
592
+ // 1:1 to the same index in the active path. Branch from there.
593
+ const path = getHistory(conv, 100);
594
+ const target = path[body.editFromIdx];
595
+ if (target?.id && target.role === 'user') {
596
+ const newUserId = editMessage(conv, target.id, msg);
597
+ if (newUserId) addRetryResponse(conv, newUserId, cleanFullResponse);
598
+ else addMessages(conv, msg, cleanFullResponse);
599
+ } else {
600
+ addMessages(conv, msg, cleanFullResponse);
601
+ }
602
+ } else {
603
+ addMessages(conv, msg, cleanFullResponse);
604
+ }
464
605
  }
465
606
  } catch {}
466
607
  }
@@ -59,10 +59,10 @@ The agent works in a loop: read → plan → modify → verify → fix if needed
59
59
  `),n=``,r=!1,i=!1,a=!1,o=``,s=``,c=0,l=()=>{r&&=(n+=`</ul>`,!1),i&&=(n+=`</ol>`,!1)};for(;c<t.length;){let e=t[c],u=e.trim();if(u.startsWith("```")){a?(n+=ye(o)+`</code></pre>`,a=!1,o=``):(l(),a=!0,o=``,s=u.slice(3).trim(),n+=`<pre><code${s?` class="language-${ye(s)}"`:``}>`),c++;continue}if(a){o+=e+`
60
60
  `,c++;continue}{let e=u.match(/^(#{1,6}) (.+)/);if(e){l();let t=e[1].length;n+=`<h${t}>${be(e[2])}</h${t}>`,c++;continue}}if(/^-{3,}$/.test(u)||/^\*{3,}$/.test(u)||/^_{3,}$/.test(u)){l(),n+=`<hr>`,c++;continue}if(u.startsWith(`|`)){l();let e=[];for(;c<t.length;){let n=t[c],r=n.trim();if(r.startsWith(`|`)||/^[|\-: ]+$/.test(r)&&r.includes(`-`)&&r.includes(`|`))e.push(n),c++;else break}e.length>0&&(n+=xe(e));continue}if(u.startsWith(`> `)){l(),n+=`<blockquote><p>${be(u.slice(2))}</p></blockquote>`,c++;continue}if(/^[-*+] /.test(u)){i&&=(n+=`</ol>`,!1),r||=(n+=`<ul>`,!0),n+=`<li>${be(u.slice(2))}</li>`,c++;continue}{let e=u.match(/^(\d+)[.)]\s(.+)/);if(e){r&&=(n+=`</ul>`,!1),i||=(n+=`<ol>`,!0),n+=`<li>${be(e[2])}</li>`,c++;continue}}if(l(),u===``){n+=`<div style="height:6px"></div>`,c++;continue}n+=`<p>${be(u)}</p>`,c++}return l(),a&&(n+=ye(o)+`</code></pre>`),n}var N={root:`_root_npowj_1`,convSidebar:`_convSidebar_npowj_8`,convSidebarHeader:`_convSidebarHeader_npowj_18`,newConvBtn:`_newConvBtn_npowj_23`,convList:`_convList_npowj_36`,convItem:`_convItem_npowj_41`,convItemActive:`_convItemActive_npowj_48`,convTitle:`_convTitle_npowj_53`,convMeta:`_convMeta_npowj_61`,convDelete:`_convDelete_npowj_69`,chatMain:`_chatMain_npowj_76`,chatToolbar:`_chatToolbar_npowj_85`,convTitleBar:`_convTitleBar_npowj_94`,toolbarBtn:`_toolbarBtn_npowj_103`,toolbarBtnDim:`_toolbarBtnDim_npowj_116`,toolbarBtnCanvas:`_toolbarBtnCanvas_npowj_128`,messages:`_messages_npowj_137`,empty:`_empty_npowj_146`,emptyIcon:`_emptyIcon_npowj_158`,emptyTitle:`_emptyTitle_npowj_159`,emptySub:`_emptySub_npowj_160`,emptyHint:`_emptyHint_npowj_161`,suggGroups:`_suggGroups_npowj_163`,suggGroup:`_suggGroup_npowj_163`,suggGroupTitle:`_suggGroupTitle_npowj_165`,suggBtns:`_suggBtns_npowj_166`,suggBtn:`_suggBtn_npowj_166`,message:`_message_npowj_137`,user:`_user_npowj_178`,assistant:`_assistant_npowj_179`,msgLabel:`_msgLabel_npowj_181`,bubble:`_bubble_npowj_188`,sentinelBubble:`_sentinelBubble_npowj_211`,cursor:`_cursor_npowj_216`,blink:`_blink_npowj_1`,msgActions:`_msgActions_npowj_231`,msgActionBtn:`_msgActionBtn_npowj_240`,editBox:`_editBox_npowj_252`,editInput:`_editInput_npowj_259`,editActions:`_editActions_npowj_272`,editSaveBtn:`_editSaveBtn_npowj_273`,editCancelBtn:`_editCancelBtn_npowj_277`,toolActivity:`_toolActivity_npowj_284`,toolActivityItem:`_toolActivityItem_npowj_290`,active:`_active_npowj_303`,toolPulse:`_toolPulse_npowj_1`,done:`_done_npowj_308`,error:`_error_npowj_309`,thinkingIndicator:`_thinkingIndicator_npowj_317`,thinkingDots:`_thinkingDots_npowj_331`,thinkingDot:`_thinkingDot_npowj_331`,thinkBounce:`_thinkBounce_npowj_1`,attachBar:`_attachBar_npowj_349`,attachClear:`_attachClear_npowj_360`,inputBar:`_inputBar_npowj_371`,inputTools:`_inputTools_npowj_381`,iconBtn:`_iconBtn_npowj_387`,iconBtnActive:`_iconBtnActive_npowj_398`,thinkBtn:`_thinkBtn_npowj_400`,thinkBtnOn:`_thinkBtnOn_npowj_412`,inputRow:`_inputRow_npowj_417`,input:`_input_npowj_371`,btn:`_btn_npowj_436`,send:`_send_npowj_447`,stop:`_stop_npowj_454`,canvasPanel:`_canvasPanel_npowj_461`,canvasPanelHeader:`_canvasPanelHeader_npowj_476`,canvasPanelActions:`_canvasPanelActions_npowj_488`,canvasPanelBtn:`_canvasPanelBtn_npowj_494`,canvasPanelClose:`_canvasPanelClose_npowj_505`,canvasFrame:`_canvasFrame_npowj_516`},Ce={body:`_body_ctbrf_4`,mdCursorBlink:`_mdCursorBlink_ctbrf_1`,compact:`_compact_ctbrf_197`};function we(e){let t=e.replace(/```(?:json|tool|data|xml|csv)[^\n]*\n[\s\S]*?```/g,``).replace(/```[^\n]*\n\s*[{\[]([\s\S]*?)```/g,``).replace(/^```\s*$/gm,``),n=``,r=0,i=!1;for(let e=0;e<t.length;e++){let a=t[e];a===`{`&&(r++,r===1&&/"action"\s*:/.test(t.slice(e,e+80))&&(i=!0)),i||(n+=a),a===`}`&&(r=Math.max(0,r-1),i&&r===0&&(i=!1))}return n.replace(/\n{3,}/g,`
61
61
 
62
- `).trim()}var Te={browser_open:`Opening page`,browser_screenshot:`Taking screenshot`,browser_click:`Clicking element`,browser_type:`Typing text`,browser_extract:`Extracting content`,browser_js:`Running JavaScript`,browser_wait:`Waiting for element`,browser_scroll:`Scrolling page`,browser_key:`Pressing key`,browser_close:`Closing browser`,web_search:`Searching the web`,fetch_url:`Fetching URL`,gmail_list:`Searching emails`,gmail_read:`Reading email`,gmail_send:`Sending email`,calendar_today:`Loading calendar`,calendar_create:`Creating event`};function Ee(){let e=j(),[t,n]=(0,_.useState)([]),[r,i]=(0,_.useState)(null),[a,o]=(0,_.useState)([]),[s,c]=(0,_.useState)(()=>localStorage.getItem(`nha_conv_sidebar`)!==`hidden`),[l,u]=(0,_.useState)(``),[d,f]=(0,_.useState)(!1),p=(0,_.useRef)(null),[m,h]=(0,_.useState)(null),[g,v]=(0,_.useState)(null),y=(0,_.useRef)(null),b=(0,_.useRef)(null),[x,S]=(0,_.useState)(!1),[C,w]=(0,_.useState)(!1),ee=(0,_.useRef)(null),[T,ne]=(0,_.useState)(null),[ie,O]=(0,_.useState)(!1),[ae,A]=(0,_.useState)(null),[oe,se]=(0,_.useState)(``),[ce,le]=(0,_.useState)([]),[ue,de]=(0,_.useState)(!1),[M,fe]=(0,_.useState)(!1),pe=(0,_.useRef)(null),me=(0,_.useRef)(null),he=(0,_.useRef)(null);(0,_.useEffect)(()=>{pe.current?.scrollIntoView({behavior:`smooth`})},[a]),(0,_.useEffect)(()=>{E(`/api/config`).then(e=>{e&&(e.thinking===!0||e.thinking===`on`||e.thinking===`true`)&&S(!0)}),ge().then(e=>{e&&e.length>0?_e(e[0].id):ve()});try{let e=sessionStorage.getItem(`nha_chat_prefill`)??sessionStorage.getItem(`nha_studio_import`);e&&(u(e),sessionStorage.removeItem(`nha_chat_prefill`),sessionStorage.removeItem(`nha_studio_import`),setTimeout(()=>me.current?.focus(),100))}catch{}},[]);let ge=(0,_.useCallback)(async()=>{let e=(await E(`/api/conversations`))?.conversations??[];return n(e),e},[]),_e=(0,_.useCallback)(async e=>{let t=await E(`/api/conversations/${e}`);t?.conversation&&(i(t.conversation.id),o(t.conversation.messages??[]))},[]),ve=(0,_.useCallback)(async()=>{let e=await D(`/api/conversations`,{});e?.conversation&&(i(e.conversation.id),o([]),ge())},[ge]),ye=(0,_.useCallback)(async e=>{let t=te.getState().apiBase;await fetch(`${t}/api/conversations/${e}`,{method:`DELETE`}),ge().then(t=>{e===r&&(t.length>0?_e(t[0].id):ve())})},[r,ge,_e,ve]),be=()=>{r&&window.open(`/api/conversations/${r}/export?format=md`,`_blank`)},xe=()=>{let e=!x;S(e),D(`/api/config`,{key:`thinking`,value:e?`on`:`off`}).catch(()=>{})},Ee=()=>{c(e=>{let t=!e;return localStorage.setItem(`nha_conv_sidebar`,t?`visible`:`hidden`),t})},P=e=>{let t=e.target.files?.[0];if(!t)return;let n=t.name.toLowerCase().endsWith(`.pdf`)||t.type===`application/pdf`,r=new FileReader;n?(r.onload=e=>{let n=(e.target?.result).split(`,`)[1];h({name:t.name,size:t.size,base64:n,mimeType:`application/pdf`,isPDF:!0}),v(null)},r.readAsDataURL(t)):(r.onload=e=>{h({name:t.name,size:t.size,content:e.target?.result}),v(null)},r.readAsText(t))},De=e=>{let t=e.target.files?.[0];if(!t)return;let n=new FileReader;n.onload=e=>{let n=(e.target?.result).split(`,`)[1];v({name:t.name,size:t.size,base64:n,mimeType:t.type||`image/jpeg`}),h(null)},n.readAsDataURL(t)},Oe=()=>{h(null),v(null),y.current&&(y.current.value=``),b.current&&(b.current.value=``)},ke=m?`[file] ${m.name} (${Math.round(m.size/1024)}KB)`:g?`[img] ${g.name} (${Math.round(g.size/1024)}KB)`:null,F=()=>{let e=window.SpeechRecognition??window.webkitSpeechRecognition;if(!e){alert(`Speech recognition not supported in this browser.`);return}if(C&&ee.current){ee.current.stop(),w(!1);return}let t=new e;ee.current=t,t.lang=`it-IT`,t.continuous=!1,t.interimResults=!1,t.onresult=e=>{let t=e.results[0][0].transcript;u(e=>e?e+` `+t:t)},t.onend=()=>w(!1),t.onerror=()=>w(!1),t.start(),w(!0)},I=(0,_.useCallback)(async()=>{let t=l.trim(),n=!!(m||g);if(!t&&!n||d)return;let i={role:`user`,content:m?(t?t+` `:``)+`[File: ${m.name}]`:g?(t?t+` `:``)+`[Image: ${g.name}]`:t};if(o(e=>[...e,i]),u(``),n){let n={message:t||`Analyze this attachment`,history:a.map(e=>({role:e.role,content:e.content}))};m?.isPDF&&m.base64?(n.pdfBase64=m.base64,n.pdfName=m.name):m?.content&&(n.fileContent=m.content,n.fileName=m.name),g?.base64&&(n.imageBase64=g.base64,n.imageMimeType=g.mimeType),Oe(),o(t=>[...t,{role:`assistant`,content:e(`chat.thinking`),streaming:!0}]),f(!0);try{let e=await D(`/api/chat`,n);o(t=>{let n=[...t],r=n[n.length-1];return r?.role===`assistant`&&(n[n.length-1]={...r,content:e?.response??(e?.error?`Error: `+e.error:`Error`),streaming:!1}),n}),ge()}catch(e){o(t=>{let n=[...t],r=n[n.length-1];return r?.role===`assistant`&&(n[n.length-1]={...r,content:`Error: `+e.message,streaming:!1}),n})}finally{f(!1)}return}Oe(),f(!0),le([]),de(!1),fe(!0);let s=new AbortController;p.current=s,o(e=>[...e,{role:`assistant`,content:``,streaming:!0}]);let c=a.map(e=>({role:e.role,content:e.content})),h;if(c.length>10){let e=c.slice(0,c.length-10);h=[{role:`user`,content:e.reduce((t,n,r)=>n.role===`user`?t+`\nUser: ${n.content.slice(0,120)}`:r>0&&e[r-1]?.role===`user`?t+` → ${n.content.slice(0,150)}`:t,`[Earlier conversation summary]:`)},{role:`assistant`,content:`Understood, I have context from our earlier conversation.`},...c.slice(-10)]}else h=c;try{let e=``,n=!1,i=[];await re(`/api/chat/stream`,{message:t,history:h,conversationId:r},t=>{if(t.type===`processing`&&fe(!0),t.type===`token`&&typeof t.data.content==`string`){fe(!1),n&&e===``&&o(e=>{let t=[...e],n=t[t.length-1];return n?.role===`assistant`&&(t[t.length-1]={...n,content:``}),t}),e+=t.data.content;let r=e,i=r.includes(`<think>`)&&!r.includes(`</think>`);if(de(i),i)return;r=we(r.replace(/<think>[\s\S]*?<\/think>/g,``)),o(e=>{let t=[...e],n=t[t.length-1];return n?.role===`assistant`&&(t[t.length-1]={...n,content:r}),t})}if(t.type===`tool`){let n=t.data.action,r=t.data.status,i=Te[n]??n,a=r===`executing`?`active`:r===`error`?`error`:`done`;le(e=>{let t=e.findIndex(e=>e.action===n&&e.status===`active`);if(t>=0){let r=[...e];return r[t]={action:n,label:i,status:a},r}return[...e,{action:n,label:i,status:a}]}),r===`executing`&&(e=we(e))}if(t.type===`tool_synthesis`&&(e=``,n=!0,de(!1),fe(!0)),t.type===`screenshot`&&typeof t.data.url==`string`&&i.push(t.data.url),t.type===`canvas`&&typeof t.data.markers==`string`){let e=t.data.markers.match(/\[CANVAS_RENDER\]([\s\S]*?)\[\/CANVAS_RENDER\]/);if(e)try{ne(JSON.parse(e[1]).html),O(!0)}catch{}}if(t.type===`done`){de(!1),fe(!1),le(e=>e.map(e=>e.status===`active`?{...e,status:`done`}:e));let n=t.data.content,r=!!t.data.__sentinel_blocked,a=(n??e).replace(/<think>[\s\S]*?<\/think>/g,``),s=a.match(/\[CANVAS_RENDER\]([\s\S]*?)\[\/CANVAS_RENDER\]/);if(s)try{ne(JSON.parse(s[1]).html),O(!0)}catch{ne(s[1]),O(!0)}if(!s){let e=a.match(/```html\n([\s\S]*?)```/);e&&e[1].includes(`<`)&&(ne(e[1]),O(!0))}let c=i.length>0?`
62
+ `).trim()}var Te={browser_open:`Opening page`,browser_screenshot:`Taking screenshot`,browser_click:`Clicking element`,browser_type:`Typing text`,browser_extract:`Extracting content`,browser_js:`Running JavaScript`,browser_wait:`Waiting for element`,browser_scroll:`Scrolling page`,browser_key:`Pressing key`,browser_close:`Closing browser`,web_search:`Searching the web`,fetch_url:`Fetching URL`,gmail_list:`Searching emails`,gmail_read:`Reading email`,gmail_send:`Sending email`,calendar_today:`Loading calendar`,calendar_create:`Creating event`};function Ee(){let e=j(),[t,n]=(0,_.useState)([]),[r,i]=(0,_.useState)(null),[a,o]=(0,_.useState)([]),[s,c]=(0,_.useState)(()=>localStorage.getItem(`nha_conv_sidebar`)!==`hidden`),[l,u]=(0,_.useState)(``),[d,f]=(0,_.useState)(!1),p=(0,_.useRef)(null),[m,h]=(0,_.useState)(null),[g,v]=(0,_.useState)(null),y=(0,_.useRef)(null),b=(0,_.useRef)(null),[x,S]=(0,_.useState)(!1),[C,w]=(0,_.useState)(!1),ee=(0,_.useRef)(null),[T,ne]=(0,_.useState)(null),[ie,O]=(0,_.useState)(!1),[ae,A]=(0,_.useState)(null),[oe,se]=(0,_.useState)(``),[ce,le]=(0,_.useState)([]),[ue,de]=(0,_.useState)(!1),[M,fe]=(0,_.useState)(!1),pe=(0,_.useRef)(null),me=(0,_.useRef)(null),he=(0,_.useRef)(null);(0,_.useEffect)(()=>{pe.current?.scrollIntoView({behavior:`smooth`})},[a]),(0,_.useEffect)(()=>{E(`/api/config`).then(e=>{e&&(e.thinking===!0||e.thinking===`on`||e.thinking===`true`)&&S(!0)}),ge().then(e=>{e&&e.length>0?_e(e[0].id):ve()});try{let e=sessionStorage.getItem(`nha_chat_prefill`)??sessionStorage.getItem(`nha_studio_import`);e&&(u(e),sessionStorage.removeItem(`nha_chat_prefill`),sessionStorage.removeItem(`nha_studio_import`),setTimeout(()=>me.current?.focus(),100))}catch{}},[]);let ge=(0,_.useCallback)(async()=>{let e=(await E(`/api/conversations`))?.conversations??[];return n(e),e},[]),_e=(0,_.useCallback)(async e=>{let t=await E(`/api/conversations/${e}`);t?.conversation&&(i(t.conversation.id),o(t.conversation.messages??[]))},[]),ve=(0,_.useCallback)(async()=>{let e=await D(`/api/conversations`,{});e?.conversation&&(i(e.conversation.id),o([]),ge())},[ge]),ye=(0,_.useCallback)(async e=>{let t=te.getState().apiBase;await fetch(`${t}/api/conversations/${e}`,{method:`DELETE`}),ge().then(t=>{e===r&&(t.length>0?_e(t[0].id):ve())})},[r,ge,_e,ve]),be=()=>{r&&window.open(`/api/conversations/${r}/export?format=md`,`_blank`)},xe=()=>{let e=!x;S(e),D(`/api/config`,{key:`thinking`,value:e?`on`:`off`}).catch(()=>{})},Ee=()=>{c(e=>{let t=!e;return localStorage.setItem(`nha_conv_sidebar`,t?`visible`:`hidden`),t})},P=e=>{let t=e.target.files?.[0];if(!t)return;let n=t.name.toLowerCase().endsWith(`.pdf`)||t.type===`application/pdf`,r=new FileReader;n?(r.onload=e=>{let n=(e.target?.result).split(`,`)[1];h({name:t.name,size:t.size,base64:n,mimeType:`application/pdf`,isPDF:!0}),v(null)},r.readAsDataURL(t)):(r.onload=e=>{h({name:t.name,size:t.size,content:e.target?.result}),v(null)},r.readAsText(t))},De=e=>{let t=e.target.files?.[0];if(!t)return;let n=new FileReader;n.onload=e=>{let n=(e.target?.result).split(`,`)[1];v({name:t.name,size:t.size,base64:n,mimeType:t.type||`image/jpeg`}),h(null)},n.readAsDataURL(t)},Oe=()=>{h(null),v(null),y.current&&(y.current.value=``),b.current&&(b.current.value=``)},ke=m?`[file] ${m.name} (${Math.round(m.size/1024)}KB)`:g?`[img] ${g.name} (${Math.round(g.size/1024)}KB)`:null,F=()=>{let e=window.SpeechRecognition??window.webkitSpeechRecognition;if(!e){alert(`Speech recognition not supported in this browser.`);return}if(C&&ee.current){ee.current.stop(),w(!1);return}let t=new e;ee.current=t,t.lang=`it-IT`,t.continuous=!1,t.interimResults=!1,t.onresult=e=>{let t=e.results[0][0].transcript;u(e=>e?e+` `+t:t)},t.onend=()=>w(!1),t.onerror=()=>w(!1),t.start(),w(!0)},I=(0,_.useCallback)(async()=>{let t=l.trim(),n=!!(m||g);if(!t&&!n||d)return;let i={role:`user`,content:m?(t?t+` `:``)+`[File: ${m.name}]`:g?(t?t+` `:``)+`[Image: ${g.name}]`:t};if(o(e=>[...e,i]),u(``),n){let n={message:t||`Analyze this attachment`,history:a.map(e=>({role:e.role,content:e.content}))};m?.isPDF&&m.base64?(n.pdfBase64=m.base64,n.pdfName=m.name):m?.content&&(n.fileContent=m.content,n.fileName=m.name),g?.base64&&(n.imageBase64=g.base64,n.imageMimeType=g.mimeType),Oe(),o(t=>[...t,{role:`assistant`,content:e(`chat.thinking`),streaming:!0}]),f(!0);try{let e=await D(`/api/chat`,n);o(t=>{let n=[...t],r=n[n.length-1];return r?.role===`assistant`&&(n[n.length-1]={...r,content:e?.response??(e?.error?`Error: `+e.error:`Error`),streaming:!1}),n}),ge()}catch(e){o(t=>{let n=[...t],r=n[n.length-1];return r?.role===`assistant`&&(n[n.length-1]={...r,content:`Error: `+e.message,streaming:!1}),n})}finally{f(!1)}return}Oe(),f(!0),le([]),de(!1),fe(!0);let s=new AbortController;p.current=s,o(e=>[...e,{role:`assistant`,content:``,streaming:!0}]);let c=a.map(e=>({role:e.role,content:e.content})),h;if(c.length>10){let e=c.slice(0,c.length-10);h=[{role:`user`,content:e.reduce((t,n,r)=>n.role===`user`?t+`\nUser: ${n.content.slice(0,120)}`:r>0&&e[r-1]?.role===`user`?t+` → ${n.content.slice(0,150)}`:t,`[Earlier conversation summary]:`)},{role:`assistant`,content:`Understood, I have context from our earlier conversation.`},...c.slice(-10)]}else h=c;try{let e=``,n=``,i=!1,a=[];await re(`/api/chat/stream`,{message:t,history:h,conversationId:r},t=>{if(t.type===`processing`&&fe(!0),t.type===`token`&&typeof t.data.content==`string`){fe(!1),e+=t.data.content;let r=we(e.replace(/<think>[\s\S]*?<\/think>/g,``)),a=e.includes(`<think>`)&&!e.includes(`</think>`);if(de(a),a)return;let s=i&&n?`${n}\n\n${r}`:r;o(e=>{let t=[...e],n=t[t.length-1];return n?.role===`assistant`&&(t[t.length-1]={...n,content:s}),t})}if(t.type===`tool`){let n=t.data.action,r=t.data.status,i=Te[n]??n,a=r===`executing`?`active`:r===`error`?`error`:`done`;le(e=>{let t=e.findIndex(e=>e.action===n&&e.status===`active`);if(t>=0){let r=[...e];return r[t]={action:n,label:i,status:a},r}return[...e,{action:n,label:i,status:a}]}),r===`executing`&&(e=we(e))}if(t.type===`tool_synthesis`&&(n=we(e.replace(/<think>[\s\S]*?<\/think>/g,``)).trim(),e=``,i=!0,de(!1),fe(!0)),t.type===`screenshot`&&typeof t.data.url==`string`&&a.push(t.data.url),t.type===`canvas`&&typeof t.data.markers==`string`){let e=t.data.markers.match(/\[CANVAS_RENDER\]([\s\S]*?)\[\/CANVAS_RENDER\]/);if(e)try{ne(JSON.parse(e[1]).html),O(!0)}catch{}}if(t.type===`done`){de(!1),fe(!1),le(e=>e.map(e=>e.status===`active`?{...e,status:`done`}:e));let n=t.data.content,r=!!t.data.__sentinel_blocked,i=(n??e).replace(/<think>[\s\S]*?<\/think>/g,``),s=i.match(/\[CANVAS_RENDER\]([\s\S]*?)\[\/CANVAS_RENDER\]/);if(s)try{ne(JSON.parse(s[1]).html),O(!0)}catch{ne(s[1]),O(!0)}if(!s){let e=i.match(/```html\n([\s\S]*?)```/);e&&e[1].includes(`<`)&&(ne(e[1]),O(!0))}let c=a.length>0?`
63
63
 
64
- `+i.map(e=>`![Screenshot](${e})`).join(`
65
- `):``,l=we(a.replace(/\[CANVAS_RENDER\][\s\S]*?\[\/CANVAS_RENDER\]/g,``).replace(/```html[\s\S]*?```/g,`[Canvas HTML — click Panel to view]`))+c;o(r?e=>{let t=[...e],n=t.findIndex((e,n)=>n===t.length-1&&e.role===`assistant`);return n>=0&&(t[n]={role:`assistant`,content:l||`Message blocked by SENTINEL.`,sentinelBlocked:!0,streaming:!1}),t}:e=>{let t=[...e],n=t[t.length-1];return n?.role===`assistant`&&(t[t.length-1]={...n,content:l,streaming:!1}),t}),ge()}t.type===`error`&&o(e=>{let n=[...e],r=n[n.length-1];return r?.role===`assistant`&&(n[n.length-1]={...r,content:`Error: `+(t.data.message??`Unknown`),streaming:!1}),n})},s.signal)}catch(e){e.name!==`AbortError`&&o(e=>{let t=[...e],n=t[t.length-1];return n?.role===`assistant`&&(t[t.length-1]={...n,content:n.content||`Error connecting to server.`,streaming:!1}),t})}finally{de(!1),fe(!1),o(e=>{let t=[...e],n=t[t.length-1];return n?.role===`assistant`&&n.streaming&&(t[t.length-1]={...n,streaming:!1}),t}),f(!1),p.current=null,setTimeout(()=>le([]),2e3)}},[l,a,d,m,g,r,ge]),Ae=()=>{p.current?.abort(),f(!1)},je=e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),I())},Me=e=>{navigator.clipboard.writeText(e.replace(/\[CANVAS_RENDER\][\s\S]*?\[\/CANVAS_RENDER\]/g,``).trim()).catch(()=>{})},Ne=(0,_.useCallback)(async t=>{if(d)return;let n=t-1;if(n<0||a[n]?.role!==`user`)return;let i=a[n],s=a.slice(0,n).map(e=>({role:e.role,content:e.content}));o(e=>{let n=[...e];return n[t]={role:`assistant`,content:``,streaming:!0},n.slice(0,t+1)}),f(!0);let c=new AbortController;p.current=c;let l=``;try{await re(`/api/chat/stream`,{message:i.content,history:s,conversationId:r},t=>{if(t.type===`token`&&typeof t.data.content==`string`){l+=t.data.content;let n=l;n=n.includes(`<think>`)&&!n.includes(`</think>`)?`💭 `+e(`chat.thinking`):we(n.replace(/<think>[\s\S]*?<\/think>/g,``)),o(e=>{let t=[...e],r=t[t.length-1];return r?.role===`assistant`&&(t[t.length-1]={...r,content:n}),t})}if(t.type===`tool_synthesis`&&(l=``,o(e=>{let t=[...e],n=t[t.length-1];return n?.role===`assistant`&&(t[t.length-1]={...n,content:``}),t})),t.type===`done`){let e=we((t.data.content??l).replace(/<think>[\s\S]*?<\/think>/g,``));o(t=>{let n=[...t],r=n[n.length-1];return r?.role===`assistant`&&(n[n.length-1]={...r,content:e,streaming:!1}),n}),ge()}},c.signal)}catch{}finally{f(!1),p.current=null}},[d,a,r,ge,e]),Pe=e=>{d||(A(e),se(a[e].content))},Fe=(0,_.useCallback)(async()=>{if(ae===null)return;let t=oe.trim();if(!t)return;let n=a.slice(0,ae).map(e=>({role:e.role,content:e.content}));o(e=>{let n=e.slice(0,ae);return n.push({role:`user`,content:t}),n.push({role:`assistant`,content:``,streaming:!0}),n}),A(null),se(``),f(!0);let i=new AbortController;p.current=i;let s=``;try{await re(`/api/chat/stream`,{message:t,history:n,conversationId:r},t=>{if(t.type===`token`&&typeof t.data.content==`string`){s+=t.data.content;let n=s;n=n.includes(`<think>`)&&!n.includes(`</think>`)?`💭 `+e(`chat.thinking`):we(n.replace(/<think>[\s\S]*?<\/think>/g,``)),o(e=>{let t=[...e],r=t[t.length-1];return r?.role===`assistant`&&(t[t.length-1]={...r,content:n}),t})}if(t.type===`tool_synthesis`&&(s=``,o(e=>{let t=[...e],n=t[t.length-1];return n?.role===`assistant`&&(t[t.length-1]={...n,content:``}),t})),t.type===`done`){let e=we((t.data.content??s).replace(/<think>[\s\S]*?<\/think>/g,``));o(t=>{let n=[...t],r=n[n.length-1];return r?.role===`assistant`&&(n[n.length-1]={...r,content:e,streaming:!1}),n}),ge()}},i.signal)}catch{}finally{f(!1),p.current=null}},[ae,oe,a,r,ge,e]);return(0,k.jsxs)(`div`,{className:N.root,children:[s&&(0,k.jsxs)(`div`,{className:N.convSidebar,children:[(0,k.jsx)(`div`,{className:N.convSidebarHeader,children:(0,k.jsxs)(`button`,{className:N.newConvBtn,onClick:ve,children:[`+ `,e(`chat.newChat`)]})}),(0,k.jsx)(`div`,{className:N.convList,children:t.map(t=>{let n=Math.floor(t.messageCount/2),i=t.id===r;return(0,k.jsxs)(`div`,{className:`${N.convItem} ${i?N.convItemActive:``}`,onClick:()=>_e(t.id),children:[(0,k.jsx)(`div`,{className:N.convTitle,children:t.title||e(`chat.newChat`)}),(0,k.jsxs)(`div`,{className:N.convMeta,children:[(0,k.jsxs)(`span`,{children:[n,` turns`]}),!i&&(0,k.jsx)(`span`,{className:N.convDelete,onClick:e=>{e.stopPropagation(),ye(t.id)},children:`del`})]})]},t.id)})})]}),(0,k.jsxs)(`div`,{className:N.chatMain,children:[(0,k.jsxs)(`div`,{className:N.chatToolbar,children:[(0,k.jsx)(`button`,{className:N.toolbarBtn,onClick:Ee,title:`Toggle conversations`,children:`💬 Chats`}),(0,k.jsx)(`span`,{className:N.convTitleBar,children:t.find(e=>e.id===r)?.title||e(`chat.newChat`)}),(0,k.jsx)(`button`,{className:N.toolbarBtn,onClick:ve,children:`+ New`}),(0,k.jsx)(`button`,{className:N.toolbarBtnDim,onClick:be,title:`Export Markdown`,children:`Export`}),T&&(0,k.jsx)(`button`,{className:`${N.toolbarBtn} ${N.toolbarBtnCanvas}`,onClick:()=>O(e=>!e),title:`Toggle canvas panel`,children:ie?`▣ Panel ✕`:`▣ Panel`})]}),(0,k.jsxs)(`div`,{className:N.messages,ref:he,children:[a.length===0&&(0,k.jsxs)(`div`,{className:N.empty,children:[(0,k.jsx)(`div`,{className:N.emptyIcon,children:`💬`}),(0,k.jsx)(`div`,{className:N.emptyTitle,children:`NHA Chat`}),(0,k.jsx)(`div`,{className:N.emptySub,children:`Personal Operations Assistant · 80 Tools · 38 Agents · Free AI`}),(0,k.jsxs)(`div`,{className:N.suggGroups,children:[(0,k.jsxs)(`div`,{className:N.suggGroup,children:[(0,k.jsx)(`div`,{className:N.suggGroupTitle,children:`⚡ Quick Actions`}),(0,k.jsx)(`div`,{className:N.suggBtns,children:[`Show my unread emails and summarize the most important ones`,`What's on my calendar today? Any meetings I need to prepare for?`,`List my pending tasks sorted by priority`,`Check my GitHub notifications and summarize open issues`].map(e=>(0,k.jsx)(`button`,{className:N.suggBtn,onClick:()=>u(e),children:e},e))})]}),(0,k.jsxs)(`div`,{className:N.suggGroup,children:[(0,k.jsx)(`div`,{className:N.suggGroupTitle,children:`🌐 Web & Research`}),(0,k.jsx)(`div`,{className:N.suggBtns,children:[`Search the web for the latest AI news and summarize the top 5 stories`,`Open google.com and take a screenshot of the homepage`,`Search for the best restaurants near me and create a summary`,`Research the latest developments in quantum computing and write a report`].map(e=>(0,k.jsx)(`button`,{className:N.suggBtn,onClick:()=>u(e),children:e},e))})]}),(0,k.jsxs)(`div`,{className:N.suggGroup,children:[(0,k.jsx)(`div`,{className:N.suggGroupTitle,children:`🛠️ Productivity`}),(0,k.jsx)(`div`,{className:N.suggBtns,children:[`Draft a professional reply to my last email`,`Create a new calendar event for tomorrow at 10am with reminder`,`Summarize my notes and create a to-do list from action items`,`Find contacts named Mario and show their details`].map(e=>(0,k.jsx)(`button`,{className:N.suggBtn,onClick:()=>u(e),children:e},e))})]}),(0,k.jsxs)(`div`,{className:N.suggGroup,children:[(0,k.jsx)(`div`,{className:N.suggGroupTitle,children:`📈 Finance`}),(0,k.jsx)(`div`,{className:N.suggBtns,children:[`What is the current price of Bitcoin and its 24h performance?`,`Analyze the current macro environment and suggest 3 trading opportunities`,`What is the current market regime? Risk-on or risk-off?`,`Give me a technical analysis of AAPL with key support/resistance levels`].map(e=>(0,k.jsx)(`button`,{className:N.suggBtn,onClick:()=>u(e),children:e},e))})]})]})]}),a.map((e,t)=>(0,k.jsxs)(`div`,{className:`${N.message} ${N[e.role]}`,children:[(0,k.jsx)(`div`,{className:N.msgLabel,children:e.role===`user`?`You`:`NHA`}),e.role===`assistant`&&e.streaming&&(0,k.jsxs)(`div`,{className:N.toolActivity,children:[(M||e.content===``&&!ue&&ce.length===0)&&(0,k.jsxs)(`div`,{className:N.thinkingIndicator,children:[(0,k.jsxs)(`div`,{className:N.thinkingDots,children:[(0,k.jsx)(`div`,{className:N.thinkingDot}),(0,k.jsx)(`div`,{className:N.thinkingDot}),(0,k.jsx)(`div`,{className:N.thinkingDot})]}),ue?`Deep thinking...`:`Generating...`]}),ue&&!M&&(0,k.jsxs)(`div`,{className:N.thinkingIndicator,children:[(0,k.jsxs)(`div`,{className:N.thinkingDots,children:[(0,k.jsx)(`div`,{className:N.thinkingDot}),(0,k.jsx)(`div`,{className:N.thinkingDot}),(0,k.jsx)(`div`,{className:N.thinkingDot})]}),`Deep thinking...`]}),ce.map((e,t)=>(0,k.jsxs)(`div`,{className:`${N.toolActivityItem} ${N[e.status]}`,children:[e.status===`active`?`⏳`:e.status===`error`?`❌`:`✅`,` `,e.label,e.status===`active`&&`...`]},t))]}),e.role===`user`&&ae===t?(0,k.jsxs)(`div`,{className:N.editBox,children:[(0,k.jsx)(`textarea`,{className:N.editInput,value:oe,onChange:e=>se(e.target.value),onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),Fe()),e.key===`Escape`&&A(null)},autoFocus:!0,rows:3}),(0,k.jsxs)(`div`,{className:N.editActions,children:[(0,k.jsx)(`button`,{className:N.editSaveBtn,onClick:Fe,children:`Send ↵`}),(0,k.jsx)(`button`,{className:N.editCancelBtn,onClick:()=>A(null),children:`Cancel`})]})]}):e.role===`assistant`?e.content!==``&&(0,k.jsx)(`div`,{className:`${N.bubble} ${Ce.body} ${e.sentinelBlocked?N.sentinelBubble:``}`,dangerouslySetInnerHTML:{__html:Se(e.content)}}):(0,k.jsx)(`div`,{className:N.bubble,children:e.content}),e.streaming&&(0,k.jsx)(`span`,{className:N.cursor}),!e.streaming&&ae!==t&&(0,k.jsxs)(`div`,{className:N.msgActions,children:[(0,k.jsx)(`button`,{className:N.msgActionBtn,onClick:()=>Me(e.content),children:`Copy`}),e.role===`user`&&!d&&(0,k.jsx)(`button`,{className:N.msgActionBtn,onClick:()=>Pe(t),children:`Edit`}),e.role===`assistant`&&!d&&(0,k.jsx)(`button`,{className:N.msgActionBtn,onClick:()=>Ne(t),children:`Retry`})]})]},t)),(0,k.jsx)(`div`,{ref:pe})]}),ke&&(0,k.jsxs)(`div`,{className:N.attachBar,children:[(0,k.jsx)(`span`,{children:ke}),(0,k.jsx)(`button`,{className:N.attachClear,onClick:Oe,children:`×`})]}),(0,k.jsxs)(`div`,{className:N.inputBar,children:[(0,k.jsxs)(`div`,{className:N.inputTools,children:[(0,k.jsx)(`button`,{className:`${N.iconBtn} ${C?N.iconBtnActive:``}`,onClick:F,title:`Voice input`,children:`🎤`}),(0,k.jsx)(`button`,{className:N.iconBtn,onClick:()=>y.current?.click(),title:`Attach file`,children:`📎`}),(0,k.jsx)(`button`,{className:N.iconBtn,onClick:()=>b.current?.click(),title:`Attach image`,children:`🖼`}),(0,k.jsx)(`input`,{ref:y,type:`file`,style:{display:`none`},onChange:P}),(0,k.jsx)(`input`,{ref:b,type:`file`,accept:`image/*`,style:{display:`none`},onChange:De}),(0,k.jsx)(`span`,{style:{flex:1}}),(0,k.jsxs)(`button`,{className:`${N.thinkBtn} ${x?N.thinkBtnOn:``}`,onClick:xe,title:`Extended Thinking`,children:[`Think: `,x?`on`:`off`]}),T&&(0,k.jsx)(`button`,{className:N.toolbarBtn,onClick:()=>O(e=>!e),title:`Canvas panel`,children:`▣ Panel`})]}),(0,k.jsxs)(`div`,{className:N.inputRow,children:[(0,k.jsx)(`textarea`,{ref:me,className:N.input,value:l,onChange:e=>u(e.target.value),onKeyDown:je,placeholder:e(`chat.placeholder`),rows:1,disabled:d}),d?(0,k.jsxs)(`button`,{className:`${N.btn} ${N.stop}`,onClick:Ae,children:[`■ `,e(`chat.stopGeneration`)]}):(0,k.jsx)(`button`,{className:`${N.btn} ${N.send}`,onClick:I,disabled:!l.trim()&&!m&&!g,children:`Send ↵`})]})]})]}),ie&&T&&(0,k.jsxs)(`div`,{className:N.canvasPanel,children:[(0,k.jsxs)(`div`,{className:N.canvasPanelHeader,children:[(0,k.jsx)(`span`,{children:`Canvas`}),(0,k.jsxs)(`div`,{className:N.canvasPanelActions,children:[(0,k.jsx)(`button`,{className:N.canvasPanelBtn,onClick:()=>{let e=new Blob([T],{type:`text/html`}),t=URL.createObjectURL(e),n=document.createElement(`a`);n.href=t,n.download=`NHA-Canvas.html`,n.click(),setTimeout(()=>URL.revokeObjectURL(t),5e3)},children:`↓ Download`}),(0,k.jsx)(`button`,{className:N.canvasPanelBtn,onClick:()=>navigator.clipboard.writeText(T).catch(()=>{}),children:`Copy HTML`}),(0,k.jsx)(`button`,{className:N.canvasPanelClose,onClick:()=>O(!1),children:`×`})]})]}),(0,k.jsx)(`iframe`,{className:N.canvasFrame,sandbox:`allow-scripts`,srcDoc:T,title:`Canvas`})]})]})}var P={root:`_root_1899x_1`,header:`_header_1899x_8`,headerLeft:`_headerLeft_1899x_19`,title:`_title_1899x_21`,subtitle:`_subtitle_1899x_28`,headerActions:`_headerActions_1899x_34`,tokenBar:`_tokenBar_1899x_41`,tokIn:`_tokIn_1899x_49`,tokOut:`_tokOut_1899x_50`,tokTotal:`_tokTotal_1899x_51`,tokDim:`_tokDim_1899x_52`,sessionsBtn:`_sessionsBtn_1899x_54`,pdfBtn:`_pdfBtn_1899x_66`,clearBtn:`_clearBtn_1899x_76`,sessionsDrawer:`_sessionsDrawer_1899x_89`,noSessions:`_noSessions_1899x_104`,sessionItem:`_sessionItem_1899x_111`,sessionInfo:`_sessionInfo_1899x_121`,sessionTask:`_sessionTask_1899x_127`,sessionMeta:`_sessionMeta_1899x_137`,sessionBtns:`_sessionBtns_1899x_143`,importBtn:`_importBtn_1899x_149`,delSessionBtn:`_delSessionBtn_1899x_159`,sessionsFooter:`_sessionsFooter_1899x_169`,clearAllSessionsBtn:`_clearAllSessionsBtn_1899x_176`,inputArea:`_inputArea_1899x_189`,inputRow:`_inputRow_1899x_198`,taskInput:`_taskInput_1899x_204`,inputControls:`_inputControls_1899x_219`,runBtn:`_runBtn_1899x_225`,stopBtn:`_stopBtn_1899x_238`,attachBtn:`_attachBtn_1899x_249`,attachBadge:`_attachBadge_1899x_262`,clearAttach:`_clearAttach_1899x_275`,examples:`_examples_1899x_284`,exampleBtn:`_exampleBtn_1899x_290`,body:`_body_1899x_308`,agentChip:`_agentChip_1899x_321`,chip_running:`_chip_running_1899x_332`,charCardPulse:`_charCardPulse_1899x_1`,chip_done:`_chip_done_1899x_338`,chip_error:`_chip_error_1899x_339`,chip_waiting:`_chip_waiting_1899x_340`,chipIcon:`_chipIcon_1899x_341`,chipLabel:`_chipLabel_1899x_342`,chipDots:`_chipDots_1899x_343`,chipCheck:`_chipCheck_1899x_344`,chipErr:`_chipErr_1899x_345`,officeSceneWrap:`_officeSceneWrap_1899x_348`,pipeline:`_pipeline_1899x_358`,pipelineWrap:`_pipelineWrap_1899x_373`,pipelineRunning:`_pipelineRunning_1899x_383`,scanSweep:`_scanSweep_1899x_1`,pipelineTitle:`_pipelineTitle_1899x_409`,pipelineNodes:`_pipelineNodes_1899x_417`,pipelineStep:`_pipelineStep_1899x_424`,arrow:`_arrow_1899x_430`,arrowActive:`_arrowActive_1899x_439`,arrowPulse:`_arrowPulse_1899x_1`,agentChar:`_agentChar_1899x_451`,charWaiting:`_charWaiting_1899x_466`,charActive:`_charActive_1899x_471`,charDone:`_charDone_1899x_479`,charError:`_charError_1899x_484`,orbitRing1:`_orbitRing1_1899x_495`,orbitRing2:`_orbitRing2_1899x_496`,orbitSpin1:`_orbitSpin1_1899x_1`,orbitSpin2:`_orbitSpin2_1899x_1`,charAvatar:`_charAvatar_1899x_542`,charIcon:`_charIcon_1899x_557`,iconBob:`_iconBob_1899x_1`,charCheck:`_charCheck_1899x_574`,badgePop:`_badgePop_1899x_1`,charErr:`_charErr_1899x_484`,charPulse:`_charPulse_1899x_618`,charPulse2:`_charPulse2_1899x_619`,expandRing:`_expandRing_1899x_1`,charLabel:`_charLabel_1899x_638`,charStatus:`_charStatus_1899x_650`,charStatusDots:`_charStatusDots_1899x_663`,dot1:`_dot1_1899x_664`,dot2:`_dot2_1899x_664`,dot3:`_dot3_1899x_664`,dotFade:`_dotFade_1899x_1`,twoCol:`_twoCol_1899x_678`,panelTitle:`_panelTitle_1899x_685`,logPanel:`_logPanel_1899x_695`,logBody:`_logBody_1899x_707`,logEntry:`_logEntry_1899x_715`,logTime:`_logTime_1899x_725`,logIcon:`_logIcon_1899x_726`,logAgent:`_logAgent_1899x_727`,logText:`_logText_1899x_728`,log_system:`_log_system_1899x_730`,log_error:`_log_error_1899x_731`,liveOutputPanel:`_liveOutputPanel_1899x_734`,liveBlock:`_liveBlock_1899x_741`,blockSlideIn:`_blockSlideIn_1899x_1`,liveBlockActive:`_liveBlockActive_1899x_755`,liveBlockScan:`_liveBlockScan_1899x_1`,liveBlockHeader:`_liveBlockHeader_1899x_780`,liveBlockIcon:`_liveBlockIcon_1899x_789`,liveBlockLabel:`_liveBlockLabel_1899x_791`,outputStatus:`_outputStatus_1899x_799`,status_done:`_status_done_1899x_810`,status_running:`_status_running_1899x_811`,status_error:`_status_error_1899x_812`,status_waiting:`_status_waiting_1899x_813`,liveBlockBody:`_liveBlockBody_1899x_816`,liveBlockWorking:`_liveBlockWorking_1899x_954`,workingDot:`_workingDot_1899x_961`,workingBounce:`_workingBounce_1899x_1`,workingLabel:`_workingLabel_1899x_978`,workingFade:`_workingFade_1899x_1`,studioBlinkCursor:`_studioBlinkCursor_1899x_1`,resultAccordion:`_resultAccordion_1899x_1007`,resultAccordionSummary:`_resultAccordionSummary_1899x_1014`,resultAccordionBody:`_resultAccordionBody_1899x_1031`,financeSection:`_financeSection_1899x_1065`,financeSectionTitle:`_financeSectionTitle_1899x_1073`,financePresets:`_financePresets_1899x_1082`,financeBtn:`_financeBtn_1899x_1088`,canvasToggleBtn:`_canvasToggleBtn_1899x_1106`,canvasPanel:`_canvasPanel_1899x_1122`,canvasPanelHeader:`_canvasPanelHeader_1899x_1137`,canvasPanelActions:`_canvasPanelActions_1899x_1149`,canvasPanelBtn:`_canvasPanelBtn_1899x_1155`,canvasPanelClose:`_canvasPanelClose_1899x_1167`,canvasFrame:`_canvasFrame_1899x_1178`,pipelineLiveTag:`_pipelineLiveTag_1899x_1186`,liveTagBlink:`_liveTagBlink_1899x_1`,reasonRow:`_reasonRow_1899x_1200`,reasonChip:`_reasonChip_1899x_1209`,reasonIcon:`_reasonIcon_1899x_1222`,reasonText:`_reasonText_1899x_1223`,liveBlockReason:`_liveBlockReason_1899x_1226`,councilWrapper:`_councilWrapper_1899x_1236`,councilPanel:`_councilPanel_1899x_1241`,councilHeader:`_councilHeader_1899x_1249`,councilHeaderLeft:`_councilHeaderLeft_1899x_1260`,councilHeaderRight:`_councilHeaderRight_1899x_1266`,councilIcon:`_councilIcon_1899x_1272`,councilTitle:`_councilTitle_1899x_1274`,councilConvergedBadge:`_councilConvergedBadge_1899x_1283`,councilDivergedBadge:`_councilDivergedBadge_1899x_1295`,councilPhaseTag:`_councilPhaseTag_1899x_1307`,councilPhaseActive:`_councilPhaseActive_1899x_1313`,phaseGlow:`_phaseGlow_1899x_1`,councilPhaseDone:`_councilPhaseDone_1899x_1322`,councilMetrics:`_councilMetrics_1899x_1325`,convRow:`_convRow_1899x_1333`,convLabel:`_convLabel_1899x_1339`,convTrack:`_convTrack_1899x_1347`,convFill:`_convFill_1899x_1355`,convPct:`_convPct_1899x_1361`,councilNodes:`_councilNodes_1899x_1371`,councilSectionTitle:`_councilSectionTitle_1899x_1376`,councilNode:`_councilNode_1899x_1371`,councilNodeHeader:`_councilNodeHeader_1899x_1393`,councilNodeIcon:`_councilNodeIcon_1899x_1406`,councilNodeLabel:`_councilNodeLabel_1899x_1407`,councilNodeToggle:`_councilNodeToggle_1899x_1408`,councilNodeBody:`_councilNodeBody_1899x_1410`,councilSynthesis:`_councilSynthesis_1899x_1420`,councilSynthesisHeader:`_councilSynthesisHeader_1899x_1424`,heraldIcon:`_heraldIcon_1899x_1433`,heraldLabel:`_heraldLabel_1899x_1435`,heraldStreaming:`_heraldStreaming_1899x_1443`,councilSynthesisBody:`_councilSynthesisBody_1899x_1445`,councilSkipped:`_councilSkipped_1899x_1475`,councilSkipIcon:`_councilSkipIcon_1899x_1486`,charSpriteRunning:`_charSpriteRunning_1899x_1499`,spriteWalk:`_spriteWalk_1899x_1`,charSpriteDone:`_charSpriteDone_1899x_1508`,charScanline:`_charScanline_1899x_1512`,scanlineScroll:`_scanlineScroll_1899x_1`,auraAnim:`_auraAnim_1899x_1532`,auraGlow:`_auraGlow_1899x_1`,parliamentPrompt:`_parliamentPrompt_1899x_1539`,parliamentPromptIcon:`_parliamentPromptIcon_1899x_1549`,parliamentPromptContent:`_parliamentPromptContent_1899x_1550`,parliamentPromptTitle:`_parliamentPromptTitle_1899x_1551`,parliamentPromptDesc:`_parliamentPromptDesc_1899x_1552`,parliamentPromptMeta:`_parliamentPromptMeta_1899x_1553`,parliamentPromptBtns:`_parliamentPromptBtns_1899x_1554`,parliamentActivateBtn:`_parliamentActivateBtn_1899x_1555`,parliamentSkipBtn:`_parliamentSkipBtn_1899x_1562`,panelTabs:`_panelTabs_1899x_1570`,panelTabBtn:`_panelTabBtn_1899x_1571`,panelTabActive:`_panelTabActive_1899x_1578`,panelEmpty:`_panelEmpty_1899x_1580`,browserPanel:`_browserPanel_1899x_1589`,browserBar:`_browserBar_1899x_1590`,browserInput:`_browserInput_1899x_1591`,browserGo:`_browserGo_1899x_1598`,liveBlockClickable:`_liveBlockClickable_1899x_1605`,liveBlockBodyClamped:`_liveBlockBodyClamped_1899x_1614`,expandHint:`_expandHint_1899x_1621`,blockModalOverlay:`_blockModalOverlay_1899x_1630`,blockModal:`_blockModal_1899x_1630`,blockModalHeader:`_blockModalHeader_1899x_1655`,blockModalTitle:`_blockModalTitle_1899x_1665`,blockModalClose:`_blockModalClose_1899x_1673`,blockModalBody:`_blockModalBody_1899x_1685`},De=[{label:`📈 Full Trading Strategy`,task:`You are a team of senior quantitative analysts and macro traders. Build a complete, actionable trading strategy with the following structure:
64
+ `+a.map(e=>`![Screenshot](${e})`).join(`
65
+ `):``,l=we(i.replace(/\[CANVAS_RENDER\][\s\S]*?\[\/CANVAS_RENDER\]/g,``).replace(/```html[\s\S]*?```/g,`[Canvas HTML — click Panel to view]`))+c;o(r?e=>{let t=[...e],n=t.findIndex((e,n)=>n===t.length-1&&e.role===`assistant`);return n>=0&&(t[n]={role:`assistant`,content:l||`Message blocked by SENTINEL.`,sentinelBlocked:!0,streaming:!1}),t}:e=>{let t=[...e],n=t[t.length-1];return n?.role===`assistant`&&(t[t.length-1]={...n,content:l,streaming:!1}),t}),ge()}t.type===`error`&&o(e=>{let n=[...e],r=n[n.length-1];return r?.role===`assistant`&&(n[n.length-1]={...r,content:`Error: `+(t.data.message??`Unknown`),streaming:!1}),n})},s.signal)}catch(e){e.name!==`AbortError`&&o(e=>{let t=[...e],n=t[t.length-1];return n?.role===`assistant`&&(t[t.length-1]={...n,content:n.content||`Error connecting to server.`,streaming:!1}),t})}finally{de(!1),fe(!1),o(e=>{let t=[...e],n=t[t.length-1];return n?.role===`assistant`&&n.streaming&&(t[t.length-1]={...n,streaming:!1}),t}),f(!1),p.current=null,setTimeout(()=>le([]),2e3)}},[l,a,d,m,g,r,ge]),Ae=()=>{p.current?.abort(),f(!1)},je=e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),I())},Me=e=>{navigator.clipboard.writeText(e.replace(/\[CANVAS_RENDER\][\s\S]*?\[\/CANVAS_RENDER\]/g,``).trim()).catch(()=>{})},Ne=(0,_.useCallback)(async t=>{if(d)return;let n=t-1;if(n<0||a[n]?.role!==`user`)return;let i=a[n],s=a.slice(0,n).map(e=>({role:e.role,content:e.content}));o(e=>{let n=[...e];return n[t]={role:`assistant`,content:``,streaming:!0},n.slice(0,t+1)}),f(!0);let c=new AbortController;p.current=c;let l=``,u=``,m=!1;try{await re(`/api/chat/stream`,{message:i.content,history:s,conversationId:r,isRetry:!0},t=>{if(t.type===`token`&&typeof t.data.content==`string`){l+=t.data.content;let n=we(l.replace(/<think>[\s\S]*?<\/think>/g,``)),r=l.includes(`<think>`)&&!l.includes(`</think>`)?`💭 `+e(`chat.thinking`):m&&u?`${u}\n\n${n}`:n;o(e=>{let t=[...e],n=t[t.length-1];return n?.role===`assistant`&&(t[t.length-1]={...n,content:r}),t})}if(t.type===`tool_synthesis`&&(u=we(l.replace(/<think>[\s\S]*?<\/think>/g,``)).trim(),l=``,m=!0),t.type===`done`){let e=we((t.data.content??l).replace(/<think>[\s\S]*?<\/think>/g,``));o(t=>{let n=[...t],r=n[n.length-1];return r?.role===`assistant`&&(n[n.length-1]={...r,content:e,streaming:!1}),n}),ge()}},c.signal)}catch{}finally{f(!1),p.current=null}},[d,a,r,ge,e]),Pe=e=>{d||(A(e),se(a[e].content))},Fe=(0,_.useCallback)(async()=>{if(ae===null)return;let t=oe.trim();if(!t)return;let n=a.slice(0,ae).map(e=>({role:e.role,content:e.content}));o(e=>{let n=e.slice(0,ae);return n.push({role:`user`,content:t}),n.push({role:`assistant`,content:``,streaming:!0}),n}),A(null),se(``),f(!0);let i=new AbortController;p.current=i;let s=``,c=``,l=!1;try{await re(`/api/chat/stream`,{message:t,history:n,conversationId:r,isEdit:!0,editFromIdx:ae},t=>{if(t.type===`token`&&typeof t.data.content==`string`){s+=t.data.content;let n=we(s.replace(/<think>[\s\S]*?<\/think>/g,``)),r=s.includes(`<think>`)&&!s.includes(`</think>`)?`💭 `+e(`chat.thinking`):l&&c?`${c}\n\n${n}`:n;o(e=>{let t=[...e],n=t[t.length-1];return n?.role===`assistant`&&(t[t.length-1]={...n,content:r}),t})}if(t.type===`tool_synthesis`&&(c=we(s.replace(/<think>[\s\S]*?<\/think>/g,``)).trim(),s=``,l=!0),t.type===`done`){let e=we((t.data.content??s).replace(/<think>[\s\S]*?<\/think>/g,``));o(t=>{let n=[...t],r=n[n.length-1];return r?.role===`assistant`&&(n[n.length-1]={...r,content:e,streaming:!1}),n}),ge()}},i.signal)}catch{}finally{f(!1),p.current=null}},[ae,oe,a,r,ge,e]);return(0,k.jsxs)(`div`,{className:N.root,children:[s&&(0,k.jsxs)(`div`,{className:N.convSidebar,children:[(0,k.jsx)(`div`,{className:N.convSidebarHeader,children:(0,k.jsxs)(`button`,{className:N.newConvBtn,onClick:ve,children:[`+ `,e(`chat.newChat`)]})}),(0,k.jsx)(`div`,{className:N.convList,children:t.map(t=>{let n=Math.floor(t.messageCount/2),i=t.id===r;return(0,k.jsxs)(`div`,{className:`${N.convItem} ${i?N.convItemActive:``}`,onClick:()=>_e(t.id),children:[(0,k.jsx)(`div`,{className:N.convTitle,children:t.title||e(`chat.newChat`)}),(0,k.jsxs)(`div`,{className:N.convMeta,children:[(0,k.jsxs)(`span`,{children:[n,` turns`]}),!i&&(0,k.jsx)(`span`,{className:N.convDelete,onClick:e=>{e.stopPropagation(),ye(t.id)},children:`del`})]})]},t.id)})})]}),(0,k.jsxs)(`div`,{className:N.chatMain,children:[(0,k.jsxs)(`div`,{className:N.chatToolbar,children:[(0,k.jsx)(`button`,{className:N.toolbarBtn,onClick:Ee,title:`Toggle conversations`,children:`💬 Chats`}),(0,k.jsx)(`span`,{className:N.convTitleBar,children:t.find(e=>e.id===r)?.title||e(`chat.newChat`)}),(0,k.jsx)(`button`,{className:N.toolbarBtn,onClick:ve,children:`+ New`}),(0,k.jsx)(`button`,{className:N.toolbarBtnDim,onClick:be,title:`Export Markdown`,children:`Export`}),T&&(0,k.jsx)(`button`,{className:`${N.toolbarBtn} ${N.toolbarBtnCanvas}`,onClick:()=>O(e=>!e),title:`Toggle canvas panel`,children:ie?`▣ Panel ✕`:`▣ Panel`})]}),(0,k.jsxs)(`div`,{className:N.messages,ref:he,children:[a.length===0&&(0,k.jsxs)(`div`,{className:N.empty,children:[(0,k.jsx)(`div`,{className:N.emptyIcon,children:`💬`}),(0,k.jsx)(`div`,{className:N.emptyTitle,children:`NHA Chat`}),(0,k.jsx)(`div`,{className:N.emptySub,children:`Personal Operations Assistant · 80 Tools · 38 Agents · Free AI`}),(0,k.jsxs)(`div`,{className:N.suggGroups,children:[(0,k.jsxs)(`div`,{className:N.suggGroup,children:[(0,k.jsx)(`div`,{className:N.suggGroupTitle,children:`⚡ Quick Actions`}),(0,k.jsx)(`div`,{className:N.suggBtns,children:[`Show my unread emails and summarize the most important ones`,`What's on my calendar today? Any meetings I need to prepare for?`,`List my pending tasks sorted by priority`,`Check my GitHub notifications and summarize open issues`].map(e=>(0,k.jsx)(`button`,{className:N.suggBtn,onClick:()=>u(e),children:e},e))})]}),(0,k.jsxs)(`div`,{className:N.suggGroup,children:[(0,k.jsx)(`div`,{className:N.suggGroupTitle,children:`🌐 Web & Research`}),(0,k.jsx)(`div`,{className:N.suggBtns,children:[`Search the web for the latest AI news and summarize the top 5 stories`,`Open google.com and take a screenshot of the homepage`,`Search for the best restaurants near me and create a summary`,`Research the latest developments in quantum computing and write a report`].map(e=>(0,k.jsx)(`button`,{className:N.suggBtn,onClick:()=>u(e),children:e},e))})]}),(0,k.jsxs)(`div`,{className:N.suggGroup,children:[(0,k.jsx)(`div`,{className:N.suggGroupTitle,children:`🛠️ Productivity`}),(0,k.jsx)(`div`,{className:N.suggBtns,children:[`Draft a professional reply to my last email`,`Create a new calendar event for tomorrow at 10am with reminder`,`Summarize my notes and create a to-do list from action items`,`Find contacts named Mario and show their details`].map(e=>(0,k.jsx)(`button`,{className:N.suggBtn,onClick:()=>u(e),children:e},e))})]}),(0,k.jsxs)(`div`,{className:N.suggGroup,children:[(0,k.jsx)(`div`,{className:N.suggGroupTitle,children:`📈 Finance`}),(0,k.jsx)(`div`,{className:N.suggBtns,children:[`What is the current price of Bitcoin and its 24h performance?`,`Analyze the current macro environment and suggest 3 trading opportunities`,`What is the current market regime? Risk-on or risk-off?`,`Give me a technical analysis of AAPL with key support/resistance levels`].map(e=>(0,k.jsx)(`button`,{className:N.suggBtn,onClick:()=>u(e),children:e},e))})]})]})]}),a.map((e,t)=>(0,k.jsxs)(`div`,{className:`${N.message} ${N[e.role]}`,children:[(0,k.jsx)(`div`,{className:N.msgLabel,children:e.role===`user`?`You`:`NHA`}),e.role===`assistant`&&e.streaming&&(0,k.jsxs)(`div`,{className:N.toolActivity,children:[(M||e.content===``&&!ue&&ce.length===0)&&(0,k.jsxs)(`div`,{className:N.thinkingIndicator,children:[(0,k.jsxs)(`div`,{className:N.thinkingDots,children:[(0,k.jsx)(`div`,{className:N.thinkingDot}),(0,k.jsx)(`div`,{className:N.thinkingDot}),(0,k.jsx)(`div`,{className:N.thinkingDot})]}),ue?`Deep thinking...`:`Generating...`]}),ue&&!M&&(0,k.jsxs)(`div`,{className:N.thinkingIndicator,children:[(0,k.jsxs)(`div`,{className:N.thinkingDots,children:[(0,k.jsx)(`div`,{className:N.thinkingDot}),(0,k.jsx)(`div`,{className:N.thinkingDot}),(0,k.jsx)(`div`,{className:N.thinkingDot})]}),`Deep thinking...`]}),ce.map((e,t)=>(0,k.jsxs)(`div`,{className:`${N.toolActivityItem} ${N[e.status]}`,children:[e.status===`active`?`⏳`:e.status===`error`?`❌`:`✅`,` `,e.label,e.status===`active`&&`...`]},t))]}),e.role===`user`&&ae===t?(0,k.jsxs)(`div`,{className:N.editBox,children:[(0,k.jsx)(`textarea`,{className:N.editInput,value:oe,onChange:e=>se(e.target.value),onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),Fe()),e.key===`Escape`&&A(null)},autoFocus:!0,rows:3}),(0,k.jsxs)(`div`,{className:N.editActions,children:[(0,k.jsx)(`button`,{className:N.editSaveBtn,onClick:Fe,children:`Send ↵`}),(0,k.jsx)(`button`,{className:N.editCancelBtn,onClick:()=>A(null),children:`Cancel`})]})]}):e.role===`assistant`?e.content!==``&&(0,k.jsx)(`div`,{className:`${N.bubble} ${Ce.body} ${e.sentinelBlocked?N.sentinelBubble:``}`,dangerouslySetInnerHTML:{__html:Se(e.content)}}):(0,k.jsx)(`div`,{className:N.bubble,children:e.content}),e.streaming&&(0,k.jsx)(`span`,{className:N.cursor}),!e.streaming&&ae!==t&&(0,k.jsxs)(`div`,{className:N.msgActions,children:[(0,k.jsx)(`button`,{className:N.msgActionBtn,onClick:()=>Me(e.content),children:`Copy`}),e.role===`user`&&!d&&(0,k.jsx)(`button`,{className:N.msgActionBtn,onClick:()=>Pe(t),children:`Edit`}),e.role===`assistant`&&!d&&(0,k.jsx)(`button`,{className:N.msgActionBtn,onClick:()=>Ne(t),children:`Retry`})]})]},t)),(0,k.jsx)(`div`,{ref:pe})]}),ke&&(0,k.jsxs)(`div`,{className:N.attachBar,children:[(0,k.jsx)(`span`,{children:ke}),(0,k.jsx)(`button`,{className:N.attachClear,onClick:Oe,children:`×`})]}),(0,k.jsxs)(`div`,{className:N.inputBar,children:[(0,k.jsxs)(`div`,{className:N.inputTools,children:[(0,k.jsx)(`button`,{className:`${N.iconBtn} ${C?N.iconBtnActive:``}`,onClick:F,title:`Voice input`,children:`🎤`}),(0,k.jsx)(`button`,{className:N.iconBtn,onClick:()=>y.current?.click(),title:`Attach file`,children:`📎`}),(0,k.jsx)(`button`,{className:N.iconBtn,onClick:()=>b.current?.click(),title:`Attach image`,children:`🖼`}),(0,k.jsx)(`input`,{ref:y,type:`file`,style:{display:`none`},onChange:P}),(0,k.jsx)(`input`,{ref:b,type:`file`,accept:`image/*`,style:{display:`none`},onChange:De}),(0,k.jsx)(`span`,{style:{flex:1}}),(0,k.jsxs)(`button`,{className:`${N.thinkBtn} ${x?N.thinkBtnOn:``}`,onClick:xe,title:`Extended Thinking`,children:[`Think: `,x?`on`:`off`]}),T&&(0,k.jsx)(`button`,{className:N.toolbarBtn,onClick:()=>O(e=>!e),title:`Canvas panel`,children:`▣ Panel`})]}),(0,k.jsxs)(`div`,{className:N.inputRow,children:[(0,k.jsx)(`textarea`,{ref:me,className:N.input,value:l,onChange:e=>u(e.target.value),onKeyDown:je,placeholder:e(`chat.placeholder`),rows:1,disabled:d}),d?(0,k.jsxs)(`button`,{className:`${N.btn} ${N.stop}`,onClick:Ae,children:[`■ `,e(`chat.stopGeneration`)]}):(0,k.jsx)(`button`,{className:`${N.btn} ${N.send}`,onClick:I,disabled:!l.trim()&&!m&&!g,children:`Send ↵`})]})]})]}),ie&&T&&(0,k.jsxs)(`div`,{className:N.canvasPanel,children:[(0,k.jsxs)(`div`,{className:N.canvasPanelHeader,children:[(0,k.jsx)(`span`,{children:`Canvas`}),(0,k.jsxs)(`div`,{className:N.canvasPanelActions,children:[(0,k.jsx)(`button`,{className:N.canvasPanelBtn,onClick:()=>{let e=new Blob([T],{type:`text/html`}),t=URL.createObjectURL(e),n=document.createElement(`a`);n.href=t,n.download=`NHA-Canvas.html`,n.click(),setTimeout(()=>URL.revokeObjectURL(t),5e3)},children:`↓ Download`}),(0,k.jsx)(`button`,{className:N.canvasPanelBtn,onClick:()=>navigator.clipboard.writeText(T).catch(()=>{}),children:`Copy HTML`}),(0,k.jsx)(`button`,{className:N.canvasPanelClose,onClick:()=>O(!1),children:`×`})]})]}),(0,k.jsx)(`iframe`,{className:N.canvasFrame,sandbox:`allow-scripts`,srcDoc:T,title:`Canvas`})]})]})}var P={root:`_root_1899x_1`,header:`_header_1899x_8`,headerLeft:`_headerLeft_1899x_19`,title:`_title_1899x_21`,subtitle:`_subtitle_1899x_28`,headerActions:`_headerActions_1899x_34`,tokenBar:`_tokenBar_1899x_41`,tokIn:`_tokIn_1899x_49`,tokOut:`_tokOut_1899x_50`,tokTotal:`_tokTotal_1899x_51`,tokDim:`_tokDim_1899x_52`,sessionsBtn:`_sessionsBtn_1899x_54`,pdfBtn:`_pdfBtn_1899x_66`,clearBtn:`_clearBtn_1899x_76`,sessionsDrawer:`_sessionsDrawer_1899x_89`,noSessions:`_noSessions_1899x_104`,sessionItem:`_sessionItem_1899x_111`,sessionInfo:`_sessionInfo_1899x_121`,sessionTask:`_sessionTask_1899x_127`,sessionMeta:`_sessionMeta_1899x_137`,sessionBtns:`_sessionBtns_1899x_143`,importBtn:`_importBtn_1899x_149`,delSessionBtn:`_delSessionBtn_1899x_159`,sessionsFooter:`_sessionsFooter_1899x_169`,clearAllSessionsBtn:`_clearAllSessionsBtn_1899x_176`,inputArea:`_inputArea_1899x_189`,inputRow:`_inputRow_1899x_198`,taskInput:`_taskInput_1899x_204`,inputControls:`_inputControls_1899x_219`,runBtn:`_runBtn_1899x_225`,stopBtn:`_stopBtn_1899x_238`,attachBtn:`_attachBtn_1899x_249`,attachBadge:`_attachBadge_1899x_262`,clearAttach:`_clearAttach_1899x_275`,examples:`_examples_1899x_284`,exampleBtn:`_exampleBtn_1899x_290`,body:`_body_1899x_308`,agentChip:`_agentChip_1899x_321`,chip_running:`_chip_running_1899x_332`,charCardPulse:`_charCardPulse_1899x_1`,chip_done:`_chip_done_1899x_338`,chip_error:`_chip_error_1899x_339`,chip_waiting:`_chip_waiting_1899x_340`,chipIcon:`_chipIcon_1899x_341`,chipLabel:`_chipLabel_1899x_342`,chipDots:`_chipDots_1899x_343`,chipCheck:`_chipCheck_1899x_344`,chipErr:`_chipErr_1899x_345`,officeSceneWrap:`_officeSceneWrap_1899x_348`,pipeline:`_pipeline_1899x_358`,pipelineWrap:`_pipelineWrap_1899x_373`,pipelineRunning:`_pipelineRunning_1899x_383`,scanSweep:`_scanSweep_1899x_1`,pipelineTitle:`_pipelineTitle_1899x_409`,pipelineNodes:`_pipelineNodes_1899x_417`,pipelineStep:`_pipelineStep_1899x_424`,arrow:`_arrow_1899x_430`,arrowActive:`_arrowActive_1899x_439`,arrowPulse:`_arrowPulse_1899x_1`,agentChar:`_agentChar_1899x_451`,charWaiting:`_charWaiting_1899x_466`,charActive:`_charActive_1899x_471`,charDone:`_charDone_1899x_479`,charError:`_charError_1899x_484`,orbitRing1:`_orbitRing1_1899x_495`,orbitRing2:`_orbitRing2_1899x_496`,orbitSpin1:`_orbitSpin1_1899x_1`,orbitSpin2:`_orbitSpin2_1899x_1`,charAvatar:`_charAvatar_1899x_542`,charIcon:`_charIcon_1899x_557`,iconBob:`_iconBob_1899x_1`,charCheck:`_charCheck_1899x_574`,badgePop:`_badgePop_1899x_1`,charErr:`_charErr_1899x_484`,charPulse:`_charPulse_1899x_618`,charPulse2:`_charPulse2_1899x_619`,expandRing:`_expandRing_1899x_1`,charLabel:`_charLabel_1899x_638`,charStatus:`_charStatus_1899x_650`,charStatusDots:`_charStatusDots_1899x_663`,dot1:`_dot1_1899x_664`,dot2:`_dot2_1899x_664`,dot3:`_dot3_1899x_664`,dotFade:`_dotFade_1899x_1`,twoCol:`_twoCol_1899x_678`,panelTitle:`_panelTitle_1899x_685`,logPanel:`_logPanel_1899x_695`,logBody:`_logBody_1899x_707`,logEntry:`_logEntry_1899x_715`,logTime:`_logTime_1899x_725`,logIcon:`_logIcon_1899x_726`,logAgent:`_logAgent_1899x_727`,logText:`_logText_1899x_728`,log_system:`_log_system_1899x_730`,log_error:`_log_error_1899x_731`,liveOutputPanel:`_liveOutputPanel_1899x_734`,liveBlock:`_liveBlock_1899x_741`,blockSlideIn:`_blockSlideIn_1899x_1`,liveBlockActive:`_liveBlockActive_1899x_755`,liveBlockScan:`_liveBlockScan_1899x_1`,liveBlockHeader:`_liveBlockHeader_1899x_780`,liveBlockIcon:`_liveBlockIcon_1899x_789`,liveBlockLabel:`_liveBlockLabel_1899x_791`,outputStatus:`_outputStatus_1899x_799`,status_done:`_status_done_1899x_810`,status_running:`_status_running_1899x_811`,status_error:`_status_error_1899x_812`,status_waiting:`_status_waiting_1899x_813`,liveBlockBody:`_liveBlockBody_1899x_816`,liveBlockWorking:`_liveBlockWorking_1899x_954`,workingDot:`_workingDot_1899x_961`,workingBounce:`_workingBounce_1899x_1`,workingLabel:`_workingLabel_1899x_978`,workingFade:`_workingFade_1899x_1`,studioBlinkCursor:`_studioBlinkCursor_1899x_1`,resultAccordion:`_resultAccordion_1899x_1007`,resultAccordionSummary:`_resultAccordionSummary_1899x_1014`,resultAccordionBody:`_resultAccordionBody_1899x_1031`,financeSection:`_financeSection_1899x_1065`,financeSectionTitle:`_financeSectionTitle_1899x_1073`,financePresets:`_financePresets_1899x_1082`,financeBtn:`_financeBtn_1899x_1088`,canvasToggleBtn:`_canvasToggleBtn_1899x_1106`,canvasPanel:`_canvasPanel_1899x_1122`,canvasPanelHeader:`_canvasPanelHeader_1899x_1137`,canvasPanelActions:`_canvasPanelActions_1899x_1149`,canvasPanelBtn:`_canvasPanelBtn_1899x_1155`,canvasPanelClose:`_canvasPanelClose_1899x_1167`,canvasFrame:`_canvasFrame_1899x_1178`,pipelineLiveTag:`_pipelineLiveTag_1899x_1186`,liveTagBlink:`_liveTagBlink_1899x_1`,reasonRow:`_reasonRow_1899x_1200`,reasonChip:`_reasonChip_1899x_1209`,reasonIcon:`_reasonIcon_1899x_1222`,reasonText:`_reasonText_1899x_1223`,liveBlockReason:`_liveBlockReason_1899x_1226`,councilWrapper:`_councilWrapper_1899x_1236`,councilPanel:`_councilPanel_1899x_1241`,councilHeader:`_councilHeader_1899x_1249`,councilHeaderLeft:`_councilHeaderLeft_1899x_1260`,councilHeaderRight:`_councilHeaderRight_1899x_1266`,councilIcon:`_councilIcon_1899x_1272`,councilTitle:`_councilTitle_1899x_1274`,councilConvergedBadge:`_councilConvergedBadge_1899x_1283`,councilDivergedBadge:`_councilDivergedBadge_1899x_1295`,councilPhaseTag:`_councilPhaseTag_1899x_1307`,councilPhaseActive:`_councilPhaseActive_1899x_1313`,phaseGlow:`_phaseGlow_1899x_1`,councilPhaseDone:`_councilPhaseDone_1899x_1322`,councilMetrics:`_councilMetrics_1899x_1325`,convRow:`_convRow_1899x_1333`,convLabel:`_convLabel_1899x_1339`,convTrack:`_convTrack_1899x_1347`,convFill:`_convFill_1899x_1355`,convPct:`_convPct_1899x_1361`,councilNodes:`_councilNodes_1899x_1371`,councilSectionTitle:`_councilSectionTitle_1899x_1376`,councilNode:`_councilNode_1899x_1371`,councilNodeHeader:`_councilNodeHeader_1899x_1393`,councilNodeIcon:`_councilNodeIcon_1899x_1406`,councilNodeLabel:`_councilNodeLabel_1899x_1407`,councilNodeToggle:`_councilNodeToggle_1899x_1408`,councilNodeBody:`_councilNodeBody_1899x_1410`,councilSynthesis:`_councilSynthesis_1899x_1420`,councilSynthesisHeader:`_councilSynthesisHeader_1899x_1424`,heraldIcon:`_heraldIcon_1899x_1433`,heraldLabel:`_heraldLabel_1899x_1435`,heraldStreaming:`_heraldStreaming_1899x_1443`,councilSynthesisBody:`_councilSynthesisBody_1899x_1445`,councilSkipped:`_councilSkipped_1899x_1475`,councilSkipIcon:`_councilSkipIcon_1899x_1486`,charSpriteRunning:`_charSpriteRunning_1899x_1499`,spriteWalk:`_spriteWalk_1899x_1`,charSpriteDone:`_charSpriteDone_1899x_1508`,charScanline:`_charScanline_1899x_1512`,scanlineScroll:`_scanlineScroll_1899x_1`,auraAnim:`_auraAnim_1899x_1532`,auraGlow:`_auraGlow_1899x_1`,parliamentPrompt:`_parliamentPrompt_1899x_1539`,parliamentPromptIcon:`_parliamentPromptIcon_1899x_1549`,parliamentPromptContent:`_parliamentPromptContent_1899x_1550`,parliamentPromptTitle:`_parliamentPromptTitle_1899x_1551`,parliamentPromptDesc:`_parliamentPromptDesc_1899x_1552`,parliamentPromptMeta:`_parliamentPromptMeta_1899x_1553`,parliamentPromptBtns:`_parliamentPromptBtns_1899x_1554`,parliamentActivateBtn:`_parliamentActivateBtn_1899x_1555`,parliamentSkipBtn:`_parliamentSkipBtn_1899x_1562`,panelTabs:`_panelTabs_1899x_1570`,panelTabBtn:`_panelTabBtn_1899x_1571`,panelTabActive:`_panelTabActive_1899x_1578`,panelEmpty:`_panelEmpty_1899x_1580`,browserPanel:`_browserPanel_1899x_1589`,browserBar:`_browserBar_1899x_1590`,browserInput:`_browserInput_1899x_1591`,browserGo:`_browserGo_1899x_1598`,liveBlockClickable:`_liveBlockClickable_1899x_1605`,liveBlockBodyClamped:`_liveBlockBodyClamped_1899x_1614`,expandHint:`_expandHint_1899x_1621`,blockModalOverlay:`_blockModalOverlay_1899x_1630`,blockModal:`_blockModal_1899x_1630`,blockModalHeader:`_blockModalHeader_1899x_1655`,blockModalTitle:`_blockModalTitle_1899x_1665`,blockModalClose:`_blockModalClose_1899x_1673`,blockModalBody:`_blockModalBody_1899x_1685`},De=[{label:`📈 Full Trading Strategy`,task:`You are a team of senior quantitative analysts and macro traders. Build a complete, actionable trading strategy with the following structure:
66
66
 
67
67
  1. MACRO REGIME ANALYSIS
68
68
  - Current macro cycle phase (expansion/peak/contraction/trough) with supporting indicators (yield curve, PMI, CPI trajectory, Fed/ECB policy stance)
@@ -8,7 +8,7 @@
8
8
  <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
9
9
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
10
10
  <title>NHA — NotHumanAllowed</title>
11
- <script type="module" crossorigin src="/assets/index-BAw59tZG.js"></script>
11
+ <script type="module" crossorigin src="/assets/index-C4d3pl8K.js"></script>
12
12
  <link rel="stylesheet" crossorigin href="/assets/index-DnJMrYkq.css">
13
13
  </head>
14
14
  <body>