Skip to content

gut(ui): remove dead thinkingLevel display plumbing (#2336 Area 7)#2471

Merged
alexey-pelykh merged 1 commit intomainfrom
gut/audit-display-thinking-level-2467
Apr 22, 2026
Merged

gut(ui): remove dead thinkingLevel display plumbing (#2336 Area 7)#2471
alexey-pelykh merged 1 commit intomainfrom
gut/audit-display-thinking-level-2467

Conversation

@alexey-pelykh
Copy link
Copy Markdown

Summary

Follow-up to #2336 (umbrella) / #2463 (Areas 1+2+4). Completes Area 7
for the Web UI surface only. Native-app state-drivers deferred per
the umbrella issue's "Do NOT touch native apps without confirming"
guidance — full classification report below so that work can be scoped
separately.

  • Web UI (ui/src/ui/): 8 files, +5/-21 — all dead display plumbing.
  • Native apps: classified below, NOT modified (release coordination
    required).
  • False positives in issue file list identified: format.test.ts /
    AssistantTextParserTests.swift only touch <think> XML tag parsing
    (CLI output display), unrelated to thinkingLevel field — kept as-is.

Why this is safe

Web UI thinkingLevel was dead display plumbing:

  • Read from chat.history response into state.chatThinkingLevel.
  • Passed through ChatProps.thinkingLevel to renderChat.
  • But the view body never read the proprenderChat uses
    activeSession?.reasoningLevel for its single reasoning branch
    (ui/src/ui/views/chat.ts:246), not thinkingLevel.
  • No UI code sends thinkingLevelpatchSession in
    ui/src/ui/controllers/sessions.ts:60-84 only handles
    label / verboseLevel.

Removing a read-only field that's never rendered and never sent has
zero runtime effect.

Changes

File Change
ui/src/ui/types.ts Drop phantom `thinkingLevel?` from `GatewaySessionRow` (426) and `SessionsPatchResult.entry` (452)
ui/src/ui/controllers/chat.ts Drop `chatThinkingLevel` from `ChatState`, narrow `chat.history` response type, drop state assignment
ui/src/ui/app-view-state.ts Drop `chatThinkingLevel` from `AppViewState`
ui/src/ui/app.ts Drop `@state() chatThinkingLevel`
ui/src/ui/app-render.ts Drop `thinkingLevel` from `ChatProps` pass-through
ui/src/ui/views/chat.ts Drop unused `thinkingLevel: string | null` prop from `ChatProps`
ui/src/ui/views/chat.test.ts, ui/src/ui/controllers/chat.test.ts Drop test fixtures/assertions for removed plumbing

Native-app audit report (deferred — informational only)

All native-app files classified as STATE-DRIVERS: they compose
mutable `thinkingLevel` state AND send it to the backend via
`sessions.patch({thinkingLevel})` and/or `chat.send(thinking:)`.
Require release coordination.

Android (4 files)

File Classification Evidence
apps/android/.../app/chat/ChatController.kt STATE-DRIVER `MutableStateFlow("off")` (42-43); `setThinkingLevel()` mutator (98); `sendMessage(thinkingLevel=...)` sends to backend (114-129)
apps/android/.../app/chat/ChatModels.kt DATA MODEL `ChatHistory.thinkingLevel: String?` (35) — parsed from `chat.history`
apps/android/.../android/chat/ChatController.kt STATE-DRIVER Parallel path to above
apps/android/.../android/NodeRuntime.kt STATE-DRIVER EXPOSURE `chatThinkingLevel: StateFlow` (536); `sendChat()` forwards to `ChatController.sendMessage(thinkingLevel=thinking)` (879)

iOS / macOS / shared (RemoteClawKit) (6 files)

File Classification Evidence
RemoteClawChatUI/ChatViewModel.swift STATE-DRIVER Mutable `thinkingLevel` (22); `sendMessage(thinking: thinkingLevel)` (440); `setSessionThinking` → `transport.setSessionThinking(thinkingLevel:)` (515, 519)
RemoteClawChatUI/ChatSessions.swift DATA MODEL `thinkingLevel: String?` on session row (53)
RemoteClawChatUI/ChatComposer.swift STATE-DRIVER UI Picker bound to `viewModel.selectThinkingLevel(next)` (95-96)
RemoteClawChatUI/ChatTransport.swift STATE-DRIVER PROTOCOL `setSessionThinking(sessionKey:, thinkingLevel:)` (24) → `sessions.patch(thinkingLevel)`
RemoteClawChatUI/ChatModels.swift DATA MODEL `thinkingLevel: String?` on response model (235)
OpenClawChatUI/ChatComposer.swift STATE-DRIVER UI (upstream-inherited, not in Package.swift) Picker bound to `$viewModel.thinkingLevel` (86)
Tests/RemoteClawKitTests/ChatViewModelTests.swift TEST (state-driver behavior) Tests for `thinkingLevel`/`selectThinkingLevel` flow

macOS-only (3 files — 2 unlisted in issue)

File Classification Evidence
apps/macos/Sources/RemoteClaw/WebChatSwiftUI.swift STATE-DRIVER `webChatThinkingLevelDefaultsKey` persistence (11); `setSessionThinking()` → `sessions.patch({thinkingLevel})` (76-82)
apps/macos/Sources/RemoteClaw/MenuSessionsInjector.swift (unlisted) MIXED (display + state-driver) Reads `row.thinkingLevel` to build menu (841); `patchThinking(_:)` action sends to backend
apps/macos/Tests/RemoteClawIPCTests/SessionDataTests.swift (unlisted) TEST FIXTURE `thinkingLevel: "high"` in session row fixture (36)

False positives in issue file list

File Why it's a false positive
ui/src/ui/format.test.ts Only tests `stripThinkingTags` — strips `` XML blocks from assistant output. Unrelated to `thinkingLevel` field.
apps/shared/RemoteClawKit/Tests/OpenClawKitTests/AssistantTextParserTests.swift Only tests ``/`` XML tag parsing. Same story.

Both preserved unchanged (legitimate display of CLI assistant output).

Sequencing for #2464

#2464 removes backend `SessionEntry.thinkingLevel` + gateway schema.
Reader-before-writer ordering:

  1. This PR (audit(apps+ui): thinkingLevel display-layer classification (#2336 Area 7) #2467) — UI reader of `thinkingLevel` from `chat.history`
    removed. Safe: backend continues to send it, UI ignores.
  2. gut(session): drop SessionEntry.thinkingLevel field + gateway schema (#2336 Area 3) #2464 next — backend stops sending the field. Safe: UI already
    doesn't read it.
  3. Native-app state-drivers remain — they'll break on
    `sessions.patch({thinkingLevel})` once backend removes schema
    validation. Coordination required with native release pipelines
    before gut(session): drop SessionEntry.thinkingLevel field + gateway schema (#2336 Area 3) #2464 lands.

Verification

  • `grep thinkingLevel|chatThinkingLevel|thinkLevel` in `ui/` → 0
    matches
  • `pnpm check` (format + tsgo + lint + 2× project-specific linters)
    → exit 0
  • `pnpm test src/ui/controllers/chat.test.ts src/ui/views/chat.test.ts`
    35/35 passed
  • Other UI test failures match `origin/main` baseline (18 pre-existing,
    unrelated to `thinkingLevel`)
  • CI green on all required checks (pending this PR's run)

Test plan

  • `pnpm check` locally
  • Targeted tests for modified files
  • CI: build, test, lint, docs, rebrand-gate, zombie-import-gate,
    stub-debt-gate, throwing-stub-callers-gate, obsolescence-audit-gate

Context

Closes #2467.

🤖 Generated with Claude Code

… never sent (#2336 Area 7)

Follow-up to #2336 (umbrella) / #2463 (Areas 1+2+4). Completes Area 7 for
the Web UI surface only. Native apps (Android / iOS / macOS) deferred —
state-drivers there require release coordination; classification report
in PR description will feed that work.

## Classification

Web UI `thinkingLevel` was dead display plumbing: read from `chat.history`
into `state.chatThinkingLevel`, passed through `ChatProps.thinkingLevel`
to `renderChat`, but the view body never read the prop. No UI code
mutates or sends `thinkingLevel` — `patchSession` in `controllers/sessions.ts`
only handles `label` / `verboseLevel`.

## Changes

- `ui/src/ui/types.ts` — drop phantom `thinkingLevel?` from `GatewaySessionRow`
  and `SessionsPatchResult.entry`.
- `ui/src/ui/controllers/chat.ts` — drop `chatThinkingLevel` from `ChatState`,
  narrow `chat.history` response type, drop the state assignment.
- `ui/src/ui/app-view-state.ts`, `ui/src/ui/app.ts`, `ui/src/ui/app-render.ts` —
  drop `chatThinkingLevel` state plumbing.
- `ui/src/ui/views/chat.ts` — drop unused `thinkingLevel` prop from
  `ChatProps`. `renderChat` reads `activeSession?.reasoningLevel` for
  its single reasoning branch — not `thinkingLevel`.
- Tests: drop fixture/assertion lines that were exercising the removed
  display plumbing.

## Backward compat

Backend still sends `thinkingLevel` in `chat.history` response (until
#2464 removes `SessionEntry.thinkingLevel`). UI ignoring unknown response
fields is safe — correct ordering: reader removed first (this PR),
backend schema removal next (#2464).

## What was NOT touched — and why

- `ui/src/ui/format.test.ts` — tests `stripThinkingTags` (XML `<think>`
  tag stripping from CLI assistant output). Unrelated to `thinkingLevel`
  state field. Keep.
- `apps/shared/RemoteClawKit/Tests/OpenClawKitTests/AssistantTextParserTests.swift` —
  same pattern: `<think>` XML parsing. Keep.
- All native-app files (Android / iOS / macOS) — state-drivers that send
  `thinkingLevel` via `sessions.patch` and `chat.send(thinking:)`.
  Deferred per issue instruction; full classification in PR description.

## Verification

- `grep thinkingLevel|chatThinkingLevel|thinkLevel` in `ui/` → 0 matches.
- `pnpm check` → exit 0 (format + tsgo + lint + lint:tmp:no-random-messaging
  + lint:no-remoteclaw-ai).
- `pnpm test src/ui/controllers/chat.test.ts src/ui/views/chat.test.ts` →
  35/35 passed. Other UI test failures on this branch match `origin/main`
  baseline (unrelated to `thinkingLevel`).

Closes #2467. Unblocks #2464.

Refs: #2336, #2463, #2464

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@alexey-pelykh alexey-pelykh enabled auto-merge (squash) April 22, 2026 14:53
@alexey-pelykh alexey-pelykh merged commit 0236c10 into main Apr 22, 2026
15 checks passed
@alexey-pelykh alexey-pelykh deleted the gut/audit-display-thinking-level-2467 branch April 22, 2026 14:53
alexey-pelykh added a commit that referenced this pull request Apr 22, 2026
…— Area 3 of #2336 (#2464) (#2476)

Completes Area 3 of the vestigial thinking-level sweep. Removes the
SessionEntry.thinkingLevel field, its gateway protocol schema entry, the
`agents.defaults.thinkingDefault` config entry, and every consumer across
gateway, auto-reply, agents, status/TUI, ACP translator, HTML export,
extensions, and tests. RemoteClaw does not control reasoning depth — CLI
runtimes (Claude, Gemini, Codex, OpenCode) own it.

Reader-before-writer ordering satisfied:
- #2471 (PR #2467) removed the Web UI reader first — safe to stop sending.
- Native apps still reference thinkingLevel as display-only; they now see
  the field absent and degrade gracefully per the umbrella's audit.

ACP bridge surgery:
- thought_level mode presentation removed (modes = empty).
- setSessionMode is a silent no-op.
- thought_level config option removed from setSessionConfigOption.
- chat.send _meta fallback simplified to single "thinking" key.

Test surface updated in 13 test files. Where tests used thinkingLevel as a
generic test field for store-update behavior, swapped to verboseLevel
(still schema-valid). Where tests specifically exercised the gutted feature,
rewrote (translator.set-session-mode.test.ts) or removed the stale cases.

Schema regenerated via scripts/generate-base-config-schema.ts.
Docs config baseline regenerated. Docs updated to drop stale references.

Fork-boundary-mock baseline 133→132 (decrease locked in).

AC verification:
- `git grep "thinkingLevel" src/` → 2 hits, both in migration comments
- `pnpm check` → PASS
- All fork-integrity gates → PASS

Closes #2464.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
alexey-pelykh added a commit that referenced this pull request Apr 22, 2026
CLI runtimes own reasoning depth — the thinkingLevel input pipeline
has no runtime effect. Remove the remaining surface after #2463-#2471
eliminated most of it.

Removals:
- Delete orphan src/auto-reply/thinking.shared.ts (no importers)
- Prune dead helpers in thinking.ts: ThinkingCatalogEntry,
  isBinaryThinkingProvider, listThinkingLevels, shadow
  normalizeProviderId
- Drop subagents.thinking from agent-defaults types/schema and
  AgentEntry.subagents zod schema
- Remove --thinking flag from cron add/edit + tests; strip thinking
  from CronPayload, normalize, store-migration, and cron jobs
  mergePayload/buildPayloadFromPatch
- Remove thinking from gateway agent.send params, HookAgentPayload,
  HookAction, HookMappingResolved, server-http, server/hooks,
  server-node-events agent.request deep link
- Remove thinking from AgentCommandOpts + thinkingOnce,
  agent-via-gateway, subagent-spawn _thinkingOverrideRaw /
  thinkingOverride, sessions_spawn tool schema
- Remove thinking from protocol schemas (agent.ts, cron.ts,
  logs-chat.ts, sessions.ts) and ACP translator chat.send path
- Remove hooks.mappings[].thinking / hooks.gmail.thinking from zod
  schema, types, help, labels, quality test; regenerate
  schema.base.generated.ts
- Remove dead --thinking option + help-text example from agent CLI
  register; remove [--thinking] from /subagents spawn usage line;
  remove "thinking" from cron-tool agentTurn payload doc + JOB_KEYS
- Remove dead mocks (normalizeThinkLevel, supportsXHighThinking) and
  dead resolvedThinkLevel param in buildStatusReply
- Sweep docs: 9 files no longer teach --thinking / thinkingDefault

Added:
- LEGACY_CONFIG_RULES entries for agents.defaults.thinkingDefault and
  agents.defaults.subagents.thinking
- strip-thinking-level-fields LEGACY_CONFIG_MIGRATIONS entry that
  strips thinkingDefault, agents.defaults.subagents.thinking,
  agents.list[].subagents.thinking, hooks.mappings[].thinking, and
  hooks.gmail.thinking so existing configs still load cleanly
- 3 new tests in config-misc.test.ts covering the new migration

Kept (intentional):
- type === "thinking" / thinking_delta output-event rendering in
  middleware/runtimes, transcript truncation, ACP output blocks,
  TUI formatters, HTML export template
- Telegram/Discord "thinking" lifecycle status emoji (different
  concept from thinking level)
- reasoningLevel everywhere (different concept — channel-bound
  display behavior)

remoteclaw cron add --thinking high now errors with
"unknown option '--thinking'".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
alexey-pelykh added a commit that referenced this pull request Apr 22, 2026
…) (#2486)

CLI runtimes own reasoning depth — the thinkingLevel input pipeline
has no runtime effect. Remove the remaining surface after #2463-#2471
eliminated most of it.

Removals:
- Delete orphan src/auto-reply/thinking.shared.ts (no importers)
- Prune dead helpers in thinking.ts: ThinkingCatalogEntry,
  isBinaryThinkingProvider, listThinkingLevels, shadow
  normalizeProviderId
- Drop subagents.thinking from agent-defaults types/schema and
  AgentEntry.subagents zod schema
- Remove --thinking flag from cron add/edit + tests; strip thinking
  from CronPayload, normalize, store-migration, and cron jobs
  mergePayload/buildPayloadFromPatch
- Remove thinking from gateway agent.send params, HookAgentPayload,
  HookAction, HookMappingResolved, server-http, server/hooks,
  server-node-events agent.request deep link
- Remove thinking from AgentCommandOpts + thinkingOnce,
  agent-via-gateway, subagent-spawn _thinkingOverrideRaw /
  thinkingOverride, sessions_spawn tool schema
- Remove thinking from protocol schemas (agent.ts, cron.ts,
  logs-chat.ts, sessions.ts) and ACP translator chat.send path
- Remove hooks.mappings[].thinking / hooks.gmail.thinking from zod
  schema, types, help, labels, quality test; regenerate
  schema.base.generated.ts
- Remove dead --thinking option + help-text example from agent CLI
  register; remove [--thinking] from /subagents spawn usage line;
  remove "thinking" from cron-tool agentTurn payload doc + JOB_KEYS
- Remove dead mocks (normalizeThinkLevel, supportsXHighThinking) and
  dead resolvedThinkLevel param in buildStatusReply
- Sweep docs: 9 files no longer teach --thinking / thinkingDefault

Added:
- LEGACY_CONFIG_RULES entries for agents.defaults.thinkingDefault and
  agents.defaults.subagents.thinking
- strip-thinking-level-fields LEGACY_CONFIG_MIGRATIONS entry that
  strips thinkingDefault, agents.defaults.subagents.thinking,
  agents.list[].subagents.thinking, hooks.mappings[].thinking, and
  hooks.gmail.thinking so existing configs still load cleanly
- 3 new tests in config-misc.test.ts covering the new migration

Kept (intentional):
- type === "thinking" / thinking_delta output-event rendering in
  middleware/runtimes, transcript truncation, ACP output blocks,
  TUI formatters, HTML export template
- Telegram/Discord "thinking" lifecycle status emoji (different
  concept from thinking level)
- reasoningLevel everywhere (different concept — channel-bound
  display behavior)

remoteclaw cron add --thinking high now errors with
"unknown option '--thinking'".

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

audit(apps+ui): thinkingLevel display-layer classification (#2336 Area 7)

1 participant