diff --git a/web-ui/html/workshop-app.html b/web-ui/html/workshop-app.html
index 0418028..b14cb76 100644
--- a/web-ui/html/workshop-app.html
+++ b/web-ui/html/workshop-app.html
@@ -72,6 +72,16 @@ body{background:var(--bg);color:var(--text);font-family:system-ui,sans-serif;dis
.rb-send:hover:not(:disabled){background:#9a5c03;}
.rb-send:disabled{opacity:.5;cursor:not-allowed;}
+.rb-model-pill{position:relative;flex-shrink:0;}
+.rb-model-pill-btn{background:none;border:1px solid var(--line);border-radius:6px;padding:2px 8px;font-size:10px;font-weight:700;color:var(--muted);cursor:pointer;font-family:inherit;max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;transition:.15s;}
+.rb-model-pill-btn:hover{border-color:#f59e0b;color:#f59e0b;}
+.rb-model-dropdown{display:none;position:absolute;top:100%;right:0;margin-top:4px;background:var(--panel-2);border:1px solid var(--line);border-radius:8px;box-shadow:0 4px 16px rgba(0,0,0,.35);min-width:200px;max-height:280px;overflow-y:auto;z-index:50;padding:4px;}
+.rb-model-dropdown.open{display:block;}
+.rb-model-opt{padding:6px 10px;font-size:12px;border-radius:5px;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--text);}
+.rb-model-opt:hover{background:var(--panel);}
+.rb-model-opt.current{color:#f59e0b;font-weight:700;}
+.rb-model-dropdown-msg{padding:6px 10px;font-size:11px;color:var(--muted);}
+
@media (max-width:900px){
.rb-layout{flex-direction:column;}
.rb-resize{display:none;}
@@ -224,6 +234,10 @@ body{background:var(--bg);color:var(--text);font-family:system-ui,sans-serif;dis
π οΈ μμ
μ€ μ±ν
+
@@ -847,12 +861,68 @@ function autoResize(el){el.style.height='auto';el.style.height=Math.min(el.scrol
document.addEventListener('mouseup',()=>{if(!dragging)return;dragging=false;handle.classList.remove('dragging');document.body.style.userSelect='';document.body.style.cursor='';try{localStorage.setItem(CHAT_W,panel.offsetWidth);}catch{};});
})();
+// ββ λͺ¨λΈ pill βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+// κ²½λ λ²μ : λ©μΈ μ±ν
μ μ€μ λͺ¨λ¬(settings-provider.js)μ ν΅μ§Έλ‘ λ€μ¬μ€μ§ μκ³ , κ°μ λ°±μλ
+// μλν¬μΈνΈ(/api/settings/model, /api/settings/provider, /api/models/test)λ§ μ¬μ¬μ©ν΄μ
+// μ μ models.primaryλ₯Ό λ°κΎΌλ€. ollama provider(λ‘컬+ν΄λΌμ°λ λͺ¨λΈ νκ·Έ) μμμλ§ μ νλ¨ β
+// provider μ체(openai/anthropic/google λ±)λ₯Ό λ°κΎΈλ 건 λ©μΈ μ€μ μμ ν΄μΌ νλ€.
+let _modelDropdownLoaded=false;
+async function loadModelPill(){
+ try{
+ const r=await fetch('/api/settings/model',{headers:authH()});
+ if(!r.ok)return;
+ const d=await r.json();
+ const btn=document.getElementById('model-pill-btn');
+ if(btn && d.primary) btn.textContent=d.primary;
+ }catch{}
+}
+async function toggleModelDropdown(ev){
+ if(ev) ev.stopPropagation();
+ const dd=document.getElementById('model-dropdown');
+ if(dd.classList.contains('open')){dd.classList.remove('open');return;}
+ dd.classList.add('open');
+ if(_modelDropdownLoaded)return;
+ dd.innerHTML='λͺ¨λΈ λΆλ¬μ€λ μ€β¦
';
+ try{
+ const pr=await fetch('/api/settings/provider',{headers:authH()});
+ const pd=await pr.json();
+ const tr=await fetch('/api/models/test',{method:'POST',headers:authH({'Content-Type':'application/json'}),body:JSON.stringify({llm:pd.llm})});
+ const td=await tr.json();
+ const models=(td.models||[]).map(m=>typeof m==='string'?m:(m.name||String(m)));
+ if(!models.length){dd.innerHTML='λͺ¨λΈ λͺ©λ‘μ κ°μ Έμ€μ§ λͺ»νμ΅λλ€.
';return;}
+ const current=(document.getElementById('model-pill-btn').textContent||'').trim();
+ dd.innerHTML=models.map(m=>`${escHtml(m)}
`).join('');
+ dd.querySelectorAll('.rb-model-opt').forEach(el=>el.addEventListener('click',()=>selectModel(el.dataset.model)));
+ _modelDropdownLoaded=true;
+ }catch(e){dd.innerHTML='μ€λ₯: '+escHtml(e.message)+'
';}
+}
+async function selectModel(name){
+ document.getElementById('model-dropdown').classList.remove('open');
+ const btn=document.getElementById('model-pill-btn');
+ const prev=btn.textContent;
+ if(name===prev)return;
+ btn.textContent=name;
+ try{
+ const r=await fetch('/api/settings/model',{method:'POST',headers:authH({'Content-Type':'application/json'}),body:JSON.stringify({primary:name})});
+ if(!r.ok)throw new Error('μ μ₯ μ€ν¨');
+ _modelDropdownLoaded=false;
+ }catch(e){
+ btn.textContent=prev;
+ addMsg('system','λͺ¨λΈ λ³κ²½ μ€ν¨: '+e.message);
+ }
+}
+document.addEventListener('click',(e)=>{
+ const pill=document.querySelector('.rb-model-pill');
+ if(pill && !pill.contains(e.target)) document.getElementById('model-dropdown')?.classList.remove('open');
+});
+
// ββ Init ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
(async function init(){
if(!(await checkAuth()))return;
await loadWorkshopData();
await initSessionId();
await loadHistory();
+ loadModelPill();
addMsg('system','π οΈ μμ
μ€ μ±ν
μ
λλ€. νμ¬ νλ‘μ νΈ: "'+(currentProject()?.name||'')+'". λΆν ꡬ맀/μν λ³κ²½, μμ
μλ£ μ²΄ν¬, μμ° νμΈ, μ νλ‘μ νΈ μμ± λ±μ λ¬Όμ΄λ³΄μΈμ.');
document.getElementById('chat-input').focus();
})();