- hasCompletedToolPhase now checks that the last assistant message in the
segment has no tool_use blocks, preventing false positives during
intermediate tool rounds that would suppress the trailing thinking indicator
- Filter reply text from cached graph steps when a completed run falls
back to the step cache, preventing the final response from appearing
inside the graph when expanding after completion
- Remove debug logging
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Gateway history contains `role: 'user'` messages that are actually
tool-result wrappers (Anthropic API format). These were incorrectly
treated as run boundaries in nextUserMessageIndexes, causing:
- isLatestOpenRun=false during tool execution → graph collapses
- Run split into multiple segments → incorrect step attribution
Add isRealUserMessage() that detects tool-result wrappers by checking
if all content blocks are type 'tool_result', and use it in both
nextUserMessageIndexes computation and userRunCards filtering.
Also remove debug logging from previous iterations.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Prevent execution graph from auto-collapsing while reply is still
streaming by excluding from autoCollapsedRunKeys and keeping
expanded=true via controlled prop
- Strip thinking blocks from the streaming ChatMessage when the reply
renders as a separate bubble, so thinking content doesn't duplicate
alongside the response text
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Move ChatToolbar (session selector, refresh, thinking toggle) from
the Chat page body into the Header component, so controls appear
at the same level as the "Chat" title
- Add New Session button (+) to create a fresh conversation
- Add newSession action to chat store
- Header conditionally renders ChatToolbar only on /chat route
- Chat page fills full content area without duplicate toolbar
Replace the iframe-based Control UI embed with a native React
implementation that communicates directly with the Gateway via
gateway:rpc IPC calls and chat event streaming.
New components:
- ChatToolbar: session selector dropdown, refresh button, thinking toggle
- ChatMessage: message bubbles with markdown (react-markdown + GFM),
collapsible thinking blocks, tool use cards, image attachments
- ChatInput: textarea with Enter to send, Shift+Enter for new line
- message-utils: extractText/extractThinking/extractImages/extractToolUse
ported from OpenClaw's message-extract.ts
Rewritten chat store with:
- Session management (sessions.list, switchSession)
- Proper chat.history loading with raw message preservation
- chat.send with idempotencyKey and run tracking
- Streaming via handleChatEvent (delta/final/error/aborted)
- Thinking toggle (show/hide reasoning blocks)
The <webview> tag had issues with event listener attachment and React
ref handling, causing the loading overlay to stay forever (white screen).
Switched to a standard <iframe> which is simpler and works reliably:
- Uses iframe onLoad/onError instead of webview dom-ready events
- Added 5s fallback timeout to dismiss loading overlay
- The X-Frame-Options/CSP header overrides from session.webRequest
allow the iframe to load the Control UI
Part 1: API Key Integration
- Create electron/utils/openclaw-auth.ts to write keys to
~/.openclaw/agents/main/agent/auth-profiles.json
- Update provider:save and provider:setApiKey IPC handlers to
persist keys to OpenClaw auth-profiles alongside ClawX storage
- Save API key to OpenClaw on successful validation in Setup wizard
- Pass provider API keys as environment variables when starting
the Gateway process (ANTHROPIC_API_KEY, OPENROUTER_API_KEY, etc.)
Part 2: Embed OpenClaw Control UI for Chat
- Replace custom Chat UI with <webview> embedding the Gateway's
built-in Control UI at http://127.0.0.1:{port}/?token={token}
- Add gateway:getControlUiUrl IPC handler to provide tokenized URL
- Enable webviewTag in Electron BrowserWindow preferences
- Override X-Frame-Options/CSP headers to allow webview embedding
- Suppress noisy control-ui token_mismatch stderr messages
- Add loading/error states for the embedded webview
This fixes the "No API key found for provider" error and replaces
the buggy custom chat implementation with OpenClaw's battle-tested
Control UI.
- Add markdown rendering with react-markdown and remark-gfm
- Create ChatMessage component with code copy functionality
- Add typing indicator animation during AI response
- Create welcome screen for new users
- Add Textarea component for multi-line input
- Improve message styling with avatars and hover actions
- Add Gateway connection status awareness
- Add prose styling for markdown content
Set up the complete project foundation for ClawX, a graphical AI assistant:
- Electron main process with IPC handlers, menu, tray, and gateway management
- React renderer with routing, layout components, and page scaffolding
- Zustand state management for gateway, settings, channels, skills, chat, and cron
- shadcn/ui components with Tailwind CSS and CSS variable theming
- Build tooling with Vite, electron-builder, and TypeScript configuration
- Testing setup with Vitest and Playwright
- Development configurations (ESLint, Prettier, gitignore, env example)