mirror of
https://github.com/turnstonelabs/turnstone.git
synced 2026-08-12 23:12:23 -06:00
feat(console): Always-on thinking-mode option in the model form
Post effort-knob rework, "Enabled" (manual) means knob-controlled — effort none turns thinking off. Operators who want the pre-#771 always-on behavior (knob never disables) previously had to hand-write thinking_mode "adaptive" into the raw capabilities JSON. The dropdown now offers all three representable modes — None / Effort-knob controlled / Always on — and the edit-load lift captures adaptive instead of relegating it to raw JSON.
This commit is contained in:
@@ -807,14 +807,15 @@ the levers live in the chat template, reached through
|
||||
`chat_template_kwargs` in the request body. Two channels, dynamic first:
|
||||
|
||||
* **Session effort knob (dynamic).** Set the model's thinking mode to
|
||||
Enabled in the admin Models form (or `thinking_mode = "manual"` +
|
||||
`thinking_param` under `[models.*.capabilities]`) and the provider
|
||||
maps the session's reasoning-effort knob onto the template toggle
|
||||
per-request: effort `none` sends `{<thinking_param>: false}`, any
|
||||
other level sends `true` — the same contract as the real lane's
|
||||
manual mode. (`thinking_mode = "adaptive"` instead always sends
|
||||
`true`: adaptive means the model self-regulates, so the knob never
|
||||
force-disables — mirroring the native adaptive branch.) Templates
|
||||
"Effort-knob controlled" in the admin Models form (or
|
||||
`thinking_mode = "manual"` + `thinking_param` under
|
||||
`[models.*.capabilities]`) and the provider maps the session's
|
||||
reasoning-effort knob onto the template toggle per-request: effort
|
||||
`none` sends `{<thinking_param>: false}`, any other level sends
|
||||
`true` — the same contract as the real lane's manual mode. ("Always
|
||||
on" / `thinking_mode = "adaptive"` instead always sends `true`: the
|
||||
model self-regulates, so the knob never force-disables — mirroring
|
||||
the native adaptive branch.) Templates
|
||||
with a graded effort key (gpt-oss-style) additionally set
|
||||
`effort_param` (e.g. `"reasoning_effort"`), plus optional
|
||||
`reasoning_effort_values` / `default_reasoning_effort` to validate
|
||||
|
||||
@@ -6980,13 +6980,14 @@ function showEditModelModal(definitionId) {
|
||||
? capsObj.server_compat
|
||||
: {};
|
||||
// Only extract thinking_mode into the dropdown when the UI can
|
||||
// represent it ("manual" or ""). Unrepresentable values like
|
||||
// "adaptive" keep thinking_mode in the raw capabilities JSON so it
|
||||
// isn't silently lost on save. Both compat lanes round-trip the
|
||||
// dropdown: on anthropic-compatible it drives the effort-knob →
|
||||
// chat_template_kwargs mapping (merge_reasoning_template_kwargs).
|
||||
// represent it ("", "manual" = effort-knob controlled, "adaptive" =
|
||||
// always on). Unrepresentable/garbage values keep thinking_mode in
|
||||
// the raw capabilities JSON so they aren't silently lost on save.
|
||||
// Both compat lanes round-trip the dropdown: it drives the
|
||||
// effort-knob → chat_template_kwargs mapping
|
||||
// (merge_reasoning_template_kwargs).
|
||||
const tmVal = capsObj.thinking_mode || "";
|
||||
const tmCaptured = tmVal === "" || tmVal === "manual";
|
||||
const tmCaptured = tmVal === "" || tmVal === "manual" || tmVal === "adaptive";
|
||||
if (tmCaptured) {
|
||||
document.getElementById("model-thinking-mode").value = tmVal;
|
||||
document.getElementById("model-thinking-param").value =
|
||||
|
||||
@@ -1771,7 +1771,8 @@
|
||||
>
|
||||
<select id="model-thinking-mode">
|
||||
<option value="">None</option>
|
||||
<option value="manual">Enabled</option>
|
||||
<option value="manual">Effort-knob controlled</option>
|
||||
<option value="adaptive">Always on</option>
|
||||
</select>
|
||||
<div id="model-thinking-param-row" hidden>
|
||||
<label for="model-thinking-param"
|
||||
|
||||
Reference in New Issue
Block a user