Settings polish: /setup provider subs, Add API defaults to api kind, picker shows offline endpoints, doc library tracks sub-tab
- /setup gains explicit provider subcommands (deepseek, openai, anthropic, openrouter, groq, gemini, xai, ollama, copilot, local, endpoint) so the autocomplete popup surfaces "/setup de…" suggestions with format hints, and bare-provider invocations still prompt for the key. - Add API endpoint defaults to kind=api (auto-refresh /v1/models) instead of kind=proxy. Proxy was a frequent footgun for OpenAI- compatible endpoints that DO serve /v1/models — the user got an empty model list and had to flip the dropdown. - Model picker now includes offline endpoints with stale:true so a briefly-down local server doesn't vanish from the picker (it dims and shows the offline pill, clickable anyway). Dedup prefers the online entry when the same model is exposed by both. - Document library modal header reflects the active sub-tab via _TAB_HEADERS so it no longer shows the wrong section name when switching between Documents / Skills / Templates.
This commit is contained in:
@@ -1598,7 +1598,11 @@ let _libraryArchivedView = false; // Documents tab showing archived docs?
|
||||
modal.innerHTML = `
|
||||
<div class="modal-content doclib-modal-content" style="width:min(640px, 92vw);max-height:85vh;background:var(--bg);">
|
||||
<div class="modal-header">
|
||||
<h4><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:-2px;margin-right:4px;"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/><line x1="8" y1="7" x2="16" y2="7"/><line x1="8" y1="11" x2="14" y2="11"/></svg>Library</h4>
|
||||
<!-- Header title + icon mirror the currently-active sub-tab (Chats /
|
||||
Documents / Research / Archive) so the user sees ONE icon at
|
||||
the top representing the section they're in, with the tab
|
||||
strip below as sub-navigation. _switchLibTab() updates this. -->
|
||||
<h4 id="doclib-header-title"><span id="doclib-header-icon" style="vertical-align:-2px;margin-right:4px;display:inline-flex;"></span><span id="doclib-header-text">Library</span></h4>
|
||||
<button class="close-btn" id="doclib-close">\u2716</button>
|
||||
</div>
|
||||
<div class="lib-tabs" id="doclib-lib-tabs" style="padding:0 10px;">
|
||||
@@ -1831,6 +1835,27 @@ let _libraryArchivedView = false; // Documents tab showing archived docs?
|
||||
grid.parentElement.appendChild(btn);
|
||||
}
|
||||
|
||||
// SVG markup + label for each tab — used to keep the modal header
|
||||
// in sync with whichever sub-tab the user is on.
|
||||
const _TAB_HEADERS = {
|
||||
chats: {
|
||||
label: 'Chats',
|
||||
svg: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>',
|
||||
},
|
||||
documents: {
|
||||
label: 'Documents',
|
||||
svg: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="8" y1="13" x2="16" y2="13"/><line x1="8" y1="17" x2="13" y2="17"/></svg>',
|
||||
},
|
||||
research: {
|
||||
label: 'Research',
|
||||
svg: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="M21 21l-4.35-4.35"/><line x1="11" y1="8" x2="11" y2="14"/><line x1="8" y1="11" x2="14" y2="11"/></svg>',
|
||||
},
|
||||
archive: {
|
||||
label: 'Archive',
|
||||
svg: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="21 8 21 21 3 21 3 8"/><rect x="1" y="3" width="22" height="5"/><line x1="10" y1="12" x2="14" y2="12"/></svg>',
|
||||
},
|
||||
};
|
||||
|
||||
function _switchLibTab(tab) {
|
||||
_activeLibTab = tab;
|
||||
_tabBtns.forEach(b => b.classList.toggle('active', b.dataset.doclibTab === tab));
|
||||
@@ -1841,6 +1866,14 @@ let _libraryArchivedView = false; // Documents tab showing archived docs?
|
||||
p.style.display = 'none';
|
||||
}
|
||||
});
|
||||
// Sync the modal header icon + label to match the active sub-tab.
|
||||
const hdr = _TAB_HEADERS[tab];
|
||||
if (hdr) {
|
||||
const ico = document.getElementById('doclib-header-icon');
|
||||
const txt = document.getElementById('doclib-header-text');
|
||||
if (ico) ico.innerHTML = hdr.svg;
|
||||
if (txt) txt.textContent = hdr.label;
|
||||
}
|
||||
if (tab === 'chats') _renderLibChats();
|
||||
else if (tab === 'archive') _renderLibArchive();
|
||||
else if (tab === 'research') _renderLibResearch();
|
||||
@@ -3121,8 +3154,10 @@ let _libraryArchivedView = false; // Documents tab showing archived docs?
|
||||
return new Date(iso).toLocaleDateString();
|
||||
}
|
||||
|
||||
// Switch to initial tab if not documents
|
||||
if (_activeLibTab !== 'documents') _switchLibTab(_activeLibTab);
|
||||
// Switch to the initial tab. Always call this — even when the
|
||||
// default ('documents') matches — so the modal header's icon + label
|
||||
// sync from "Library" to the active sub-tab on first open.
|
||||
_switchLibTab(_activeLibTab);
|
||||
|
||||
const searchInput = document.getElementById('doclib-search');
|
||||
searchInput.addEventListener('input', () => {
|
||||
|
||||
Reference in New Issue
Block a user