mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-21 16:18:55 +00:00
feat(cli): make reasoning effort session-scoped
This commit is contained in:
parent
8b6fde3a35
commit
8590c2d0d9
9 changed files with 269 additions and 50 deletions
4
cli.py
4
cli.py
|
|
@ -7151,11 +7151,15 @@ class HermesCLI(CLIAgentSetupMixin, CLICommandsMixin, CLIBillingMixin):
|
|||
self.conversation_history = []
|
||||
self._pending_title = None
|
||||
self._resumed = False
|
||||
self.reasoning_config = _parse_reasoning_config(
|
||||
CLI_CONFIG["agent"].get("reasoning_effort", "")
|
||||
)
|
||||
_sync_process_session_id(self.session_id)
|
||||
|
||||
if self.agent:
|
||||
self.agent.session_id = self.session_id
|
||||
self.agent.session_start = self.session_start
|
||||
self.agent.reasoning_config = self.reasoning_config
|
||||
self.agent.reset_session_state()
|
||||
if hasattr(self.agent, "_last_flushed_db_idx"):
|
||||
self.agent._last_flushed_db_idx = 0
|
||||
|
|
|
|||
|
|
@ -2516,12 +2516,13 @@ class CLICommandsMixin:
|
|||
Usage:
|
||||
/reasoning Show current effort level and display state
|
||||
/reasoning <level> Set effort (none, minimal, low, medium, high, xhigh, max, ultra)
|
||||
/reasoning <level> --session Set reasoning effort for this session only
|
||||
/reasoning show|on Show model thinking/reasoning in output
|
||||
/reasoning hide|off Hide model thinking/reasoning from output
|
||||
/reasoning full Show complete thinking (no 10-line clamp)
|
||||
/reasoning clamp Collapse long thinking to the first 10 lines
|
||||
"""
|
||||
from cli import _ACCENT, _DIM, _RST, _cprint, _parse_reasoning_config, save_config_value
|
||||
from cli import CLI_CONFIG, _ACCENT, _DIM, _RST, _cprint, _parse_reasoning_config, save_config_value
|
||||
parts = cmd.strip().split(maxsplit=1)
|
||||
|
||||
if len(parts) < 2:
|
||||
|
|
@ -2537,10 +2538,14 @@ class CLICommandsMixin:
|
|||
full_state = "full" if getattr(self, "reasoning_full", False) else "clamped to 10 lines"
|
||||
_cprint(f" {_ACCENT}Reasoning effort: {level}{_RST}")
|
||||
_cprint(f" {_ACCENT}Reasoning display: {display_state} ({full_state}){_RST}")
|
||||
_cprint(f" {_DIM}Usage: /reasoning <none|minimal|low|medium|high|xhigh|max|ultra|show|hide|full|clamp>{_RST}")
|
||||
_cprint(f" {_DIM}Usage: /reasoning <none|minimal|low|medium|high|xhigh|max|ultra|show|hide|full|clamp> [--session]{_RST}")
|
||||
return
|
||||
|
||||
arg = parts[1].strip().lower()
|
||||
arg_tokens = arg.split()
|
||||
explicit_session = "--session" in arg_tokens
|
||||
if explicit_session:
|
||||
arg = " ".join(token for token in arg_tokens if token != "--session")
|
||||
|
||||
# Display toggle
|
||||
if arg in {"show", "on"}:
|
||||
|
|
@ -2580,13 +2585,21 @@ class CLICommandsMixin:
|
|||
_cprint(f" {_DIM}(._.) Unknown argument: {arg}{_RST}")
|
||||
_cprint(f" {_DIM}Valid levels: none, minimal, low, medium, high, xhigh, max, ultra{_RST}")
|
||||
_cprint(f" {_DIM}Display: show, hide{_RST}")
|
||||
_cprint(f" {_DIM}Scope: saved by default, --session for a temporary override{_RST}")
|
||||
return
|
||||
|
||||
self.reasoning_config = parsed
|
||||
self.agent = None # Force agent re-init with new reasoning config
|
||||
|
||||
if save_config_value("agent.reasoning_effort", arg):
|
||||
if not explicit_session and save_config_value("agent.reasoning_effort", arg):
|
||||
agent_cfg = CLI_CONFIG.get("agent")
|
||||
if not isinstance(agent_cfg, dict):
|
||||
agent_cfg = {}
|
||||
CLI_CONFIG["agent"] = agent_cfg
|
||||
agent_cfg["reasoning_effort"] = arg
|
||||
_cprint(f" {_ACCENT}✓ Reasoning effort set to '{arg}' (saved to config){_RST}")
|
||||
elif not explicit_session:
|
||||
_cprint(f" {_ACCENT}✓ Reasoning effort set to '{arg}' (session only; config save failed){_RST}")
|
||||
else:
|
||||
_cprint(f" {_ACCENT}✓ Reasoning effort set to '{arg}' (session only){_RST}")
|
||||
|
||||
|
|
|
|||
|
|
@ -153,8 +153,8 @@ COMMAND_REGISTRY: list[CommandDef] = [
|
|||
CommandDef("yolo", "Toggle YOLO mode (skip all dangerous command approvals)",
|
||||
"Configuration"),
|
||||
CommandDef("reasoning", "Manage reasoning effort and display", "Configuration",
|
||||
args_hint="[level|show|hide|full|clamp]",
|
||||
subcommands=("none", "minimal", "low", "medium", "high", "xhigh", "max", "ultra", "show", "hide", "on", "off", "full", "clamp")),
|
||||
args_hint="[level|show|hide|full|clamp] [--session]",
|
||||
subcommands=("none", "minimal", "low", "medium", "high", "xhigh", "max", "ultra", "show", "hide", "on", "off", "full", "clamp", "--session")),
|
||||
CommandDef("fast", "Toggle fast mode — OpenAI Priority Processing / Anthropic Fast Mode (Normal/Fast)", "Configuration",
|
||||
args_hint="[normal|fast|status]",
|
||||
subcommands=("normal", "fast", "status", "on", "off")),
|
||||
|
|
|
|||
|
|
@ -154,6 +154,60 @@ class TestHandleReasoningCommand(unittest.TestCase):
|
|||
level = rc.get("effort", "medium")
|
||||
self.assertEqual(level, "xhigh")
|
||||
|
||||
def test_effort_defaults_to_global_save(self):
|
||||
"""Plain /reasoning <level> keeps the existing config-writing behavior."""
|
||||
from cli import CLI_CONFIG
|
||||
from hermes_cli.cli_commands_mixin import CLICommandsMixin
|
||||
|
||||
stub = self._make_cli(reasoning_config={"enabled": True, "effort": "medium"})
|
||||
with patch.dict(CLI_CONFIG.setdefault("agent", {}), {"reasoning_effort": "medium"}), \
|
||||
patch("cli.save_config_value", return_value=True) as save_config, \
|
||||
patch("cli._cprint"):
|
||||
CLICommandsMixin._handle_reasoning_command(stub, "/reasoning high")
|
||||
self.assertEqual(CLI_CONFIG["agent"]["reasoning_effort"], "high")
|
||||
|
||||
save_config.assert_called_once_with("agent.reasoning_effort", "high")
|
||||
self.assertEqual(stub.reasoning_config, {"enabled": True, "effort": "high"})
|
||||
self.assertIsNone(stub.agent)
|
||||
|
||||
def test_effort_session_flag_does_not_persist_config(self):
|
||||
"""--session opts into a temporary session-only effort override."""
|
||||
from hermes_cli.cli_commands_mixin import CLICommandsMixin
|
||||
|
||||
stub = self._make_cli(reasoning_config={"enabled": True, "effort": "medium"})
|
||||
with patch("cli.save_config_value") as save_config, patch("cli._cprint"):
|
||||
CLICommandsMixin._handle_reasoning_command(stub, "/reasoning high --session")
|
||||
|
||||
save_config.assert_not_called()
|
||||
self.assertEqual(stub.reasoning_config, {"enabled": True, "effort": "high"})
|
||||
self.assertIsNone(stub.agent)
|
||||
|
||||
def test_new_session_clears_session_reasoning_override(self):
|
||||
"""/new and /clear must not carry a session-only effort override forward."""
|
||||
from cli import CLI_CONFIG, HermesCLI
|
||||
|
||||
agent = SimpleNamespace(
|
||||
reasoning_config={"enabled": True, "effort": "high"},
|
||||
reset_session_state=MagicMock(),
|
||||
)
|
||||
stub = SimpleNamespace(
|
||||
agent=agent,
|
||||
conversation_history=[],
|
||||
session_id="old-session",
|
||||
_session_db=None,
|
||||
_pending_title=None,
|
||||
_resumed=False,
|
||||
reasoning_config={"enabled": True, "effort": "high"},
|
||||
_notify_session_boundary=MagicMock(),
|
||||
)
|
||||
|
||||
with patch.dict(CLI_CONFIG.setdefault("agent", {}), {"reasoning_effort": "medium"}):
|
||||
HermesCLI.new_session(stub, silent=True)
|
||||
|
||||
self.assertEqual(stub.reasoning_config, {"enabled": True, "effort": "medium"})
|
||||
self.assertEqual(agent.reasoning_config, {"enabled": True, "effort": "medium"})
|
||||
agent.reset_session_state.assert_called_once()
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Reasoning extraction and result dict
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ def test_reasoning_full_sets_and_persists(tmp_path, monkeypatch):
|
|||
assert saved["display"]["reasoning_full"] is True
|
||||
|
||||
|
||||
def test_reasoning_clamp_resets_and_persists(tmp_path, monkeypatch):
|
||||
def test_reasoning_clamp_resets_and_persists(tmp_path, monkeypatch, capsys):
|
||||
hh = _seed_config(tmp_path, monkeypatch)
|
||||
s = _Stub()
|
||||
s.reasoning_full = True
|
||||
|
|
@ -64,6 +64,7 @@ def test_reasoning_clamp_resets_and_persists(tmp_path, monkeypatch):
|
|||
assert s.reasoning_full is False
|
||||
saved = yaml.safe_load((hh / "config.yaml").read_text())
|
||||
assert saved["display"]["reasoning_full"] is False
|
||||
assert "Unknown argument" not in capsys.readouterr().out
|
||||
|
||||
|
||||
def test_reasoning_all_is_alias_for_full(tmp_path, monkeypatch):
|
||||
|
|
|
|||
|
|
@ -4649,8 +4649,18 @@ def test_complete_slash_details_args():
|
|||
assert any(item["text"] == "expanded" for item in resp_mode["result"]["items"])
|
||||
|
||||
|
||||
def test_complete_slash_reasoning_includes_current_efforts_and_session_scope():
|
||||
resp = server.handle_request(
|
||||
{"id": "1", "method": "complete.slash", "params": {"text": "/reasoning "}}
|
||||
)
|
||||
|
||||
values = {item["text"] for item in resp["result"]["items"]}
|
||||
assert {"max", "ultra", "--session"} <= values
|
||||
|
||||
|
||||
def test_config_set_reasoning_updates_live_session_and_agent(tmp_path, monkeypatch):
|
||||
monkeypatch.setattr(server, "_hermes_home", tmp_path)
|
||||
(tmp_path / "config.yaml").write_text("agent:\n reasoning_effort: medium\n", encoding="utf-8")
|
||||
agent = types.SimpleNamespace(reasoning_config=None)
|
||||
server._sessions["sid"] = _session(agent=agent)
|
||||
|
||||
|
|
@ -4658,11 +4668,42 @@ def test_config_set_reasoning_updates_live_session_and_agent(tmp_path, monkeypat
|
|||
{
|
||||
"id": "1",
|
||||
"method": "config.set",
|
||||
"params": {"session_id": "sid", "key": "reasoning", "value": "low"},
|
||||
"params": {
|
||||
"session_id": "sid",
|
||||
"key": "reasoning",
|
||||
"value": "low",
|
||||
},
|
||||
}
|
||||
)
|
||||
assert resp_effort["result"]["value"] == "low"
|
||||
assert agent.reasoning_config == {"enabled": True, "effort": "low"}
|
||||
assert server._sessions["sid"]["create_reasoning_override"] == {"enabled": True, "effort": "low"}
|
||||
assert server._load_cfg()["agent"]["reasoning_effort"] == "medium"
|
||||
|
||||
resp_status = server.handle_request(
|
||||
{
|
||||
"id": "5",
|
||||
"method": "config.get",
|
||||
"params": {"session_id": "sid", "key": "reasoning"},
|
||||
}
|
||||
)
|
||||
assert resp_status["result"]["value"] == "low"
|
||||
|
||||
resp_global_status = server.handle_request(
|
||||
{"id": "6", "method": "config.get", "params": {"key": "reasoning"}}
|
||||
)
|
||||
assert resp_global_status["result"]["value"] == "medium"
|
||||
|
||||
del server._sessions["sid"]["create_reasoning_override"]
|
||||
agent.reasoning_config = {"enabled": True, "effort": "high"}
|
||||
resp_agent_status = server.handle_request(
|
||||
{
|
||||
"id": "7",
|
||||
"method": "config.get",
|
||||
"params": {"session_id": "sid", "key": "reasoning"},
|
||||
}
|
||||
)
|
||||
assert resp_agent_status["result"]["value"] == "high"
|
||||
|
||||
resp_show = server.handle_request(
|
||||
{
|
||||
|
|
@ -4714,6 +4755,36 @@ def test_config_set_reasoning_updates_live_session_and_agent(tmp_path, monkeypat
|
|||
assert cfg_clamp["display"]["sections"]["thinking"] == "collapsed"
|
||||
|
||||
|
||||
def test_config_set_reasoning_global_scope_clears_session_override(tmp_path, monkeypatch):
|
||||
monkeypatch.setattr(server, "_hermes_home", tmp_path)
|
||||
(tmp_path / "config.yaml").write_text("agent:\n reasoning_effort: medium\n", encoding="utf-8")
|
||||
agent = types.SimpleNamespace(reasoning_config=None)
|
||||
server._sessions["sid"] = _session(agent=agent)
|
||||
server._sessions["sid"]["create_reasoning_override"] = {"enabled": True, "effort": "low"}
|
||||
|
||||
resp = server.handle_request(
|
||||
{
|
||||
"id": "1",
|
||||
"method": "config.set",
|
||||
"params": {
|
||||
"session_id": "sid",
|
||||
"key": "reasoning",
|
||||
"value": "high",
|
||||
"scope": "global",
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
assert resp["result"]["value"] == "high"
|
||||
assert server._load_cfg()["agent"]["reasoning_effort"] == "high"
|
||||
assert "create_reasoning_override" not in server._sessions["sid"]
|
||||
|
||||
status = server.handle_request(
|
||||
{"id": "2", "method": "config.get", "params": {"session_id": "sid", "key": "reasoning"}}
|
||||
)
|
||||
assert status["result"]["value"] == "high"
|
||||
|
||||
|
||||
def test_config_set_verbose_updates_session_mode_and_agent(tmp_path, monkeypatch):
|
||||
monkeypatch.setattr(server, "_hermes_home", tmp_path)
|
||||
agent = types.SimpleNamespace(verbose_logging=False)
|
||||
|
|
|
|||
|
|
@ -11555,6 +11555,8 @@ def _(rid, params: dict) -> dict:
|
|||
from hermes_constants import parse_reasoning_effort
|
||||
|
||||
arg = str(value or "").strip().lower()
|
||||
scope = str(params.get("scope") or "").strip().lower()
|
||||
global_scope = scope == "global"
|
||||
if arg in {"show", "on"}:
|
||||
cfg = _load_cfg()
|
||||
display = (
|
||||
|
|
@ -11634,23 +11636,25 @@ def _(rid, params: dict) -> dict:
|
|||
parsed = parse_reasoning_effort(arg)
|
||||
if parsed is None:
|
||||
return _err(rid, 4002, f"unknown reasoning value: {value}")
|
||||
if session is not None:
|
||||
if global_scope or session is None:
|
||||
_write_config_key("agent.reasoning_effort", arg)
|
||||
if session is not None:
|
||||
session.pop("create_reasoning_override", None)
|
||||
else:
|
||||
# Session-scoped, like the messaging gateway's `/reasoning
|
||||
# <level>` (global persistence is `--global` / Settings →
|
||||
# Model territory). Writing config.yaml here let every
|
||||
# desktop model-menu selection rewrite the user's global
|
||||
# agent.reasoning_effort to the preset default.
|
||||
session["create_reasoning_override"] = parsed
|
||||
if session.get("agent") is not None:
|
||||
session["agent"].reasoning_config = parsed
|
||||
_persist_live_session_runtime(session)
|
||||
_emit(
|
||||
"session.info",
|
||||
params.get("session_id", ""),
|
||||
_session_info(session["agent"], session),
|
||||
)
|
||||
else:
|
||||
_write_config_key("agent.reasoning_effort", arg)
|
||||
if session and session.get("agent") is not None:
|
||||
session["agent"].reasoning_config = parsed
|
||||
_persist_live_session_runtime(session)
|
||||
_emit(
|
||||
"session.info",
|
||||
params.get("session_id", ""),
|
||||
_session_info(session["agent"], session),
|
||||
)
|
||||
return _ok(rid, {"key": key, "value": arg})
|
||||
except Exception as e:
|
||||
return _err(rid, 5001, str(e))
|
||||
|
|
@ -12345,19 +12349,23 @@ def _(rid, params: dict) -> dict:
|
|||
)
|
||||
if key == "reasoning":
|
||||
cfg = _load_cfg()
|
||||
effort = ""
|
||||
# Prefer the session's live value — `config.set reasoning` is
|
||||
# session-scoped, so the global key may not reflect this chat.
|
||||
session = _sessions.get(params.get("session_id", ""))
|
||||
live = getattr((session or {}).get("agent"), "reasoning_config", None)
|
||||
if live is None and session is not None:
|
||||
live = session.get("create_reasoning_override")
|
||||
if isinstance(live, dict):
|
||||
if live.get("enabled") is False:
|
||||
reasoning_config = None
|
||||
if session is not None:
|
||||
if isinstance(session.get("create_reasoning_override"), dict):
|
||||
reasoning_config = session.get("create_reasoning_override")
|
||||
else:
|
||||
agent = session.get("agent")
|
||||
agent_reasoning = getattr(agent, "reasoning_config", None)
|
||||
if isinstance(agent_reasoning, dict):
|
||||
reasoning_config = agent_reasoning
|
||||
|
||||
if isinstance(reasoning_config, dict):
|
||||
if reasoning_config.get("enabled") is False:
|
||||
effort = "none"
|
||||
else:
|
||||
effort = str(live.get("effort", "") or "")
|
||||
if not effort:
|
||||
effort = str(reasoning_config.get("effort") or "medium")
|
||||
else:
|
||||
raw_effort = (cfg.get("agent") or {}).get("reasoning_effort", "")
|
||||
if raw_effort is False:
|
||||
# YAML `reasoning_effort: false`/`off`/`no` — thinking
|
||||
|
|
|
|||
|
|
@ -267,6 +267,43 @@ describe('createSlashHandler', () => {
|
|||
})
|
||||
})
|
||||
|
||||
it('reads /reasoning status for the active session', () => {
|
||||
patchUiState({ sid: 'sid-abc' })
|
||||
const ctx = buildCtx()
|
||||
|
||||
expect(createSlashHandler(ctx)('/reasoning')).toBe(true)
|
||||
expect(ctx.gateway.rpc).toHaveBeenCalledWith('config.get', {
|
||||
key: 'reasoning',
|
||||
session_id: 'sid-abc'
|
||||
})
|
||||
})
|
||||
|
||||
it.each(['low', 'max', 'ultra'])('sends plain /reasoning %s as global config.set', effort => {
|
||||
patchUiState({ sid: 'sid-abc' })
|
||||
const ctx = buildCtx()
|
||||
|
||||
expect(createSlashHandler(ctx)(`/reasoning ${effort}`)).toBe(true)
|
||||
expect(ctx.gateway.rpc).toHaveBeenCalledWith('config.set', {
|
||||
key: 'reasoning',
|
||||
scope: 'global',
|
||||
session_id: 'sid-abc',
|
||||
value: effort
|
||||
})
|
||||
})
|
||||
|
||||
it('strips /reasoning session flags before config.set', () => {
|
||||
patchUiState({ sid: 'sid-abc' })
|
||||
const ctx = buildCtx()
|
||||
|
||||
expect(createSlashHandler(ctx)('/reasoning low --session')).toBe(true)
|
||||
expect(ctx.gateway.rpc).toHaveBeenCalledWith('config.set', {
|
||||
key: 'reasoning',
|
||||
scope: 'session',
|
||||
session_id: 'sid-abc',
|
||||
value: 'low'
|
||||
})
|
||||
})
|
||||
|
||||
it('opens the skills hub locally for bare /skills', () => {
|
||||
const ctx = buildCtx()
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ import type { SlashCommand } from '../types.js'
|
|||
const USAGE_CTA = 'Run /subscription to change plan · /topup to add to your balance'
|
||||
|
||||
const TUI_SESSION_MODEL_RE = new RegExp(`(?:^|\\s)${TUI_SESSION_MODEL_FLAG}(?:\\s|$)`)
|
||||
const REASONING_SESSION_FLAGS = new Set(['--session'])
|
||||
const REASONING_EFFORT_VALUES = new Set(['none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max', 'ultra'])
|
||||
|
||||
const modelValueForConfigSet = (arg: string) => {
|
||||
const trimmed = arg.trim()
|
||||
|
|
@ -38,6 +40,33 @@ const modelValueForConfigSet = (arg: string) => {
|
|||
return trimmed
|
||||
}
|
||||
|
||||
const reasoningConfigPayload = (arg: string, sid: string) => {
|
||||
const parts = arg.trim().split(/\s+/).filter(Boolean)
|
||||
let scope = ''
|
||||
const valueParts: string[] = []
|
||||
|
||||
for (const part of parts) {
|
||||
const flag = part.toLowerCase()
|
||||
if (REASONING_SESSION_FLAGS.has(flag)) {
|
||||
scope = 'session'
|
||||
continue
|
||||
}
|
||||
valueParts.push(part)
|
||||
}
|
||||
|
||||
const value = valueParts.join(' ')
|
||||
if (!scope && REASONING_EFFORT_VALUES.has(value.toLowerCase())) {
|
||||
scope = 'global'
|
||||
}
|
||||
|
||||
return {
|
||||
key: 'reasoning',
|
||||
session_id: sid,
|
||||
value,
|
||||
...(scope ? { scope } : {})
|
||||
}
|
||||
}
|
||||
|
||||
export const sessionCommands: SlashCommand[] = [
|
||||
{
|
||||
aliases: ['bg', 'btw'],
|
||||
|
|
@ -445,7 +474,7 @@ export const sessionCommands: SlashCommand[] = [
|
|||
run: (arg, ctx) => {
|
||||
if (!arg) {
|
||||
return ctx.gateway
|
||||
.rpc<ConfigGetValueResponse>('config.get', { key: 'reasoning' })
|
||||
.rpc<ConfigGetValueResponse>('config.get', { key: 'reasoning', session_id: ctx.sid })
|
||||
.then(
|
||||
ctx.guarded<ConfigGetValueResponse>(
|
||||
r => r.value && ctx.transcript.sys(`reasoning: ${r.value} · display ${r.display || 'hide'}`)
|
||||
|
|
@ -453,29 +482,31 @@ export const sessionCommands: SlashCommand[] = [
|
|||
)
|
||||
}
|
||||
|
||||
ctx.gateway.rpc<ConfigSetResponse>('config.set', { key: 'reasoning', session_id: ctx.sid, value: arg }).then(
|
||||
ctx.guarded<ConfigSetResponse>(r => {
|
||||
if (!r.value) {
|
||||
return
|
||||
}
|
||||
ctx.gateway
|
||||
.rpc<ConfigSetResponse>('config.set', reasoningConfigPayload(arg, ctx.sid ?? ''))
|
||||
.then(
|
||||
ctx.guarded<ConfigSetResponse>(r => {
|
||||
if (!r.value) {
|
||||
return
|
||||
}
|
||||
|
||||
if (r.value === 'hide') {
|
||||
patchUiState(state => ({
|
||||
...state,
|
||||
sections: { ...state.sections, thinking: 'hidden' },
|
||||
showReasoning: false
|
||||
}))
|
||||
} else if (r.value === 'show') {
|
||||
patchUiState(state => ({
|
||||
...state,
|
||||
sections: { ...state.sections, thinking: 'expanded' },
|
||||
showReasoning: true
|
||||
}))
|
||||
}
|
||||
if (r.value === 'hide') {
|
||||
patchUiState(state => ({
|
||||
...state,
|
||||
sections: { ...state.sections, thinking: 'hidden' },
|
||||
showReasoning: false
|
||||
}))
|
||||
} else if (r.value === 'show') {
|
||||
patchUiState(state => ({
|
||||
...state,
|
||||
sections: { ...state.sections, thinking: 'expanded' },
|
||||
showReasoning: true
|
||||
}))
|
||||
}
|
||||
|
||||
ctx.transcript.sys(`reasoning: ${r.value}`)
|
||||
})
|
||||
)
|
||||
ctx.transcript.sys(`reasoning: ${r.value}`)
|
||||
})
|
||||
)
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue