Skip to content

feat: the thinking channel, stored, streamed and shown (reasoning support Parts A and C) - #423

Merged
igolubic merged 2 commits into
mainfrom
feature/reasoning-channel
Aug 4, 2026
Merged

feat: the thinking channel, stored, streamed and shown (reasoning support Parts A and C)#423
igolubic merged 2 commits into
mainfrom
feature/reasoning-channel

Conversation

@igolubic

@igolubic igolubic commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

What

The remaining two parts of the owner-approved reasoning design (Part B shipped in #405). Governing principle throughout: thinking is a CHANNEL, not content — displayed live and afterwards, never captured, cited, verified, or evaluated.

Part A — the channel

ModelGateway.completeStream now yields channel-tagged deltas ({channel: 'thinking' | 'text', text}). The OpenAI-compatible adapter surfaces reasoning_content / reasoning / thinking deltas on the thinking channel (and a thinking delta arms the Part B headroom, so live chat traffic teaches the adapter too); Mistral yields text only; Anthropic maps thinking_delta although Cogeto never requests extended thinking. The four decorators follow the two approved rulings:

  • The budget charges BOTH channels — thinking costs real tokens, and on the reference reasoning model it is most of them; the old meter under-reported spend several times over.
  • Redaction strips thinking, fail closed — the vision posture. Re-identification maps pseudonyms back into text the user reads; deliberation interleaves pseudonym fragments the flush logic cannot bound, so under redaction the thinking channel does not exist.
  • The egress audit counts both channels' characters (structural only); the router dispatches untouched. The eval-cache wrapper records the text channel only: thinking is never evaluated, so a fixture cannot freeze it.

A non-reasoning model yields the same bytes it always did, one field deeper, proven by test.

Part C — stored, streamed, shown

  • Migration 0044: chat_message.thinking (nullable text, content-bearing). The answer-redaction cascade nulls it in the same UPDATE that overwrites a citing answer, because reasoning ABOUT an erased memory must not survive the citation that grounded it; row deletion takes it implicitly, receipts unchanged.
  • A thinking SSE event interleaves with token events; the chat UI renders a collapsed Thinking disclosure above the answer — streaming live, expandable, reopenable on stored answers, and rendering NOTHING when there is no thinking. New chat:reasoning.* keys in all four locales.
  • The fingerprint marker (honesty rule 3), at emission time: configurationForEmission appends --reasoning to the trust-artifact id from the same probe the capability panel uses, in both harnesses identically so the partial-merge guard holds. Appended at emission and nowhere else, because whether a binding reasons is a runtime fact the static resolver cannot know. A Mistral-routed run probes off and emits the unchanged id — every existing artifact, gate and cached fixture is untouched, and no fixture refresh was needed (the eval-gate on this PR replays the committed cache as-is).

Validation

Per the owner's instruction, no eval runs: unit and integration suites (1,104 tests green, including the new channel, strip, charge, persistence, cascade and marker tests) plus a live boot — migration 0044 applied, app and worker healthy, reasoning ON | vision ON, chat streaming verified end-to-end through the SSE path in the integration suite.

Docs: docs/features/reasoning.md (the whole design in one place), capabilities.md and CLAUDE.md updated; the resolver comment now points at the emission-time marker.

Closes #420
Closes #421
Closes #422

@igolubic igolubic added this to Cogeto Aug 4, 2026
@igolubic igolubic moved this to In Progress in Cogeto Aug 4, 2026
@igolubic
igolubic enabled auto-merge (squash) August 4, 2026 14:39
@igolubic
igolubic merged commit 410c548 into main Aug 4, 2026
8 checks passed
@igolubic
igolubic deleted the feature/reasoning-channel branch August 4, 2026 20:23
@igolubic igolubic moved this from In Progress to Done in Cogeto Aug 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

1 participant