diff --git a/frontend/index.html b/frontend/index.html index 9cb4106..bafbef2 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -115,7 +115,19 @@ tbody tr:last-child td{border-bottom:none} .ch-c{display:flex;flex-direction:column;height:calc(100vh - 56px - 3rem);overflow:hidden} .ch-t{display:flex;gap:.5rem;align-items:center;padding:.6rem .85rem;background:var(--bg1);border:1px solid var(--bd); border-radius:var(--rl) var(--rl) 0 0;font-size:.74rem;flex-wrap:wrap;box-shadow:var(--sh1)} -.ch-t select{max-width:260px;font-size:.74rem;padding:.35rem .5rem}.ch-t select.cmod-sel{max-width:320px} +.ch-t select{max-width:260px;font-size:.74rem;padding:.35rem .5rem} +.mdrop{position:relative;display:inline-block} +.mdrop-btn{background:var(--bg2);border:1px solid var(--bd);border-radius:8px;padding:.35rem .6rem;font-size:.74rem;cursor:pointer;max-width:320px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:flex;align-items:center;gap:.3rem;min-width:180px} +.mdrop-btn:hover{border-color:var(--ac)} +.mdrop-btn .arr{font-size:.55rem;margin-left:auto;opacity:.5} +.mdrop-dd{position:absolute;top:100%;left:0;z-index:100;background:var(--bg1);border:1px solid var(--bd);border-radius:10px;box-shadow:0 8px 24px rgba(0,0,0,.12);margin-top:4px;min-width:320px;max-width:400px;display:none} +.mdrop-dd.open{display:block} +.mdrop-dd input{width:100%;padding:.45rem .6rem;border:none;border-bottom:1px solid var(--bd);font-size:.74rem;background:var(--bg2);border-radius:10px 10px 0 0;outline:none;box-sizing:border-box} +.mdrop-list{max-height:220px;overflow-y:auto;padding:.25rem 0} +.mdrop-list .grp{font-size:.64rem;font-weight:700;color:var(--t3);padding:.4rem .7rem .15rem;text-transform:uppercase;letter-spacing:.04em} +.mdrop-list .itm{padding:.3rem .7rem;font-size:.74rem;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis} +.mdrop-list .itm:hover{background:var(--bg3)} +.mdrop-list .itm.sel{background:var(--pl);color:var(--p);font-weight:600} .ch-params{padding:.55rem .85rem;background:var(--bg1);border-left:1px solid var(--bd);border-right:1px solid var(--bd);border-bottom:1px solid var(--bg3);font-size:.72rem} .ch-params .g3{display:grid;grid-template-columns:repeat(3,1fr);gap:.5rem;margin-bottom:.3rem} .ch-params label{font-weight:600;color:var(--t3);font-size:.66rem;margin-bottom:2px;display:block} @@ -265,14 +277,19 @@ function rPg(){switch(S.tab){case'chat':return rChat();case'explorer':return rEx function rChat(){ const ms=S.msgs.length===0?'
🤖

Inicie uma conversa com o agente.

Selecione um modelo ou use o agente local.

' :S.msgs.map(m=>`
${fm(m.c)}
`).join(''); - // Build model select with optgroups - const presetOpts=S.genaiCfg.map(g=>{const mi=S.models[g.model_id];return``}).join(''); + // Build custom dropdown items const skip=new Set(['openai.gpt-image-1','openai.gpt-image-1.5','openai.gpt-audio','meta.llama-guard-4-12b','protectai.deberta-v3-base-prompt-injection-v2', 'openai.gpt-5.3-codex','openai.gpt-5.2-codex','openai.gpt-5.1-codex','openai.gpt-5.1-codex-max','openai.gpt-5.1-codex-mini','openai.gpt-5-codex', 'openai.gpt-oss-120b','openai.gpt-oss-20b']); const provs={};for(const[mid,info]of Object.entries(S.models)){if(skip.has(mid))continue;const p=info.provider||'other';if(!provs[p])provs[p]=[];provs[p].push({id:mid,name:info.name})} const provOrder=['openai','google','meta','cohere','xai']; - const catalogOpts=provOrder.filter(p=>provs[p]).map(p=>{const label=p.charAt(0).toUpperCase()+p.slice(1);const opts=provs[p].map(m=>``).join('');return`${opts}`}).join(''); + let ddItems=`
Agente Local (sem IA)
`; + if(S.genaiCfg.length){ddItems+=`
Configs Salvas
`;S.genaiCfg.forEach(g=>{const mi=S.models[g.model_id];ddItems+=`
${g.name||mi?.name||g.model_id} (${g.genai_region})
`})} + provOrder.filter(p=>provs[p]).forEach(p=>{ddItems+=`
${p.charAt(0).toUpperCase()+p.slice(1)}
`;provs[p].forEach(m=>{ddItems+=`
${m.name}
`})}); + // Current label + let curLabel='Agente Local (sem IA)'; + if(S.chatModel.startsWith('cfg:')){const g=S.genaiCfg.find(x=>x.id===S.chatModel.slice(4));const mi=g?S.models[g.model_id]:null;curLabel=g?(g.name||mi?.name||g.model_id)+' ('+g.genai_region+')':'Config...'} + else if(S.chatModel){const mi=S.models[S.chatModel];curLabel=mi?mi.name:S.chatModel} const isDirect=S.chatModel&&!S.chatModel.startsWith('cfg:'); const hasModel=!!S.chatModel; // OCI selector for direct mode @@ -291,14 +308,21 @@ function rChat(){
`:''; return`
-
+
${curLabel} â–¼
${ddItems}
${ociSel}${gearBtn}${ragBadge}
${paramsPanel}
${ms}
`} -function chatModelChanged(){S.chatModel=document.getElementById('cmod').value; - if(S.chatModel&&!S.chatModel.startsWith('cfg:')&&!S.chatOci&&S.ociCfg.length){S.chatOci=S.ociCfg[0].id;const c=S.ociCfg[0];S.chatRegion=c.region;S.chatCompartment=c.compartment_id||''} +function toggleModelDrop(){const dd=document.getElementById('mdd');dd.classList.toggle('open');if(dd.classList.contains('open')){const inp=document.getElementById('mds');inp.value='';inp.focus();filterModels('')}} +function pickModel(v){S.chatModel=v;document.getElementById('mdd').classList.remove('open'); + if(v&&!v.startsWith('cfg:')&&!S.chatOci&&S.ociCfg.length){S.chatOci=S.ociCfg[0].id;const c=S.ociCfg[0];S.chatRegion=c.region;S.chatCompartment=c.compartment_id||''} R()} +function filterModels(q){const list=document.getElementById('mdl');const items=list.querySelectorAll('.itm,.grp');const ql=q.toLowerCase(); + let lastGrp=null,grpHasVisible=false; + items.forEach(el=>{if(el.classList.contains('grp')){if(lastGrp)lastGrp.style.display=grpHasVisible?'':'none';lastGrp=el;grpHasVisible=false} + else{const show=!q||el.textContent.toLowerCase().includes(ql);el.style.display=show?'':'none';if(show)grpHasVisible=true}}); + if(lastGrp)lastGrp.style.display=grpHasVisible?'':'none'} +document.addEventListener('click',e=>{const dd=document.getElementById('mdd');if(dd&&dd.classList.contains('open')&&!e.target.closest('.mdrop'))dd.classList.remove('open')}) function chatOciChanged(){S.chatOci=document.getElementById('coci').value;const c=S.ociCfg.find(x=>x.id===S.chatOci);if(c){S.chatRegion=c.region;S.chatCompartment=c.compartment_id||''}} function toggleChatParams(){S.chatParamsOpen=!S.chatParamsOpen;R()} function fm(t){return t.replace(/\*\*(.*?)\*\*/g,'$1').replace(/`(.*?)`/g,'$1').replace(/\n/g,'
')}