nothumanallowed 9.3.11 → 9.3.12

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": "9.3.11",
3
+ "version": "9.3.12",
4
4
  "description": "NotHumanAllowed — 38 AI agents + 58 tools + browser automation + web search. Streaming chat, headless Chrome CDP, multi-conversation, export. Gmail, Calendar, Drive, GitHub, Notion, Slack. 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 = '9.3.11';
8
+ export const VERSION = '9.3.12';
9
9
  export const BASE_URL = 'https://nothumanallowed.com/cli';
10
10
  export const API_BASE = 'https://nothumanallowed.com/api/v1';
11
11
 
@@ -520,7 +520,7 @@ export function buildSystemPrompt(persona, personaDescription, config, initialCo
520
520
  if (profile.notes) fields.push(`Notes: ${profile.notes}`);
521
521
 
522
522
  if (fields.length > 0) {
523
- prompt += `\n\n--- USER PROFILE (use this for personal references like "my home", "my city", etc.) ---\n${fields.join('\n')}`;
523
+ prompt += `\n\n--- USER PROFILE (use this for personal references like "my home", "my city", etc.) ---\n${fields.join('\n')}\nNOTE: The profile above is for context only. It does NOT determine your response language. Always respond in the language of the user's message.`;
524
524
  }
525
525
  }
526
526
 
@@ -105,6 +105,8 @@ input:focus,textarea:focus{border-color:var(--green3)}
105
105
  .chat__input{flex:1;resize:none;min-height:40px;max-height:100px;padding:10px 14px}
106
106
  .chat__send{background:var(--green3);color:var(--bg);padding:10px 16px;border-radius:var(--r);font-weight:700;font-size:12px}
107
107
  .chat__send:disabled{opacity:.4}
108
+ .chat__stop{background:var(--red);color:var(--bright);padding:10px 16px;border-radius:var(--r);font-weight:700;font-size:12px;display:none}
109
+ .chat__stop--visible{display:block}
108
110
 
109
111
  /* ---- TASKS ---- */
110
112
  .task-bar{display:flex;gap:8px;margin-bottom:12px;flex-wrap:wrap}
@@ -207,6 +209,22 @@ var convList = [];
207
209
  var dash = {emails:[],events:[],tasks:[],plan:null,status:null};
208
210
  var dashLoaded = {emails:false,events:false,tasks:false,contacts:false,notes:false,drive:false,github:false,notion:false,slack:false};
209
211
  var chatStreaming = false;
212
+ var chatAbortController = null;
213
+
214
+ function endStreaming(){
215
+ chatStreaming=false;chatAbortController=null;
216
+ var stopBtn=document.getElementById('chatStop');if(stopBtn)stopBtn.classList.remove('chat__stop--visible');
217
+ var sendBtn=document.getElementById('chatSend');if(sendBtn)sendBtn.style.display='';
218
+ }
219
+ function stopChat(){
220
+ if(chatAbortController){try{chatAbortController.abort()}catch(e){}}
221
+ endStreaming();
222
+ if(chatHistory.length>0){
223
+ var last=chatHistory[chatHistory.length-1];
224
+ if(last.role==='assistant'&&(!last.content||last.content===''))last.content='[Stopped]';
225
+ }
226
+ renderMessages();
227
+ }
210
228
 
211
229
  function loadConvList(){return apiGet('/api/conversations').then(function(r){convList=(r&&r.conversations)||[];renderConvSidebar();})}
212
230
  function loadConv(id){return apiGet('/api/conversations/'+id).then(function(r){if(r&&r.conversation){activeConvId=r.conversation.id;chatHistory=r.conversation.messages||[];renderMessages();renderConvSidebar();}})}
