feat(ai): integrate Block API in frontend (Issue #71)#80
Merged
Conversation
dde7e73 to
b2fe41b
Compare
* feat(chat-apps): add foundation for multi-platform chat apps integration Phase 1 of #53: Infrastructure setup for Telegram, WhatsApp, DingTalk - Add ChatChannel interface for platform abstraction - Add proto definitions for ChatAppService (API + Store) - Add database migrations for chat_app_credential table - Add channel_type column to conversation_context - Implement skeleton for Telegram, WhatsApp, DingTalk channels - Add media processing interface (Whisper OCR placeholder) - Add token encryption utilities for secure credential storage Created files: - docs/specs/chat-apps-integration.md (technical specification) - proto/api/v1/chat_app_service.proto - proto/store/chat_app_service.proto - plugin/chat_apps/ (channels, media, store) - store/migration/postgres/20260203_*.sql Refs #53 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(chat_apps): complete Telegram channel DownloadMedia + QA improvements - Implement Telegram media download with HTTP client - Add RWMutex to ChannelRouter for concurrent safety - Configure HTTP client timeout and connection pool - Add structured logging (log/slog) to store and channels - Enhance Telegram webhook verification (method, content-type) - Fix string concatenation in SendChunkedMessage (use strings.Builder) Refs #53 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(chat-apps): implement ChatAppService handlers and complete Telegram DownloadMedia - Complete DownloadMedia implementation with HTTP download - Add HTTP client to TelegramChannel struct - Fix file.Link() method call (requires bot token parameter) - Add proper error handling and MIME type detection - Remove google.api.http annotations (store layer doesn't need HTTP) - Add google.protobuf.Empty import - Implement all 7 ChatAppService RPC methods: - RegisterCredential: bind chat app account with encryption - ListCredentials: list user's chat app bindings - DeleteCredential: remove binding with ownership check - UpdateCredential: modify access token/webhook URL - HandleWebhook: process incoming webhook events - SendMessage: send messages to chat platforms - GetWebhookInfo: return webhook setup instructions - Add conversion functions between proto and internal types - Add ChannelRegistry interface for channel management - Integrate with Store.GetDriver().GetDB() for database access - Use os.Getenv() for environment variable access - Add UnimplementedChatAppServiceServer embedding - Register ChatAppService with gRPC-Gateway - Regenerate proto files with buf generate - Add chat_app_service.connect.go for Connect RPC Refs #53 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(chat-apps): implement webhook message processing - Add credential lookup by PlatformUserID to find DivineSense user - Add credential enabled check - Implement asynchronous message processing (non-blocking webhook response) - Add processChatAppMessage for AI routing (stub for future implementation) The webhook now: 1. Validates the incoming request 2. Parses the message using channel-specific parser 3. Looks up the user credential by platform user ID 4. Returns immediately with success (async processing) 5. Processes the message in background (stub for AI routing) Refs #53 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(chat-apps): complete DingTalk channel implementation - Add HTTP client for API calls - Add access token caching with thread-safe double-check locking - Token expires 5 minutes early to avoid edge cases - `sendText()`: Send text messages via webhook - `sendMedia()`: Send media messages (placeholder with text fallback) - `sendWebhook()`: HTTP POST to DingTalk webhook with error handling - `GetAccessToken()`: Fetch and cache access tokens (2hr expiry) - `DownloadMedia()`: Download media using downloadCode - Implements DingTalk signature validation (HMAC-SHA256) - Supports webhook-based outgoing messages - Uses context with timeout for all HTTP requests - Proper error handling with structured logging Refs #53 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(chat-apps): add frontend Chat Apps settings panel - Create ChatAppsSection component in `web/src/components/Settings/ChatAppsSection.tsx` - Add chat apps account management UI with: - List existing credentials with platform labels - Enable/disable toggle - Delete credential button - Webhook info display - Platform selection (Telegram, WhatsApp, DingTalk) - Platform user ID input with hints - Access token input (password type) - Webhook URL input (DingTalk only) - Platform-specific help text - Add "chat-apps" to BASIC_SECTIONS (available to all users) - Add MessageSquare icon for the section - Render ChatAppsSection in Setting.tsx - Add English translations in `en.json` - Add Chinese translations in `zh-Hans.json` - Includes all labels, hints, and error messages Refs #53 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(chat-apps): implement WhatsApp Baileys bridge service Create Node.js bridge service for WhatsApp integration using Baileys library. Features: - Express HTTP server with health check endpoint - WhatsApp Web API connection via Baileys - QR code pairing for WhatsApp authentication - Message forwarding from WhatsApp to DivineSense webhook - Send message endpoint for DivineSense to WhatsApp - Media download endpoint - Auto-reconnection on connection loss - Environment-based configuration Files added: - plugin/chat_apps/channels/whatsapp/bridge/package.json - plugin/chat_apps/channels/whatsapp/bridge/src/index.js - plugin/chat_apps/channels/whatsapp/bridge/README.md The bridge service runs as a standalone Node.js process and communicates with DivineSense via HTTP endpoints. This architecture is required because the Baileys library only works in a Node.js runtime. Refs #53 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * style(chat-apps): format DingTalk channel code * lint(chat-apps): fix golangci-lint issues - Use double %%w for error wrapping in DownloadMedia - Add rows.Err() check in ListCredentials Fixes: - errorlint: non-wrapping format verb for fmt.Errorf - rowserrcheck: rows.Err must be checked Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * lint(chat-apps): fix frontend lint and i18n issues - Fix Platform enum usage (TELEGRAM not PLATFORM_TELEGRAM) - Remove unused imports (Checkbox, AlertDialogAction, useToast) - Change AlertDialog to Dialog (standard component) - Add useEffect for proper lifecycle - Add inline error display instead of toast - Fix duplicate i18n keys in en.json and zh-Hans.json - Remove duplicate 'chat-apps' string key - Remove duplicate 'webhook-url' key - Remove duplicate 'storage'/'storage-section' keys - Format code with Biome Fixes: - TypeScript enum access errors - Biome import organization issues - Duplicate object keys in locale files Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs(chat-apps): add comprehensive user manual Complete zero-barrier entry guide for Chat Apps integration: - Feature introduction and platform comparison - Detailed Telegram, WhatsApp, DingTalk setup guides - Step-by-step instructions with examples - Troubleshooting section with common issues - Security best practices - Advanced configuration options File: docs/user-guides/CHAT_APPS.md Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(chat-apps): complete Telegram, DingTalk, and WhatsApp integration This commit implements multi-platform chat app integration, allowing users to interact with DivineSense AI agents through Telegram, DingTalk, and WhatsApp. Features: - Register/list/delete chat app credentials - Webhook endpoint for receiving messages (all 3 platforms) - AI integration using AUTO agent routing - Token encryption (AES-256-GCM) with fail-fast validation - Frontend settings panel with i18n support - WhatsApp via Baileys Node.js bridge service (complete implementation) - Metrics tracking for webhook events Code Quality Fixes: - Fixed double close channel panic (goroutine owns channel close) - Removed insecure plaintext fallback (fail-fast on missing encryption key) - Consolidated duplicate functions (~100 lines removed) - Fixed metrics tracking (moved after credential lookup) - Added typed context key to prevent collisions Documentation: - Added comprehensive user guide (docs/guides/CHAT_APPS.md) - Updated architecture docs with Chat Apps module - Added database schema documentation for chat_app_credential table - Added frontend component documentation for ChatAppsSection Refs #53 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * style(chat-apps): format code with go fmt Auto-formatted by pre-commit hook. Refs #53 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * lint(chat-apps): fix golangci-lint issues - Use fields in test to avoid unused warnings - Remove unnecessary int64 conversion (messagesProcessed is already int64) - Remove unused getAIResponse function and its imports (strings, sync) Refs #53 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs(chat-apps): 完善用户手册和开发者手册 用户手册更新 (docs/user-guides/CHAT_APPS.md): - 添加详细的平台配置步骤(Telegram/WhatsApp/钉钉) - 新增架构说明和 QR 码配对流程 - 完善 FAQ 和故障排查章节 - 添加调试信息获取指南 开发者指南更新 (docs/guides/CHAT_APPS.md): - 添加系统架构图和核心组件说明 - 完善数据模型和 API 端点文档 - 新增平台集成技术细节 - 添加安全机制、加密存储说明 - 完善开发调试和部署指南 - 新增扩展新平台的步骤指南 WhatsApp Bridge README 更新: - 添加架构图和功能特性表格 - 完善 API 端点文档和请求示例 - 新增 PM2/Systemd/Docker 部署指南 - 添加故障排查章节 - 完善安全建议 其他修复: - 修复 qrcode-terminal ES 模块导入问题 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(deploy): add WhatsApp Bridge deployment automation This commit adds comprehensive deployment automation for the WhatsApp Bridge service (Baileys), integrating it into the main installation workflow. - Standalone deployment management script for WhatsApp Bridge - Commands: install, start, stop, restart, status, logs, health, qr, backup, update, uninstall - Supports both PM2 and systemd process managers - Health check endpoint monitoring - QR code display for WhatsApp pairing - Docker Compose configuration including DivineSense, PostgreSQL, and Baileys Bridge - Health checks for all services - Proper networking and volume management - PM2 ecosystem configuration for process management - Automatic restart, logging, resource limits - Health check integration - systemd service file for production deployment - Security hardening (NoNewPrivileges, ProtectSystem) - Resource limits (512M memory, 50% CPU) - Environment configuration template - Documentation for all configuration options - Added INSTALL_WHATSAPP variable to interactive wizard - Added --whatsapp command-line flag - Integrated WhatsApp Bridge installation into both binary and docker modes - Added help text for WhatsApp Bridge option - Added WhatsApp Bridge management commands to user Makefile - Added sudoers entries for baileys-bridge.sh and baileys-bridge.service - Added bash aliases: ds-wa-status, ds-wa-qr, ds-wa-logs, ds-wa-install - Fixed systemd service user from 'divinesense' to 'divine' ```bash curl -fsSL https://raw.githubusercontent.com/hrygo/divinesense/main/deploy/install.sh | sudo bash -s -- --interactive curl -fsSL ... | sudo bash -s -- --whatsapp ``` ```bash make whatsapp-status # Check bridge status make whatsapp-qr # Display QR code for pairing make whatsapp-logs # View logs ds-wa-status # Shortcut alias ``` Resolves #53 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(deploy): security hardening and error handling improvements This commit addresses security and reliability issues identified in code review. - Added BRIDGE_API_KEY environment variable for protecting sensitive endpoints - /send and /download endpoints now support optional API key auth via X-Bridge-Api-Key header - When BRIDGE_API_KEY is set, requests must include valid API key - Added ALLOWED_ORIGINS environment variable - Default behavior unchanged (*), but production can now restrict origins - Documented in .env.example with examples - baileys-bridge.sh now checks health check return value - Installation shows warning if service fails to start - Provides troubleshooting hints on failure - Added explicit log message when copying bridge files - Sets correct ownership (divine:divine) after copy - Warns if source directory not found - Added BindsTo=divinesense.service to baileys-bridge.service - Ensures bridge restarts when DivineSense restarts - Prevents orphaned bridge service - Installation now distinguishes between success and failure - Shows manual installation command on failure - Webhook URL template warns against using localhost in production - Updated all configuration files (.env.example, ecosystem.config.cjs, baileys-bridge.service, with-whatsapp.yml) to include new security environment variables - Added .gitignore to exclude Baileys auth data directory Resolves code review findings Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(i18n): add missing English translations for SSO settings Add missing translation keys in en.json for SSO section: - custom - delete-sso - disabled-password-login-warning - display-name - identifier-filter - no-sso-found - redirect-url - scopes - single-sign-on - sso-created - sso-list - sso-updated - template - token-endpoint - update-sso - user-endpoint These keys existed in zh-Hans.json but were missing in en.json, causing TypeScript type errors during lint checks. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(chat-apps): address security and concurrency issues from code review - Add input validation (platform whitelist, length limits) in store layer - Add startup validation for DIVINESENSE_CHAT_APPS_SECRET_KEY - Fix DingTalk token cache race condition (RWMutex → Mutex) - Add timestamp validation to DingTalk webhook signature (prevent replay) - Improve WhatsApp Bridge health check (verify connection status) - Update media upload fallback behavior with clear logging Security improvements: - MaxPlatformUserID: 255, MaxAccessToken: 2048, MaxAppSecret: 2048 - Webhook timestamp window: 5 minutes with clock skew tolerance - Fail-fast on missing/invalid encryption key at service startup Refs #64 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs(chat-apps): complete documentation for v6.1 release - Add Chat Apps architecture section to ARCHITECTURE.md - Update BACKEND_DB.md with security details (input validation, webhook security) - Enhance CHAT_APPS.md developer guide with security mechanisms - Add comprehensive release notes for v6.1 Documentation highlights: - Security: AES-256-GCM encryption, startup validation, input limits - Webhook security: HMAC-SHA256 + timestamp validation (5-min window) - Concurrency safety: fixed token cache race condition - Architecture diagrams and data flow documentation Related: #64 #53 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs(release): fix issue link in v6.1 release notes - Fix Issue link from #63 to #53 (correct issue number) - Include previous code fixes and documentation updates Refs #53 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(i18n): add missing chat-apps translation keys - Add all required translation keys for Chat Apps settings - Remove duplicate chat-apps section in locale files - Fix code formatting issues Refs #53 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * style(proto): format protobuf files with buf - Apply buf format to chat_app_service.proto files - Collapse multi-line http options to single line - Fix import/option ordering Refs #53 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(settings): add Chat Apps section menu item display - Use .title suffix for chat-apps menu label - Fixes missing Chat Apps entry in settings dropdown Refs #53 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(settings): use .title suffix for chat-apps in sidebar menu too - Apply same fix to SectionMenuItem component - Both desktop and mobile menus now display "Chat Apps" correctly Refs #53 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs(env): add Chat Apps configuration to .env.example - Document DIVINESENSE_CHAT_APPS_SECRET_KEY requirement - Add instructions for generating encryption key Refs #53 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs(chat-apps): add missing INSTANCE_URL and WHATSAPP_BRIDGE_URL env vars - Add DIVINESENSE_INSTANCE_URL for webhook URL generation - Add DIVINESENSE_WHATSAPP_BRIDGE_URL for optional WhatsApp bridge - Document both variables in .env.example with usage descriptions Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs(deploy): add Chat Apps env vars to production config template - Add DIVINESENSE_CHAT_APPS_SECRET_KEY for token encryption - Add DIVINESENSE_WHATSAPP_BRIDGE_URL for optional WhatsApp bridge - Keep in sync with root .env.example Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: 黄飞虹 <aaronwong1989@gmail.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This PR implements the Unified Block Model to consolidate data storage for Normal/Geek/Evolution AI modes into a single Block-based structure. Phase 1: Database & Store - Add ai_block table with JSONB for flexible data storage - Implement AIBlockStore with full CRUD operations - Add migration for PostgreSQL (SQLite stub for compatibility) Phase 2: Proto & API - Add Block message types to ai_service.proto - Add Block-related RPC methods (List/Get/Create/Update/Delete) - Implement gRPC handlers with authentication and ownership checks - Add Connect RPC wrappers Phase 3: Frontend Types - Create block.ts with type definitions and utility functions - Add type guards and constants for BlockType/BlockMode/BlockStatus Phase 4: Frontend Hooks - Create useBlockQueries.ts with React Query hooks - Implement hooks for all Block operations Phase 5: Chat Handler Integration - Create BlockManager for Block lifecycle management - Integrate with existing chat handlers Phase 6: Testing - Add unit tests for PostgreSQL AIBlockStore - Integration tests (require database setup) Resolves #71 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove unused convertAgentTypeToBlockMode function - Remove unused formatMetadata function from block_manager - Remove unused encoding/json import - Fix nil check on map (len() handles nil correctly) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Backend optimizations: - Add database trigger for auto-increment round_number (eliminates extra query) - Add AppendEventsBatch method for efficient event streaming - Add CompleteBlock transaction method for atomicity - Optimize database indexes (composite, GIN with jsonb_path_ops, partial) Frontend optimizations: - Add React Query cache configuration with staleTime/gcTime - Implement optimistic updates with rollback support - Add comprehensive error handling system (blockErrors.ts) - Add useBlockStream hook for efficient streaming - Add usePrefetchBlock hook for data preloading DevOps: - Set up GitHub branch protection (reject force push, reject deletion) Refs #71 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Complete implementation of the Unified Block Model for AI chat: Phase 4 (Frontend): - ChatMessages.tsx: Support AIBlock[] data structure with backward compatibility - AIChatContext: Add loadBlocks, appendUserInput, updateBlockStatus methods - block.ts: Add blockModeToParrotAgentType() helper function - Clean up: Remove unused useBlockStream.ts and blockErrors.ts Phase 5 (Backend Integration): - handler.go: Integrate BlockManager into ParrotHandler streaming flow - Create Block at chat start with proper mode (normal/geek/evolution) - Append events asynchronously during streaming - Complete or mark error on Block at stream end - ai_service_chat.go: Wire up BlockManager in createChatHandler() Phase 6 (Tests): - Add block_manager_test.go with 13 test cases - Block creation (normal, geek, evolution modes) - Event appending (single and batch) - Status updates and completion - Error handling - All tests passing Refs #71 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 4: Frontend integration of Unified Block Model - AIChat.tsx now uses useBlocks() hook to load AIBlock[] data - Added block_id to ChatResponse proto for streaming updates - Backend handler sends block_id in all ChatResponse messages - Frontend useChat hook invalidates blocks cache on block_id event - Regenerated proto types for Go and TypeScript Changes: - proto/api/v1/ai_service.proto: Add block_id field (field 10) - server/router/api/v1/ai/handler.go: Include BlockId in all stream responses - web/src/pages/AIChat.tsx: Use useBlocks() hook and pass blocks to ChatMessages - web/src/hooks/useAIQueries.ts: Handle block_id events, invalidate blocks cache - proto/gen/*: Regenerated proto types This connects the frontend to the existing Block API, enabling real-time Block updates during streaming chat. Refs #71 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 4 enhancements for Unified Block Model: 1. **追加用户输入到 Block** (Append User Input to Block) - AIChat.tsx detects streaming Block state when user sends message - Calls appendUserInput() API to append to current Block instead of creating new message - Added isActiveStatus import from block.ts for Block status detection 2. **错误处理回退** (Error Handling & Fallback) - Added useBlocksWithFallback() hook in useBlockQueries.ts - Returns shouldFallback flag when Block API fails or returns empty - AIChat.tsx uses fallback mode to display ChatItem[] when Block API unavailable - Ensures UI remains functional even when Block backend is down Changes: - web/src/pages/AIChat.tsx: Import isActiveStatus, appendUserInput, loadBlocks - web/src/pages/AIChat.tsx: Detect streaming Block and append user input - web/src/pages/AIChat.tsx: Use useBlocksWithFallback() with error fallback - web/src/hooks/useBlockQueries.ts: Add useBlocksWithFallback() hook - docs/specs/block-design: Update documentation Refs #71 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs(research): add layout spacing unification research report - Analyze current layout spacing inconsistencies across all pages - Define unified spacing specification (mobile: pt-4, desktop: pt-6) - Document sidebar width standardization (w-72 = 288px) - Create implementation roadmap with file change list Refs #74 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(ai): implement Unified Block Model (Issue #71) This PR implements the Unified Block Model to consolidate data storage for Normal/Geek/Evolution AI modes into a single Block-based structure. Phase 1: Database & Store - Add ai_block table with JSONB for flexible data storage - Implement AIBlockStore with full CRUD operations - Add migration for PostgreSQL (SQLite stub for compatibility) Phase 2: Proto & API - Add Block message types to ai_service.proto - Add Block-related RPC methods (List/Get/Create/Update/Delete) - Implement gRPC handlers with authentication and ownership checks - Add Connect RPC wrappers Phase 3: Frontend Types - Create block.ts with type definitions and utility functions - Add type guards and constants for BlockType/BlockMode/BlockStatus Phase 4: Frontend Hooks - Create useBlockQueries.ts with React Query hooks - Implement hooks for all Block operations Phase 5: Chat Handler Integration - Create BlockManager for Block lifecycle management - Integrate with existing chat handlers Phase 6: Testing - Add unit tests for PostgreSQL AIBlockStore - Integration tests (require database setup) Resolves #71 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(ai): remove unused code and fix lint issues - Remove unused convertAgentTypeToBlockMode function - Remove unused formatMetadata function from block_manager - Remove unused encoding/json import - Fix nil check on map (len() handles nil correctly) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(frontend): resolve TypeScript lint issues - Fix proto enum references (BlockMode.NORMAL vs BLOCK_MODE_NORMAL) - Fix bigint to number conversion for id fields - Reorganize imports to satisfy Biome linter - Update type guards to handle both enum and string types Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(ai): optimize Unified Block Model implementation Backend optimizations: - Add database trigger for auto-increment round_number (eliminates extra query) - Add AppendEventsBatch method for efficient event streaming - Add CompleteBlock transaction method for atomicity - Optimize database indexes (composite, GIN with jsonb_path_ops, partial) Frontend optimizations: - Add React Query cache configuration with staleTime/gcTime - Implement optimistic updates with rollback support - Add comprehensive error handling system (blockErrors.ts) - Add useBlockStream hook for efficient streaming - Add usePrefetchBlock hook for data preloading DevOps: - Set up GitHub branch protection (reject force push, reject deletion) Refs #71 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(ai): complete Unified Block Model Phase 4-6 Complete implementation of the Unified Block Model for AI chat: Phase 4 (Frontend): - ChatMessages.tsx: Support AIBlock[] data structure with backward compatibility - AIChatContext: Add loadBlocks, appendUserInput, updateBlockStatus methods - block.ts: Add blockModeToParrotAgentType() helper function - Clean up: Remove unused useBlockStream.ts and blockErrors.ts Phase 5 (Backend Integration): - handler.go: Integrate BlockManager into ParrotHandler streaming flow - Create Block at chat start with proper mode (normal/geek/evolution) - Append events asynchronously during streaming - Complete or mark error on Block at stream end - ai_service_chat.go: Wire up BlockManager in createChatHandler() Phase 6 (Tests): - Add block_manager_test.go with 13 test cases - Block creation (normal, geek, evolution modes) - Event appending (single and batch) - Status updates and completion - Error handling - All tests passing Refs #71 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(ai): remove tautological nil check for sessionSummary sessionSummary is always non-nil (created as pointer to struct literal), so the nil check is redundant. Remove it to satisfy golangci-lint. Refs #71 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(ai): fix code quality issues from code review - Simplify redundant switch statement in block_manager.go (all branches return same value) - Remove unused GIN index on event_stream (no query by event content exists) - Fix enum comparison in ChatMessages (use strict equality instead of String/includes) - Update schema version comment to remove misleading "Phase 1" reference Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * style(proto): fix proto file formatting for buf linter Align comments to single space indentation for buf format compliance. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs: reorganize specification documents and fix optimistic UI - Reorganized Unified Block Model specs into docs/specs/block-design/ - Archived Phase 1-6 implementation specs in archived/ subfolder - Updated main documentation indexes (INDEX.md, README.md) - Fixed broken relative links in documentation - Fixed optimistic UI update logic in useCreateBlock hook - Added joint-audit-report.md and improvement.md for block model * feat: implement timestamp normalization and tree-like branching foundations - Normalized all conversation timestamps to milliseconds (Postgres & Go) - Added parent_block_id to ai_block table for tree-branching support - Updated protobuf definitions for block structure extension - Optimized block storage and conversation summarization logic - Synchronized frontend dependencies * refactor(ai): remove GenUI functionality from normal mode agents Remove Generative UI (GenUI) feature from three normal mode agents: - MemoParrot (灰灰) - removed ui_memo_preview event - SchedulerAgentV2 (时巧) - removed wrapUICallback system and UI events - AmazingParrot (折衷) - removed ui_memo_preview and ui_schedule_list events Backend changes: - ai/agent/amazing_parrot.go: removed uiPreviewCardLimit and UI event generation - ai/agent/memo_parrot.go: removed ui_memo_preview event generation - ai/agent/scheduler_v2.go: removed wrapUICallback and 5 helper functions - ai/agent/scheduler_test.go: updated test expectations Frontend changes: - Deleted web/src/components/ScheduleAI/ directory (16 GenUI components) - Deleted web/src/hooks/useAITools.ts - Removed uiTools props and handlers from AIChat.tsx, ChatMessages.tsx, Schedule.tsx - Simplified useScheduleAgent.ts, useScheduleQueries.ts, useAIQueries.ts - Created simplified StreamingFeedback.tsx for ScheduleQuickInput Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(schedule): i18n optimization for StreamingFeedback component Replace hardcoded English text with i18n keys: - schedule.ai.creating-schedule - schedule.ai.checking-schedule - schedule.ai.updating-schedule - schedule.ai.finding-free-time - schedule.ai.thinking - schedule.ai.processing - schedule.ai.using-tool Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(ai): add event transformers and improve test comments - Add eventTransformers.ts with utilities for extracting ThinkingStep and ToolCall from BlockEvent[] stream - Improve scheduler_test.go comments explaining callback mechanism and why FindSchedules is called twice during ExecuteWithCallback Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(proto): remove trailing whitespace in ai_service.proto Fix buf format lint error by removing trailing spaces in comments. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: 黄飞虹 <aaronwong1989@gmail.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Comprehensive analysis of specification vs implementation for Issue #71. Key findings: - Implementation significantly ahead of documentation - Phases 1-5 complete (83%), Phase 6 partially done - Only real gap: frontend unit tests Report location: docs/reports/unified-block-model-gap-analysis-2026-02-05.md Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
根因分析报告,识别出运行时差距的关键问题: P0 - 异步事件追加错误抑制 - handler.go:483-486 goroutine 忽略 AppendEvent 错误 - 导致 event_stream 刷新后为空 - 用户报告:"仅仅持久化了用户输入和最终模型返回消息" P1 - 前端 Fallback 逻辑缺陷 - useBlockQueries.ts:627 空数组触发 shouldFallback - 新会话强制回退到 items,无法使用 Block API 问题分析: - Mode 正确持久化(数据库验证通过) - event_stream 为空是异步错误抑制导致 - SessionSummary.mode 优先级可能导致主题随机变化 修复方案: - 添加错误通道或同步追加 - 区分"新会话"和"API 失败" - 添加数据库验证日志 Refs #71 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
… of truth 重构目标:移除 SessionSummary.mode,让 Block.mode 成为 Mode 的唯一载体。 变更: 1. proto/api/v1/ai_service.proto - 移除 SessionSummary.mode 字段 2. server/router/api/v1/ai/handler.go - 移除 mode 赋值逻辑 3. web/src/components/AIChat/ChatMessages.tsx - useEffectiveParrotId 只从 Block.mode 读取 4. web/src/types/parrot.ts - 移除 SessionSummary.mode 类型定义 问题解决: - 前端主题不再随机变化 - 消除 SessionSummary.mode 与 Block.mode 的不一致性 - 统一数据来源,简化前端逻辑 新增文档: - docs/specs/block-design/session-summary-positioning.md 三种模式对比图解,SessionSummary 正确定位说明 Refs #71 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ship - Rename proto message SessionSummary to BlockSummary (semantic clarity) - Remove BlockSummary.mode field (Block.mode is single source of truth) - Fix frontend: each Block now reads summary from its own sessionStats - Add sessionStatsToBlockSummary() converter function - Update MessageBlock interface: attachBlockSummary → blockSummary - ChatMessagesProps.blockSummary now only for streaming block This ensures Block and BlockSummary maintain a 1:1 relationship: - Completed blocks: summary from Block.sessionStats (persisted in DB) - Streaming block: summary from ChatResponse.blockSummary (real-time) Refs #71 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…rename - P0: Add error logging to async AppendEvent (was suppressing errors) - P1: Fix streamingBlockSummary condition (only apply to last streaming block) - P2: Remove duplicate Chinese comments in handler.go Refs #71 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Extract complex mergeMessagesIntoState (86 lines) into 5 pure functions for better testability and readability. Fix multiple lint issues discovered during code review. Frontend refactor: - Extract getMessageUid: Get unique identifier from ChatItem - Extract findOptimisticMatch: Find local optimistic update to replace - Extract replaceOptimisticMessage: Replace with metadata preservation - Extract mergeMessageLists: Core merge logic with 3 strategies - Simplify mergeMessagesIntoState from 86 to 30 lines (-65%) Lint fixes: - Add SessionStats import from @/types/block - Fix totalCostUsd → totalCostUSD field name - Fix totalInputTokens → inputTokens field mapping - Fix SessionStats.status → isError conversion - Fix loadMoreMessages dependency: convertMessageFromPb → convertBlockToChatItem Backend monitoring: - Add structured "metric" attribute to event persistence failure logs for monitoring/alerting systems Refs #71 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Code review fixes (11 issues): - P1: Fix race condition in block append (AIChat.tsx) - P1: Add context.WithoutCancel for async goroutines (handler.go) - P2: Add panic recovery in streaming goroutine (ai_service_chat.go) - P2: Pre-allocate toolsUsed slice for performance - P2: Use useMemo for actionDescription (ChatHeader.tsx) - P2: Rename TOOL_CALL_OFFSET_MS → TOOL_CALL_OFFSET_US (constants.ts) - P2: Fix type assertion in useBlockQueries.ts - P3: Add AUTO to PARROT_AGENTS and fix parrotToProtoAgentType mapping - P3: Simplify BLOCK_THEMES to use BlockMode only (NORMAL/GEEK/EVOLUTION) Features: - Remove isTyping restriction: allow sending messages at any time - Messages append to streaming block when available Refs #71 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fix issue where appended user inputs (via appendUserInput API) were not displayed in the UI. Now: - Split Block.userInputs array: first as userMessage, rest as additionalUserInputs - Pass additionalUserInputs to UnifiedMessageBlock component - Add additionalUserInputs field to MessageBlock interface Refs #71 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove 67MB 'divinesense' binary from repository - Add to .gitignore to prevent future accidental commits Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
BlockStatus enum values are numeric (PENDING=1, STREAMING=2), but isActiveStatus was comparing string constants like "BLOCK_STATUS_STREAMING" with numeric values, always returning false. This caused streaming blocks to be incorrectly treated as inactive, resulting in new blocks being created instead of appending user input to the active streaming block. - Change type signature to accept number type - Convert status to numeric before comparison - Compare against enum values (1=PENDING, 2=STREAMING) directly Fixes Geek/Evolution mode user input appending issue. Refs #71 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
AUTO agent type should map to DEFAULT proto type to trigger backend routing. Previously it fell through to AMAZING. Refs #71 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
b2fe41b to
bcd9e68
Compare
- Optimize translateThinkingSteps to skip array creation when no translation needed - Update JSDoc comments: session summary → block summary (2 occurrences) - Update inline comments for consistency - Improve factory.go comment precision for AUTO → DEFAULT mapping Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix UUID namespace collision in cc_runner.go (P0) - Use project-specific UUID namespace instead of DNS namespace - Prevents potential collision with other services - Unify React Query cache keys with blockKeys factory (P1) - Import blockKeys in AIChatContext for consistent cache invalidation - Prevents stale data issues - Optimize logo animation selector performance (P1) - Change from body-scoped to class-scoped selector - Add logo-animated class to NavigationDrawer img element - Replace 'any' types with ApiError interface (P1) - Create web/src/config/errors.ts with type-safe error handling - Update useBlockQueries.ts to use ApiError instead of any - Centralize config constants (P2) - Create web/src/config/chat.ts for chat-related constants - Replace magic numbers across codebase - Remove unused variable (P2) - Remove unused isLoadingBlocks from AIChat.tsx destructuring Refs #71 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
概述
完成 Unified Block Model (Issue #71) 的核心前端集成工作,将前端从使用 ChatItem[] 迁移到使用 AIBlock[] 作为主要数据源。
变更内容
Proto 更新
proto/api/v1/ai_service.proto: 添加int64 block_id = 10字段到 ChatResponse后端修改
server/router/api/v1/ai/handler.go: 在所有 ChatResponse 中包含 BlockId 字段前端修改
web/src/pages/AIChat.tsx: 使用useBlocks()hook 加载 Blocks 数据web/src/hooks/useAIQueries.ts: 处理 block_id 事件,使 Blocks 缓存失效数据流变化
关联 Issue
Resolves #71
测试计划
检查清单
Co-Authored-By: Claude Opus 4.5 noreply@anthropic.com