fix: expose supports_tools toggle for local endpoints in UI (#3195)

* fix: expose supports_tools toggle for local endpoints in UI

Local endpoints (Ollama, vLLM, etc.) default to fenced tool blocks
when supports_tools is not set, which breaks tool calling for models
that support native function calling. The backend already supports
per-endpoint supports_tools overrides via the PATCH API, but there
was no UI to set it.

Add a 'Tools: Auto/On/Off' toggle button for local endpoints that
cycles through the three states:
- Auto (null): use the existing heuristic
- On (true): always use native function calling
- Off (false): always use fenced tool blocks

Fixes #3141

* docs: add screenshot of supports_tools toggle showing Auto/On/Off states

* Add Tools toggle screenshot for PR #3195

* refactor: convert Tools toggle to select dropdown per review feedback

Replace cycle-through button with a <select> dropdown for the
supports_tools tri-state setting. Options: Auto / On / Off with
explicit labels. Uses existing admin select styling. Fires PATCH
on change event. Same API contract (Auto=null, On=true, Off=false).

* Update Tools toggle screenshot (now dropdown select)

* fix: remove orphan screenshot and move Tools dropdown below button row

- Remove docs/screenshots/tools-toggle-three-states.png (unreferenced image causing test_no_orphan_images_in_docs to fail)
- Move Tools dropdown to its own line below Disable/Delete buttons, aligned right
- Keep Disable and Delete buttons grouped together per maintainer feedback

* fix: move Tools select onto same row left of Disable/Delete, use CSS class

Per vdmkenny feedback: move the Tools dropdown select from its own row below
the button group onto the same row, to the left of the Disable and Delete
buttons (which stay adjacent on the right). Replace inline style on the
button row with the existing .admin-ep-actions CSS class, adding
align-items:center for proper vertical alignment.

* chore: remove committed screenshots from tree

Screenshots should be in PR description/comments, not in repo history.

---------

Co-authored-by: michaelxer <michaelxer@users.noreply.github.com>
This commit is contained in:
michaelxer
2026-06-08 05:29:06 +07:00
committed by GitHub
parent 3557a3f495
commit 7b68413433
2 changed files with 35 additions and 1 deletions
+18 -1
View File
@@ -431,7 +431,8 @@ async function loadEndpoints() {
${ep.is_enabled ? '' : '<span class="admin-badge admin-badge-off">disabled</span>'}
${hasModels ? '<span style="font-size:10px;opacity:0.4;">Click to manage models</span>' : ''}
</div>
<div style="display:flex;gap:4px;align-items:center;">
<div class="admin-ep-actions">
${_isLocalEndpoint(ep.base_url) ? '<select class="admin-tools-select" data-adm-tools-select="' + ep.id + '" title="Native tool calling mode. Auto = use heuristic (fenced blocks for Ollama /v1). On = always use native function calling. Off = always use fenced blocks."><option value="auto"' + (ep.supports_tools !== true && ep.supports_tools !== false ? ' selected' : '') + '>Tools: Auto</option><option value="true"' + (ep.supports_tools === true ? ' selected' : '') + '>Tools: On</option><option value="false"' + (ep.supports_tools === false ? ' selected' : '') + '>Tools: Off</option></select>' : ''}
<button class="admin-btn-sm" data-adm-toggle-ep="${ep.id}">${ep.is_enabled ? 'Disable' : 'Enable'}</button>
<button class="admin-btn-delete" data-adm-del-ep="${ep.id}" data-adm-ep-online="${ep.online ? '1' : '0'}">Delete</button>
${hasModels ? '<svg class="admin-user-chevron" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" style="opacity:0.3;transition:transform 0.2s,opacity 0.2s;"><polyline points="6 9 12 15 18 9"/></svg>' : ''}
@@ -476,6 +477,22 @@ async function loadEndpoints() {
queryAll('[data-adm-toggle-ep]').forEach(btn => {
btn.addEventListener('click', async (e) => { e.stopPropagation(); await fetch(`/api/model-endpoints/${btn.dataset.admToggleEp}`, { method: 'PATCH' }); loadEndpoints(); });
});
queryAll('[data-adm-tools-select]').forEach(sel => {
sel.addEventListener('change', async (e) => {
e.stopPropagation();
const epId = sel.dataset.admToolsSelect;
const val = sel.value;
const body = {};
if (val === 'auto') body.supports_tools = null;
else body.supports_tools = val === 'true';
await fetch(`/api/model-endpoints/${epId}`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
});
loadEndpoints();
});
});
queryAll('[data-adm-copy-url]').forEach(btn => {
btn.addEventListener('click', (e) => {
e.stopPropagation();
+17
View File
@@ -14154,6 +14154,22 @@ body:has(.doc-version-panel:not(.hidden)) .hamburger-btn {
background: var(--border);
border-color: var(--red);
}
.admin-tools-select {
padding: 3px 6px;
border: 1px solid var(--border);
border-radius: 6px;
background: var(--panel);
color: var(--fg);
cursor: pointer;
font-size: 11px;
font-family: inherit;
height: 26px;
min-width: 90px;
}
.admin-tools-select:hover {
background: var(--border);
border-color: var(--red);
}
.admin-spinner {
display: inline-block;
width: 12px;
@@ -14269,6 +14285,7 @@ body:has(.doc-version-panel:not(.hidden)) .hamburger-btn {
.admin-ep-actions {
display: flex;
gap: 4px;
align-items: center;
flex-shrink: 0;
}