@@ -347,7 +365,7 @@ function renderChat(el){
347
365
  '</div>'+
348
366
  '<div class="chat"><div class="chat__messages" id="chatMessages"></div>'+
349
367
  '<div id="chatAttachInfo" style="display:none;padding:4px 12px;font-size:11px;color:var(--cyan);background:var(--bg2);border-top:1px solid var(--border)"><span id="chatAttachName"></span> <button onclick="clearChatAttach()" style="background:none;border:none;color:#f44;cursor:pointer;font-size:14px;font-weight:700">&times;</button></div>'+
350
- '<div class="chat__bar"><button class="chat__mic" id="chatMic" onclick="toggleVoiceInput()" title="Voice input">&#127908;</button><button onclick="document.getElementById(\\x27chatFileInput\\x27).click()" style="background:none;border:none;cursor:pointer;font-size:16px;padding:4px" title="Attach file">&#128206;</button><button onclick="document.getElementById(\\x27chatImageInput\\x27).click()" style="background:none;border:none;cursor:pointer;font-size:16px;padding:4px" title="Attach image">&#128247;</button><input type="file" id="chatFileInput" style="display:none" onchange="handleChatFile(this)"><input type="file" id="chatImageInput" accept="image/*" style="display:none" onchange="handleChatImage(this)"><textarea class="chat__input" id="chatInput" placeholder="Ask anything... (or attach file/image first)" rows="1"></textarea><button class="chat__send" id="chatSend">Send</button></div>'+
368
+ '<div class="chat__bar"><button class="chat__mic" id="chatMic" onclick="toggleVoiceInput()" title="Voice input">&#127908;</button><button onclick="document.getElementById(\\x27chatFileInput\\x27).click()" style="background:none;border:none;cursor:pointer;font-size:16px;padding:4px" title="Attach file">&#128206;</button><button onclick="document.getElementById(\\x27chatImageInput\\x27).click()" style="background:none;border:none;cursor:pointer;font-size:16px;padding:4px" title="Attach image">&#128247;</button><input type="file" id="chatFileInput" style="display:none" onchange="handleChatFile(this)"><input type="file" id="chatImageInput" accept="image/*" style="display:none" onchange="handleChatImage(this)"><textarea class="chat__input" id="chatInput" placeholder="Ask anything... (or attach file/image first)" rows="1"></textarea><button class="chat__send" id="chatSend">Send</button><button class="chat__stop" id="chatStop" onclick="stopChat()">Stop</button></div>'+
351
369
  '</div>'+
352
370
  '</div>'+
353
371
  '</div>';
@@ -480,18 +498,22 @@ function sendChat(){
480
498
 
481
499
  // Streaming SSE
482
500
  chatStreaming=true;
501
+ chatAbortController=new AbortController();
502
+ // Show Stop button, hide Send button
503
+ var stopBtn=document.getElementById('chatStop');if(stopBtn)stopBtn.classList.add('chat__stop--visible');
504
+ var sendBtn=document.getElementById('chatSend');if(sendBtn)sendBtn.style.display='none';
483
505
  chatHistory.push({role:'assistant',content:''});
484
506
  renderMessages();
485
507
  var streamIdx=chatHistory.length-1;
486
508
  var allHistory=chatHistory.slice(0,-1).map(function(m){return{role:m.role,content:(m.content||'').replace(/!\\[Screenshot\\]\\(data:image\\/[^)]+\\)/g,'[Screenshot taken]')};});
487
509
  var payload={message:msg,history:allHistory,conversationId:activeConvId};
488
510
 
489
- fetch(API+'/api/chat/stream',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(payload)}).then(function(response){
490
- if(!response.ok||!response.body){chatHistory[streamIdx].content='Error: connection failed';chatStreaming=false;renderMessages();return;}
511
+ fetch(API+'/api/chat/stream',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(payload),signal:chatAbortController.signal}).then(function(response){
512
+ if(!response.ok||!response.body){chatHistory[streamIdx].content='Error: connection failed';endStreaming();renderMessages();return;}
491
513
  var reader=response.body.getReader();var decoder=new TextDecoder();var buffer='';var currentEvent='';
492
514
  function pump(){
493
515
  reader.read().then(function(result){
494
- if(result.done){chatStreaming=false;renderMessages();loadConvList();return;}
516
+ if(result.done){endStreaming();renderMessages();loadConvList();return;}
495
517
  buffer+=decoder.decode(result.value,{stream:true});
496
518
  var lines=buffer.split('\\n');buffer=lines.pop()||'';
497
519
  for(var i=0;i<lines.length;i++){
@@ -522,16 +544,16 @@ function sendChat(){
522
544
  renderMessages();
523
545
  }
524
546
  if(currentEvent==='tool_synthesis'){chatHistory[streamIdx].content='';renderMessages();}
525
- if(currentEvent==='done'){chatStreaming=false;if(data.content)chatHistory[streamIdx].content=data.content;var ss=chatHistory[streamIdx]._screenshots;if(ss&&ss.length>0){for(var si=0;si<ss.length;si++){chatHistory[streamIdx].content+='\\n![Screenshot]('+ss[si]+')\\n';}}renderMessages();loadConvList();}
526
- if(currentEvent==='error'){chatStreaming=false;chatHistory[streamIdx].content='Error: '+(data.message||'Unknown');renderMessages();}
547
+ if(currentEvent==='done'){endStreaming();if(data.content)chatHistory[streamIdx].content=data.content;var ss=chatHistory[streamIdx]._screenshots;if(ss&&ss.length>0){for(var si=0;si<ss.length;si++){chatHistory[streamIdx].content+='\\n![Screenshot]('+ss[si]+')\\n';}}renderMessages();loadConvList();}
548
+ if(currentEvent==='error'){endStreaming();chatHistory[streamIdx].content='Error: '+(data.message||'Unknown');renderMessages();}
527
549
  }catch(e){}
528
550
  }
529
551
  }
530
552
  pump();
531
- }).catch(function(e){chatStreaming=false;chatHistory[streamIdx].content='Error: '+e.message;renderMessages();});
553
+ }).catch(function(e){endStreaming();if(e.name!=='AbortError'){chatHistory[streamIdx].content='Error: '+e.message;renderMessages();}});
532
554
  }
533
555
  pump();
534
- }).catch(function(e){chatStreaming=false;chatHistory[streamIdx].content='Error: '+e.message;renderMessages();});
556
+ }).catch(function(e){endStreaming();if(e.name!=='AbortError'){chatHistory[streamIdx].content='Error: '+e.message;renderMessages();}});
535
557
  }
536
558
 
537
559
  // ---- TASKS ----