Repository navigation
v2.2.0 - feat:thinking/reasoning stream for chat + agent #60
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
cf996c2
chore: add @eslint/core as explicit devDependency
ddutchie fd01f59
fix: GitHub-style raw HTML in markdown + chat session management
ddutchie 6491f6b
feat: thinking/reasoning stream + v2.2.0 changelog
ddutchie d1bb72b
fix: PR review fixes for reasoning stream
ddutchie d0ffa68
fix: ThinkingPanel re-open effect only fires on empty→non-empty trans…
ddutchie 3d17509
fix: replace exclusiveMinimum with minimum in search_notes_semantic s…
ddutchie b406215
feat: round-trip thought_signature on tool calls for Gemini 3.x
ddutchie 8f2b529
fix: PR review — reasoning persistence, subagent thoughts, workspace …
ddutchie File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| ## What's new | ||
|
|
||
| ### Features | ||
|
|
||
| - **Thinking / reasoning stream**: AI chat and the Cairn Agent now stream model reasoning text (Claude `thinking_delta`, OpenAI `delta.reasoning`) as a separate channel alongside content — never merged into note content or tool-call JSON. A collapsible **Thinking** panel renders above the assistant's reply, expanded by default while reasoning unfolds, auto-collapsing the instant the first content token arrives, and re-expandable via chevron at any time. Reasoning text is persisted to the `chat_messages` and `pi_agent_messages` tables so past messages retain their thinking panel across app restarts. For models that don't expose reasoning (e.g. standard GPT-4o), the panel simply never appears — zero overhead. | ||
| - **Backend**: `runToolLoop` in `electron/ipc/chat.ts` and `runAgentLoop` in `electron/lib/pi-agent-loop.ts` both parse `delta.reasoning` from SSE chunks, accumulate it through the tool-call loop, and emit new `chat:thought` / `pi-agent:thought` IPC channels mirroring the existing token channels. Non-streaming localllm path also reads `message.reasoning` from the completion response. | ||
| - **Usage**: `completion_tokens_details.reasoning_tokens` is now parsed from the OpenAI usage object and threaded through `onUsage` callbacks on both paths. The ContextRing popover (top-right of chat) now shows an **Output** section with **Answer** / **Thinking** / **Total** token breakdowns when a turn completes with reasoning token data. | ||
| - **IPC**: New preload listeners `window.electron.chat.onThought` and `window.electron.piAgent.onThought` added; `chat:usage` / `pi-agent:usage` payloads extended with `reasoningTokens`; `chat:done` payload now carries `reasoning` text for persistence. | ||
| - **Store**: `ChatMessage` and `PiAgentMessage` types gain `reasoning?: string`; `ChatThread.lastUsage` and `TerminalSession.lastUsage` gain `reasoningTokens?: number`. New `appendPiThought` Zustand action mirrors `appendPiToken` for live agent reasoning accumulation. | ||
| - **DB migration v20**: `ALTER TABLE chat_messages ADD COLUMN reasoning TEXT` and the same for `pi_agent_messages`. Idempotent — checks `PRAGMA table_info` before adding. | ||
| - **UI components**: New shared `ThinkingPanel.tsx` (`src/components/chat/chat-panel/`) handles both streaming (auto-collapse on first content token, re-expand on new reasoning, honour user override) and persisted (collapsed by default with chevron toggle) states. Rendered in `ToolCallIndicator` (live chat), `ChatMessageBubble` (persisted chat), and `AgentMessageBubble` (both live and persisted agent messages + subagent rows). | ||
|
|
||
| - **GitHub-style raw HTML in markdown**: All three markdown pipelines (`NoteMarkdownPreview`, `note-editor` read mode, `MarkdownContent` for chat) now install `rehype-raw` as the first rehype plugin, preserving raw HTML like `<p align="center">`, `<img>`, `<details>`/`<summary>`, and `<br>` instead of stripping them. Matches GitHub's rendering behaviour for README files pasted into notes or chat. | ||
|
|
||
| ### Fixes | ||
|
|
||
| - **New chat thread not selected**: `SessionPane.handleNewChatThread` created a new thread but didn't call `setActiveChatThreadId` with the new thread's ID, so the chat panel kept showing the old session instead of switching to the freshly-created one. Now immediately switches. | ||
|
|
||
| - **Chat thread not switching on project change**: The `ChatPanel` init effect short-circuited whenever `activeChatThreadId` was non-null, so switching projects kept displaying the old project's chat thread. The effect now detects when `activeProjectId` changes and switches to a thread scoped to the new project via `getOrCreateThread`. | ||
|
|
||
| - **ESLint clean-install failure**: `eslint.config.mjs` imports from `eslint/config` (`@eslint/core`) which was only available transitively through `eslint@9` — clean installs (e.g. CI, PR review bots) couldn't resolve it. `@eslint/core` is now an explicit devDependency. | ||
|
|
||
| ### Changes | ||
|
|
||
| - **Reasoning is intentionally stripped from compaction**: The chat compaction flow (`compactChatThread` in `src/store/slices/chat.ts`) sends only `{ role, content }` when summarising — reasoning text is never embedded into summary content, per the guidance that reasoning shouldn't leak into user-visible notes as text. Token counts (`reasoningTokens`) remain tracked for metrics/billing. | ||
|
|
||
| - **MCP / LLM history excludes reasoning**: `pi_agent_llm_history` (the raw model replay buffer for agent sessions) stores only role + content, so reasoning blocks don't interfere with downstream model turns. | ||
|
|
||
| - **`max_tokens` unchanged**: No request-side changes to `max_tokens` / `max_completion_tokens` were made. Models that split reasoning from content (e.g. Gemini-3.5-flash) produce `finish_reason: "length"` if the limit is too low — the existing `max_tokens: 4096` in `runToolLoop` is sufficient for most turns. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.