Skip to content

feat: Sidebar Bot Integration with WebSocket and SQLite Sync#37

Merged
idoubi merged 47 commits intoworkany-ai:devfrom
fengcunhan:feat/sidebar-bot-integration
Mar 1, 2026
Merged

feat: Sidebar Bot Integration with WebSocket and SQLite Sync#37
idoubi merged 47 commits intoworkany-ai:devfrom
fengcunhan:feat/sidebar-bot-integration

Conversation

@fengcunhan
Copy link

Summary

This PR integrates the Bot chat feature into the sidebar and implements a robust WebSocket-based real-time communication system with SQLite synchronization for offline support.

Key Changes

Sidebar & Navigation

  • Merge local tasks and bot chats into a unified sidebar list with tab navigation
  • Add pagination for history lists (10 items per page with "More..." button)
  • Persist pagination state across navigation

Bot Chat System

  • Implement WebSocket real-time streaming with moltbot protocol
  • Add SQLite sync for bot sessions and messages (offline support)
  • Create BotChatProvider for centralized state management
  • Extract shared BotMessageList and MarkdownContent components

Agent Improvements

  • Implement two-step SSE pattern (POST returns jobId, GET SSE stream) to fix WKWebView timeout
  • Add language-aware responses - agent responds in user's language
  • Add API format selector for Anthropic/OpenAI compatibility
  • Support both OpenClaw Bot and Kimi CLI agent providers

UI Enhancements

  • Add sample prompts with refresh functionality on home page
  • Add provider selector dropdown for task execution
  • Make working directory path editable in settings
  • Filter intermediate files (py, js, ts, etc.) from artifacts panel

Test Plan

  • Verify sidebar shows both local tasks and bot chats correctly
  • Test pagination works for long history lists
  • Verify WebSocket connection and real-time message streaming
  • Test SQLite sync persists bot sessions across app restarts
  • Verify sample prompts display and refresh correctly
  • Test provider selector switches between Claude Code and OpenClaw
  • Verify language-aware responses work for English and Chinese

🤖 Generated with Claude Code

cunhanfeng and others added 30 commits February 11, 2026 00:22
Implement OpenClaw bot feature with real-time WebSocket communication:

- Add OpenClaw agent extension with WebSocket gateway client
- Add BotChat page for interactive bot conversations
- Add ThinkingBlock and ToolCallBlock components for message rendering
- Add OpenClaw settings panel with runtime detection
- Add bot-storage utilities for localStorage management
- Add useBotChats hook for session state management
- Add i18n translations (zh/en) for new features
- Update router and navigation to include BotChat page

The implementation includes:
- RPC request/response pattern with waiter机制
- Message streaming and transformation
- Runtime agent detection and validation
- Session persistence with localStorage
- Configurable polling and timeout handling

This provides users with an alternative AI bot interface that
supports real-time conversations and tool execution visualization.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move bot chat session fetching logic from useBotChats hook into
a dedicated BotChatProvider component for better separation of
concerns and reusability.
…ntent components

Extract duplicate bot message rendering logic into shared components:
- BotMessageList: consolidates bot chat message rendering
- MarkdownContent: reusable markdown rendering with ReactMarkdown

This removes ~500 lines of duplicate code across Home.tsx, BotChat.tsx,
and TaskDetail.tsx while maintaining consistent styling and behavior.
- Add auto-scroll to bottom when new messages arrive
- Poll chat history every 1s during message sending
- Cleanup polling interval on unmount
- Use functional setState for error handling
Add isPureUserMessage helper to filter out system-injected context:
- Detects context markers like "Conversation info (untrusted metadata)"
- Filters them out when extracting clean content from history

This prevents messages like:
```
"Conversation info (untrusted metadata):\n```json\n{\n  \"conversation_label\": \"workany\"\n}\n```\n\nhello"
```

from being saved and displayed to users.

Fixes lint issues with array formatting.
…ssages

Improve extractRealUserContent to correctly handle complex message patterns:
- Remove untrusted block markers (xxx (untrusted xxx): pattern)
- Remove JSON code blocks (```json ... ```)
- Remove metadata titles like "Conversation info (untrusted metadata):"
- Clean up residual JSON remnants

This preserves actual user messages like "hello" while removing
system-injected context blocks that were causing display issues.

Fix regex escaping issues (remove unnecessary backslash escapes).
Add missing Bot Chats props to LeftSidebar in Library.tsx:
- Import and use useBotChats hook
- Pass botChats and refreshSessions to LeftSidebar

This fixes the bug where clicking "更多..." on the home page
would navigate to /library but show empty "所有聊天" section.
Remove loadChatHistory from useEffect dependency array to prevent
unnecessary API calls on sessionKey changes.

The polling mechanism in handleSubmit already handles fetching
new messages, so we should only:
1. Load from localStorage on initial mount (with location.state dep)
2. Poll for updates via handleSubmit (existing mechanism)

This fixes the UI flashing issue caused by repeated API requests.
Add Local/Bot task mode toggle buttons to Home page:
- Local Task button with "local task" text/icon
- Bot Task button with "bot task" text/icon
- Update ChatInput component with bottomContent prop

This provides quick access to switch between local AI agent
mode and OpenClaw bot mode directly from the chat interface.
… protocol

Add WebSocket-based real-time event streaming for Bot chat:
- Create openclaw-ws.ts server for event proxying
- Add useOpenClawWebSocket hook for frontend integration
- Implement node.event subscription for session events (chat.subscribe)
- Handle delta/final/error/aborted chat states
- Support tool/lifecycle agent events streaming
- Fix stale closure issues causing repeated WebSocket reconnections
- Add safety timeout for loading state (60s)
- Add BotLoadingIndicator component for streaming UI

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update Home page Bot chat to handle async responses:
- Add pollForAssistantMessage function for async response handling
- Use convertOpenClawMessage utility for message conversion
- Handle 'accepted' status from async chat endpoint
- Add error alert for missing OpenClaw configuration

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add isMountedRef and isConnectingRef to handle StrictMode double-invocation
- Check mount status before disconnecting in cleanup effect
- Fix moltbot protocol: use payloadJSON (string) instead of payload (object)
- Wait for connect handshake response before resolving connection
- Add extensive logging for debugging WebSocket event flow

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add "更多..." button to bot chats section in left sidebar
- When clicked, main content is replaced with full chat list panel
- Panel shows all bot chat sessions with title and last message
- Clicking a chat item selects it and closes the panel
- Works in both BotChat page and Home page views

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add "Get OpenClaw Bot" section with link to workany.ai/bot
- Remove enable toggle - auto-enable when config is set
- Move connection status below auth token for better UX flow
- Auto-enable bot when gatewayUrl or authToken is configured

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Change "All tasks" to "Local tasks" to distinguish from Bot tasks
- Change "All chats" to "Bot chats" for consistency
- Update both English and Chinese translations

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix duplicate messages appearing in Bot chat UI caused by multiple issues:

- Session key format mismatch between frontend (bot_xxx) and MoltBot
  (agent:main:bot_xxx) causing events not to be forwarded
- Streaming message (chatStream) not cleared after lifecycle.end,
  resulting in both streaming and final message displayed
- Missing deduplication for events received via both broadcast()
  and nodeSendToSession()

Changes:
- Add normalizeSessionKey() to convert between short and canonical formats
- Add sessionKeyMatches() for flexible key matching
- Add event deduplication using (runId, seq) on backend
- Add chatStream cleanup on lifecycle.end in WebSocket hook
- Remove unnecessary pendingUserMessageRef logic causing duplicates
- Add protocol documentation for reference

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix missing thinking and toolCalls content in real-time Bot chat:

- Enhanced addAssistantMessage() to accept full message data including
  rawContent (thinking, toolCall, toolResult)
- Pass complete message data from chat.final events
- Fetch history after agent.lifecycle.end fallback to get complete
  messages with thinking and toolCalls when MoltBot only sends agent
  events (no chat events)

This ensures thinking blocks and tool calls are visible in real-time,
not just when viewing history.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove .claude directory from version control.
Contains local Claude Code settings that should not be shared.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add horizontal tab navigation in left sidebar with Local/Bot tabs
- Chinese labels: 本地 (Local) / WorkAny Bot (Bot)
- Remove redundant task type selector from input area
- Lift SidebarProvider to main.tsx for state persistence across pages
- Auto-switch tab based on current page (Bot tab for /bot, Local for others)
- Update right sidebar to show different content based on active tab

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Change "更多..." button to load more items directly in sidebar
- Remove navigation to library page for loading more tasks
- Remove onShowAllBotChats prop (no longer needed)
- Increase initial visible count from 5 to 10 items
- Load 5 more items each time "更多..." is clicked

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add generateTitleFromContent utility for creating chat titles
- Use message content as fallback when session has no label
- Title priority: API label > generated from content > friendlyId > "新对话"
- Increase pagination batch size from 5 to 10 items

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add TaskType field to distinguish local tasks from bot chats
- Add new fields to Task: type, label, last_message, message_count, remote_updated_at
- Add new fields to Message: message_key (for deduplication), role, timestamp, raw_content, details, is_error
- Upgrade IndexedDB to v3 with new indexes
- Add helper functions: getMessageByKey, getTasksByType, generateMessageKey, upsertBotMessage, syncBotMessages
- Update bot-chat-provider to sync cloud sessions to local database
- Support offline fallback to local data when cloud is unavailable

This enables merging local tasks and bot chats into a unified display.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Analyze agent system architecture
- Document message processing flow
- List key code locations
- Propose local task integration approaches

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove tab navigation in favor of single unified history list
- Add Zap icon (amber) for local tasks, Bot icon (blue) for bot chats
- Merge and sort all items by updated_at timestamp
- Clean up unused variables and imports
- Fix formatting in BotChat.tsx

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Filter local tasks to exclude bot type (avoid duplicate display)
- Remove unnecessary message sync to local database
- Bot sessions are fetched directly from cloud, history loaded on demand
- Simplified bot-chat-provider.tsx by removing database sync logic

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Move visibleTaskCount state to SidebarContext
- Prevents pagination reset when clicking on items
- Add loadMoreTasks callback for loading more items

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add TaskProvider type (claude-code, codex, openclaw)
- Add provider selector dropdown in ChatInput component
- Show selector only on home page when not in bot mode
- OpenClaw option only appears when configured
- Pass selected provider to task execution

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Provider selection is now available in the task input area,
making the settings page selector redundant.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Always show OpenClaw option in provider dropdown
- If not configured, clicking opens settings modal
- Show settings icon indicator when OpenClaw needs configuration
- Auto-refresh config status when settings modal closes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Design for syncing bot sessions and messages to local SQLite database
with background sync support.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
cunhanfeng and others added 17 commits February 19, 2026 23:58
Detailed 8-task implementation plan with step-by-step instructions
for syncing bot sessions and messages to local SQLite database.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add bot-sync.ts with functions for syncing bot sessions/messages
- Fetch sessions from cloud API (/openclaw/sessions)
- Fetch messages from cloud API (/openclaw/history)
- Convert cloud data to local SQLite format
- Export Database type from database.ts for use in sync utilities
- Add normalizeRole helper for type-safe role validation
- Add safeParseJson for graceful JSON parse error handling
- Add fetchWithTimeout with AbortController for network timeouts
- Include HTTP status code in error messages for better debugging

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add isMounted cleanup pattern in useEffect to prevent memory leaks
  from state updates after component unmount
- Add console.error logging in fetchBotChatsFromCloud catch block
  to improve debugging visibility

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add loadLocalMessagesFromContext helper to get messages from context
- Modify loadChatHistory to check local data first before fetching from cloud
- Trigger background sync via syncMessages() when local data is available
- Add effect to update messages when sync completes
- Add visual sync indicator (loading spinner) when syncing from cloud
- Import Loader2 icon from lucide-react for sync indicator

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add proper typing for OpenClawSession.lastMessage instead of 'unknown'
to fix TS2345 error when passing to convertOpenClawMessage.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Refactor agent execution to use POST (create job) + GET (stream SSE)
pattern. This prevents WKWebView from disconnecting idle SSE connections
during long Claude thinking periods.

Changes:
- Add job store with background generator execution and message buffering
- POST /agent returns {jobId, sessionId} immediately
- GET /agent/stream/:jobId provides SSE with 15s heartbeats
- Update useAgent.ts to use two-step fetch pattern
- Add OpenClaw config validation in BotChat before API calls
- Convert BotChat handlers to useCallback for stable references
- Improve bot-sync to include gatewayUrl/authToken in requests
- Add warning logs for unknown message roles in bot-sync
- Deprecate syncBotMessages (renamed to syncBotTaskMessages)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ility

Allow users to choose between Anthropic-compatible (/v1/messages) and
OpenAI-compatible (/v1/chat/completions) API formats when adding or
editing providers.

Changes:
- Add apiFormat field to AIProvider interface and settings state
- Add buildOpenAIApiUrl for OpenAI-compatible endpoint construction
- Update detect endpoint to handle both API formats
- Add radio button selector in ModelSettings UI for both new and existing providers
- Add locale strings for apiFormat labels and hints in en/zh

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add LANGUAGE RULE to ensure agent responds in user's language
- Fix abort controller to check both session and options signals
- Filter intermediate files (py, js, ts, etc.) from artifacts panel
- Make working directory path editable in WorkplaceSettings

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add 9 sample task prompts with batch refresh functionality
- Support controlled mode in ChatInput for external value injection
- Update input placeholder to "Describe a task..."
- Add Chinese translations for sample prompts
- Ignore features/ directory in .gitignore

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Update /plan and /execute endpoints to return jobId immediately
- Client now GETs SSE stream via /agent/stream/:jobId
- Sample prompts now use { title, prompt } object format
- Remove fixed height from prompt cards for better text fit
- Add Chinese translations for prompt titles

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ation

- Add Kimi CLI agent provider from upstream
- Keep OpenClaw Bot agent provider
- Merge both openclaw and kimi in AgentProvider type
- Update Chinese translations for both runtimes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@idoubi idoubi merged commit c68ec65 into workany-ai:dev Mar 1, 2026
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.

2 participants