diff --git a/backend/app.py b/backend/app.py index 1a327e5..2eb49a5 100644 --- a/backend/app.py +++ b/backend/app.py @@ -1577,7 +1577,16 @@ async def chat(msg: ChatMsg, u=Depends(current_user)): genai_cfg = None if msg.genai_config_id: with db() as c: - genai_cfg = c.execute("SELECT * FROM genai_configs WHERE id=?", (msg.genai_config_id,)).fetchone() + row = c.execute("SELECT * FROM genai_configs WHERE id=?", (msg.genai_config_id,)).fetchone() + if row: + genai_cfg = dict(row) + # Override params from inline chat settings if provided + if msg.temperature is not None: genai_cfg["temperature"] = msg.temperature + if msg.max_tokens is not None: genai_cfg["max_tokens"] = msg.max_tokens + if msg.top_p is not None: genai_cfg["top_p"] = msg.top_p + if msg.top_k is not None: genai_cfg["top_k"] = msg.top_k + if msg.frequency_penalty is not None: genai_cfg["frequency_penalty"] = msg.frequency_penalty + if msg.presence_penalty is not None: genai_cfg["presence_penalty"] = msg.presence_penalty elif msg.model_id and msg.oci_config_id: # Direct model mode: build synthetic config dict with db() as c: diff --git a/frontend/index.html b/frontend/index.html index 1bf6da3..e135990 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -272,13 +272,14 @@ function rChat(){ 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(''); const isDirect=S.chatModel&&!S.chatModel.startsWith('cfg:'); + const hasModel=!!S.chatModel; // OCI selector for direct mode const ociSel=isDirect?``:''; - const gearBtn=isDirect?`
${S.chatParamsOpen?'✕':'⚙️'}
`:''; + const gearBtn=hasModel?`
${S.chatParamsOpen?'✕':'⚙️'}
`:''; const ragBadge=S.adbCfg.some(c=>c.genai_config_id&&c.is_active)?'RAG':''; - // Params panel + // Params panel - available for any model (direct or preset) const pp=S.chatParams; - const paramsPanel=isDirect&&S.chatParamsOpen?`
+ const paramsPanel=hasModel&&S.chatParamsOpen?`
@@ -294,8 +295,7 @@ ${paramsPanel}
${ms}
`} function chatModelChanged(){S.chatModel=document.getElementById('cmod').value; - if(S.chatModel.startsWith('cfg:')){S.chatParamsOpen=false} - else if(S.chatModel&&!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||''} + 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||''} R()} 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()} @@ -303,7 +303,10 @@ function fm(t){return t.replace(/\*\*(.*?)\*\*/g,'$1').replace( async function sChat(){const el=document.getElementById('chi');const m=el.value.trim();if(!m)return;el.value=''; S.msgs.push({r:'user',c:m});R();scCh(); try{const body={message:m,session_id:S.sid}; - if(S.chatModel.startsWith('cfg:')){body.genai_config_id=S.chatModel.slice(4)} + 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} body.model_id=S.chatModel;body.oci_config_id=S.chatOci;body.genai_region=S.chatRegion;body.compartment_id=S.chatCompartment; @@ -418,29 +421,21 @@ function rGenAI(){const eg=S.editing?.type==='genai'?S.genaiCfg.find(g=>g.id===S const mOpts=''+Object.entries(S.models).map(([k,v])=>``).join(''); const rOpts=S.regions.map(r=>``).join(''); return`
🧠 Modelos Configurados
- +
ConfigModeloRegiãoTempTokensAções
${S.genaiCfg.map(g=>{const mi=S.models[g.model_id]||{};return` -`}).join('')}
ConfigModeloRegiãoAções
${g.name||'—'}${g.is_default?' ⭐':''} ${mi.name||(g.model_ocid?'OCID Personalizado':g.model_id)}
${mi.provider||(g.model_ocid?'custom':'?')}
${g.genai_region}${g.temperature}${g.max_tokens}
${!S.genaiCfg.length?'

Nenhum modelo configurado.

':''}
${eg?'✏️ Editar Modelo GenAI':'➕ Novo Modelo GenAI'}
-
${eg?'Editando: '+eg.name+'':'Configura conexão via OCI SDK (GenerativeAiInferenceClient). O endpoint é gerado automaticamente pela região selecionada.'}
-
+
${eg?'Editando: '+eg.name+'':'Adicione modelos personalizados que não estão no catálogo do Chat Agent, ou crie presets com credenciais específicas.'}
+
Cole o OCID do modelo do portal OCI. Se preenchido, será usado no lugar do modelo selecionado acima.
-
Parâmetros
-
-
-
-
-
-
${eg?'':''}
`+rConfigLogs('genai')} async function sGenai(){const btn=document.getElementById('gbtn');btn.disabled=true;btn.textContent='Salvando...';sm('gm',' Salvando modelo...','i'); @@ -453,9 +448,6 @@ async function sGenai(){const btn=document.getElementById('gbtn');btn.disabled=t model_ocid:ocid, compartment_id:document.getElementById('gcmp').value,genai_region:document.getElementById('greg').value, endpoint:null,serving_type:'ON_DEMAND',dedicated_endpoint_id:null, - temperature:parseFloat(document.getElementById('gtemp').value),max_tokens:parseInt(document.getElementById('gmt').value), - top_p:parseFloat(document.getElementById('gtp').value),top_k:parseInt(document.getElementById('gtk').value), - frequency_penalty:parseFloat(document.getElementById('gfp').value),presence_penalty:parseFloat(document.getElementById('gpp').value), is_default:isEdit?(S.genaiCfg.find(g=>g.id===S.editing.id)?.is_default||false):S.genaiCfg.length===0}; try{const url=isEdit?'/genai/configs/'+S.editing.id:'/genai/config';const method=isEdit?'PUT':'POST'; await $api(url,{method,body});S.editing=null;S.genaiCfg=await $api('/genai/configs');sm('gm','✅ Modelo '+(isEdit?'atualizado':'salvo')+' com sucesso!','s');R()}catch(e){sm('gm',e.message,'e');btn.disabled=false;btn.textContent=isEdit?'Salvar Alterações':'Salvar Modelo'}}