feat: granular CIS MCP server, chat memory compaction, and UX improvements

- Rewrite mcp_cis_server.py with per-section scan tools (IAM, Networking,
  Compute, Logging/Monitoring, Storage, Asset Management) instead of
  monolithic full-tenancy scan — 12 granular tools
- Add cis_reports.py (Oracle CIS Benchmark checker) to backend
- Add chat memory compaction: auto-summarize old messages when history
  exceeds ~8000 tokens, keeping 6 recent messages intact
- Fix GenAI tool use loop: accumulate assistant+tool messages across
  iterations for proper conversation flow (Generic format)
- Remove tenancy confirmation section from system prompt
- Add thinking indicator and button disable in chat UI while waiting
- Add requests dependency for cis_reports.py
- Fix NoneType error in cis_reports.py region filtering
This commit is contained in:
nogueiraguh
2026-03-05 08:26:43 -03:00
parent f259239a17
commit 5038403d08
6 changed files with 7457 additions and 27 deletions

View File

@@ -345,21 +345,28 @@ async function sChat(){const el=document.getElementById('chi');const m=el.value.
if(!S.chatModel){S.msgs.push({r:'assistant',c:'⚠️ Selecione um modelo antes de enviar uma mensagem.'});R();return}
el.value='';
S.msgs.push({r:'user',c:m});R();scCh();
// Disable input and show thinking indicator
const btn=document.querySelector('.ch-i .btn');
el.disabled=true;if(btn){btn.disabled=true;btn.dataset.origText=btn.textContent;btn.innerHTML='<span class="spinner" style="width:14px;height:14px;border-width:2px;margin-right:6px"></span>Pensando...'}
S.msgs.push({r:'assistant',c:'⏳ _Pensando..._',thinking:true});R();scCh();
try{const body={message:m,session_id:S.sid,use_tools:S.chatUseTools};
if(S.chatModel.startsWith('cfg:')){
body.genai_config_id=S.chatModel.slice(4);
body.temperature=S.chatParams.temperature;body.max_tokens=S.chatParams.max_tokens;body.top_p=S.chatParams.top_p;
body.top_k=S.chatParams.top_k;body.frequency_penalty=S.chatParams.frequency_penalty;body.presence_penalty=S.chatParams.presence_penalty}
else if(S.chatModel){
if(!S.chatOci){S.msgs.push({r:'assistant',c:'⚠️ Selecione uma credencial OCI para usar o modelo direto.'});R();return}
if(!S.chatOci){S.msgs.pop();S.msgs.push({r:'assistant',c:'⚠️ Selecione uma credencial OCI para usar o modelo direto.'});R();el.disabled=false;if(btn){btn.disabled=false;btn.textContent=btn.dataset.origText}return}
body.model_id=S.chatModel;body.oci_config_id=S.chatOci;body.genai_region=S.chatRegion;body.compartment_id=S.chatCompartment;
body.temperature=S.chatParams.temperature;body.max_tokens=S.chatParams.max_tokens;body.top_p=S.chatParams.top_p;
body.top_k=S.chatParams.top_k;body.frequency_penalty=S.chatParams.frequency_penalty;body.presence_penalty=S.chatParams.presence_penalty}
const d=await $api('/chat',{method:'POST',body});S.sid=d.session_id;
// Remove thinking indicator
S.msgs=S.msgs.filter(x=>!x.thinking);
let resp=d.response;
if(d.tools_used&&d.tools_used.length){resp+='\n\n🔧 **Tools utilizadas:** '+d.tools_used.map(t=>t.name).join(', ')}
S.msgs.push({r:'assistant',c:resp});R();scCh()}
catch(e){S.msgs.push({r:'assistant',c:'❌ Erro: '+e.message});R()}}
catch(e){S.msgs=S.msgs.filter(x=>!x.thinking);S.msgs.push({r:'assistant',c:'❌ Erro: '+e.message});R()}
finally{el.disabled=false;el.focus();if(btn){btn.disabled=false;btn.textContent=btn.dataset.origText||'Enviar →'}}}
function scCh(){setTimeout(()=>{const e=document.getElementById('chm');if(e)e.scrollTop=e.scrollHeight},50)}
async function clrChat(){if(S.sid)try{await $api('/chat/'+S.sid,{method:'DELETE'})}catch(e){}S.msgs=[];S.sid=null;R()}