Skip to content

feat: Evolution Mode 🧬 - Self-Evolution Capability#1

Merged
hrygo merged 14 commits into
mainfrom
evolution/evolution-mode-implementation
Jan 30, 2026
Merged

feat: Evolution Mode 🧬 - Self-Evolution Capability#1
hrygo merged 14 commits into
mainfrom
evolution/evolution-mode-implementation

Conversation

@hrygo

@hrygo hrygo commented Jan 30, 2026

Copy link
Copy Markdown
Owner

概述

实现 Evolution Mode(进化模式) —— DivineSense 自我进化能力,允许系统通过 AI 修改自身源代码并提交 PR。

功能

后端

  • CCRunner 抽象: 统一的 Claude Code CLI 集成层(Geek/Evolution 共享)
  • CCMode 接口: 策略模式实现 GeekMode/EvolutionMode
  • EvolutionParrot: 进化模式专用代理
  • GitService: Git 操作封装(分支创建、提交、checkout)
  • GitHubService: GitHub API 集成(PR 创建)
  • 路径安全: 白名单/黑名单验证

前端

  • EvolutionModeToggle: 切换按钮组件(DNA 视觉元素)
  • EvolutionModeThemeProvider: 主题管理器
  • Purple/Blue 主题: 区别于 Geek Mode 的 Green/Black
  • 互斥逻辑: Geek/Evolution 模式互斥

视觉设计

模式 主色调 动效
Geek Mode Green/Black 终端风格
Evolution Mode Purple/Blue DNA 螺旋

安全

  • 仅限管理员访问
  • 强制 PR 提交流程
  • 路径白名单/黑名单
  • 环境变量启用控制

测试计划

  • 单元测试(CCRunner, GitService, GitHubService)
  • 集成测试(端到端进化流程)
  • UI 测试(切换交互、主题应用)

Co-Authored-By: Claude Opus 4.5 noreply@anthropic.com

aaronwong1989 and others added 14 commits January 30, 2026 14:07
Implements Evolution Mode 🧬 - a self-evolution capability where DivineSense can modify its own source code under strict safety constraints.

## Core Components

### CCRunner Abstraction (cc_runner.go)
- Unified Claude Code CLI integration layer
- Shared by Geek Mode and Evolution Mode
- Session management and stream processing
- Configurable timeout and logging

### CCMode Interface (cc_mode.go)
- Mode-specific behavior interface
- GeekMode: User sandbox directory
- EvolutionMode: Source code root, admin-only
- Path whitelist/blacklist validation

### EvolutionParrot (evolution_parrot.go)
- Main agent for Evolution Mode
- Creates evolution branches (evolution/{task-id})
- Integrates with GitService and GitHubService

### GitService (git_service.go)
- Git operations wrapper
- Branch creation, checkout, commit
- Status tracking and change detection

### GitHubService (github_service.go)
- GitHub API integration
- Pull request creation
- PR listing and status retrieval

## API Changes

- Added `evolution_mode` field to ChatRequest (proto + handler)
- New `handleEvolutionMode()` in ParrotHandler
- Evolution mode has highest priority in routing

## Security

- Admin-only access (requires UserRole.Admin)
- Environment variable gate (DIVINESENSE_EVOLUTION_ENABLED)
- Path whitelist: plugin/, server/, web/src/, docs/, CLAUDE.md
- Path blacklist: .env*, *.secret*, deploy/, .git/, go.mod, go.sum
- Forced GitHub PR workflow (no direct main commits

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add EvolutionModeToggle component with DNA visual motif
- Add EvolutionModeThemeProvider for CSS class management
- Add evolution-mode.css with Purple/Blue gradient theme
- Update AIChatContext with evolutionMode state and toggle
- Add mutual exclusion logic between Geek/Evolution modes
- Update ChatHeader with Evolution Mode toggle button
- Add i18n translations (en/zh-Hans)
- Wire up evolutionMode in AIChat page

Visual design:
- Purple (#BC13FE) + Blue (#4D4DFF) gradient
- DNA helix animation patterns
- Organic flow backgrounds
- Distinct from Geek Mode's Green/Black theme

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add comprehensive GitService tests (branch, commit, status, checkout)
- Add GitHubService tests (PR creation, retrieval, listing)
- Fix GetStatus parsing bug (TrimSpace causing filename truncation)
- Fix status parsing to handle staged changes correctly

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Format files with gofmt (cc_runner.go, evolution_parrot.go, git_service_test.go)
- Remove unused struct fields in test (github_service_test.go)
- Fix printf format specifier for int32 UserID (handler.go)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add evolutionMode field to ChatRequest interface in proto types
- Add evolutionMode parameter to useAIQueries stream function
- Fix biome formatting issues

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Per design review, GitService and GitHubService are unnecessary since
Claude Code CLI handles all git operations and PR creation internally.

Changes:
- Remove GitService (git_service.go, git_service_test.go)
- Remove GitHubService (github_service.go, github_service_test.go)
- Simplify EvolutionMode struct - remove gitService/githubService fields
- Simplify EvolutionParrot - remove gitService-dependent methods
- Update handler.go - remove GetBranchName() call

EvolutionMode now only provides configuration and permission checking;
CC handles the actual git workflow.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update EvolutionMode system prompt to explicitly require following
CLAUDE.md conventions when making code changes.

Key additions:
- MANDATORY section: Always read and follow CLAUDE.md
- CLAUDE.md Key Requirements: atomic commits, conventional format,
  Co-Authored-By tag, i18n, Tailwind v4, make check-all
- Updated workflow: Step 1 is "Read CLAUDE.md first"

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove redundant CLAUDE.md explanations - CC already knows it.
Just require compliance.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove hardcoded path whitelist/blacklist. Now CC follows:
- Forbidden: files excluded by .gitignore
- Allowed: all other files

Also remove ValidatePath method (no longer needed).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add User Interaction Flow section to explain:
- Web browser → Go backend → CLI → Browser streaming
- Progressive output visibility
- Self-evolution scenario context

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove redundancy:
- Duplicate interaction flow (already in basePrompt)
- Duplicate workspace/dir info
- Unnecessary device/OS/user-agent details
- Obvious file output instruction
- Path constraints (CC follows .gitignore automatically)

Focus: Self-evolution + CLAUDE.md + PR requirement.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove basePrompt (no need for device/context info)
- Remove File Output section
- Simplify: ## Requirements → ## Rules
- Add Interaction line for attention guidance

Final prompt: 8 lines, pure signal.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move File Output section from base buildSystemPrompt to GeekMode only
- Fix: Remove debug log at buildSystemPrompt line 66
- Add cc_test.go with 13 unit tests for CCRunner and CCMode
- Reduce geek_parrot.go from 630 to 179 lines (-71%)
- Consolidate shared types (StreamMessage, ContentBlock) into cc_runner.go

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Inject store.Store into EvolutionMode for user role verification
- Implement isAdmin() method using store.GetUser() to check RoleAdmin/RoleHost
- Make AdminOnly configurable via env DIVINESENSE_EVOLUTION_ADMIN_ONLY
- Update NewEvolutionParrot signature to accept store parameter
- Update tests to cover AdminOnly=false scenario

Fixes the placeholder isAdmin() that always returned false,
making Evolution Mode completely inaccessible even for admins.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@hrygo

hrygo commented Jan 30, 2026

Copy link
Copy Markdown
Owner Author

ok

@hrygo hrygo merged commit 9bb3d9d into main Jan 30, 2026
8 checks passed
@hrygo hrygo deleted the evolution/evolution-mode-implementation branch January 30, 2026 10:44
hrygo added a commit that referenced this pull request Feb 5, 2026
* feat(ai): implement Evolution Mode for self-evolution capability

Implements Evolution Mode 🧬 - a self-evolution capability where DivineSense can modify its own source code under strict safety constraints.

## Core Components

### CCRunner Abstraction (cc_runner.go)
- Unified Claude Code CLI integration layer
- Shared by Geek Mode and Evolution Mode
- Session management and stream processing
- Configurable timeout and logging

### CCMode Interface (cc_mode.go)
- Mode-specific behavior interface
- GeekMode: User sandbox directory
- EvolutionMode: Source code root, admin-only
- Path whitelist/blacklist validation

### EvolutionParrot (evolution_parrot.go)
- Main agent for Evolution Mode
- Creates evolution branches (evolution/{task-id})
- Integrates with GitService and GitHubService

### GitService (git_service.go)
- Git operations wrapper
- Branch creation, checkout, commit
- Status tracking and change detection

### GitHubService (github_service.go)
- GitHub API integration
- Pull request creation
- PR listing and status retrieval

## API Changes

- Added `evolution_mode` field to ChatRequest (proto + handler)
- New `handleEvolutionMode()` in ParrotHandler
- Evolution mode has highest priority in routing

## Security

- Admin-only access (requires UserRole.Admin)
- Environment variable gate (DIVINESENSE_EVOLUTION_ENABLED)
- Path whitelist: plugin/, server/, web/src/, docs/, CLAUDE.md
- Path blacklist: .env*, *.secret*, deploy/, .git/, go.mod, go.sum
- Forced GitHub PR workflow (no direct main commits

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(web): implement Evolution Mode UI with Purple/Blue theme

- Add EvolutionModeToggle component with DNA visual motif
- Add EvolutionModeThemeProvider for CSS class management
- Add evolution-mode.css with Purple/Blue gradient theme
- Update AIChatContext with evolutionMode state and toggle
- Add mutual exclusion logic between Geek/Evolution modes
- Update ChatHeader with Evolution Mode toggle button
- Add i18n translations (en/zh-Hans)
- Wire up evolutionMode in AIChat page

Visual design:
- Purple (#BC13FE) + Blue (#4D4DFF) gradient
- DNA helix animation patterns
- Organic flow backgrounds
- Distinct from Geek Mode's Green/Black theme

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test(agent): add Evolution Mode unit tests

- Add comprehensive GitService tests (branch, commit, status, checkout)
- Add GitHubService tests (PR creation, retrieval, listing)
- Fix GetStatus parsing bug (TrimSpace causing filename truncation)
- Fix status parsing to handle staged changes correctly

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* lint: fix golangci-lint issues

- Format files with gofmt (cc_runner.go, evolution_parrot.go, git_service_test.go)
- Remove unused struct fields in test (github_service_test.go)
- Fix printf format specifier for int32 UserID (handler.go)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(web): add evolutionMode to TypeScript types

- Add evolutionMode field to ChatRequest interface in proto types
- Add evolutionMode parameter to useAIQueries stream function
- Fix biome formatting issues

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(agent): simplify Evolution Mode - let CC handle git operations

Per design review, GitService and GitHubService are unnecessary since
Claude Code CLI handles all git operations and PR creation internally.

Changes:
- Remove GitService (git_service.go, git_service_test.go)
- Remove GitHubService (github_service.go, github_service_test.go)
- Simplify EvolutionMode struct - remove gitService/githubService fields
- Simplify EvolutionParrot - remove gitService-dependent methods
- Update handler.go - remove GetBranchName() call

EvolutionMode now only provides configuration and permission checking;
CC handles the actual git workflow.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs(agent): require CLAUDE.md compliance in Evolution Mode prompt

Update EvolutionMode system prompt to explicitly require following
CLAUDE.md conventions when making code changes.

Key additions:
- MANDATORY section: Always read and follow CLAUDE.md
- CLAUDE.md Key Requirements: atomic commits, conventional format,
  Co-Authored-By tag, i18n, Tailwind v4, make check-all
- Updated workflow: Step 1 is "Read CLAUDE.md first"

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(agent): simplify Evolution Mode prompt

Remove redundant CLAUDE.md explanations - CC already knows it.
Just require compliance.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(agent): use .gitignore as path constraint source

Remove hardcoded path whitelist/blacklist. Now CC follows:
- Forbidden: files excluded by .gitignore
- Allowed: all other files

Also remove ValidatePath method (no longer needed).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs(agent): clarify interaction flow in Evolution Mode prompt

Add User Interaction Flow section to explain:
- Web browser → Go backend → CLI → Browser streaming
- Progressive output visibility
- Self-evolution scenario context

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(agent): simplify Evolution Mode prompt

Remove redundancy:
- Duplicate interaction flow (already in basePrompt)
- Duplicate workspace/dir info
- Unnecessary device/OS/user-agent details
- Obvious file output instruction
- Path constraints (CC follows .gitignore automatically)

Focus: Self-evolution + CLAUDE.md + PR requirement.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(agent): finalize Evolution Mode prompt

- Remove basePrompt (no need for device/context info)
- Remove File Output section
- Simplify: ## Requirements → ## Rules
- Add Interaction line for attention guidance

Final prompt: 8 lines, pure signal.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(agent): unify GeekParrot and EvolutionParrot architecture

- Move File Output section from base buildSystemPrompt to GeekMode only
- Fix: Remove debug log at buildSystemPrompt line 66
- Add cc_test.go with 13 unit tests for CCRunner and CCMode
- Reduce geek_parrot.go from 630 to 179 lines (-71%)
- Consolidate shared types (StreamMessage, ContentBlock) into cc_runner.go

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(agent): implement real admin check for Evolution Mode

- Inject store.Store into EvolutionMode for user role verification
- Implement isAdmin() method using store.GetUser() to check RoleAdmin/RoleHost
- Make AdminOnly configurable via env DIVINESENSE_EVOLUTION_ADMIN_ONLY
- Update NewEvolutionParrot signature to accept store parameter
- Update tests to cover AdminOnly=false scenario

Fixes the placeholder isAdmin() that always returned false,
making Evolution Mode completely inaccessible even for admins.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: huangzhonghui <610195979@qq.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Test User <test@example.com>
hrygo pushed a commit that referenced this pull request Feb 6, 2026
… audit fixes (Issue #79)

This commit completes the P0-P3 phase tasks and addresses all code audit findings:

**P2 Tasks:**
- Add BlockSummary restoration from persisted Block.sessionStats after page refresh
- Implement friendly branch path numbering (0/1/2 → A.2.3) with Base26 conversion
- Integrate SessionBar into ChatHeader for PC, mobile-only standalone display

**P3 Tasks:**
- Update AI_CHAT_INTERFACE.md to v0.93.1 with new UI patterns

**Code Audit Fixes:**
- P1-#1: Add safeBigIntToNumber with MAX_SAFE_INTEGER boundary check
- P2-#1: Add MAX_ITERATIONS limit to toBase26 to prevent potential infinite loops
- P2-#2: Optimize calculateSessionStats to process only last 100 blocks
- P3-#1: Replace hardcoded Chinese text with i18n t() calls
- P3-#2: Add detailed comment for MILLI_CENTS_TO_USD constant

**New Components:**
- HeaderSessionStats: Mode-differentiated session stats (Normal/Geek/Evolution)

**Bug Fixes:**
- Fix ForkBlock protobuf serialization using create(UserInputSchema, ...)
- Fix ToolCalls duplication with occurrence-based deduplication
- Fix import ordering per Biome lint rules

Refs #79

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
hrygo added a commit that referenced this pull request Feb 6, 2026
…79) (#84)

* feat(ai): implement LLM stats collection, cost tracking, and conversation branching (Issue #79)

This commit implements three interconnected specifications:
- P1-A006: LLM Stats Collection + Session Summary for Normal Mode
- ai-block-fields-extension: Token usage, cost estimate, model version fields
- tree-conversation-branching: Fork/switch/delete conversation branches

Backend changes:
- Add LLMCallStats struct with token usage and timing metrics
- Refactor LLMService.Chat/ChatStream to return stats
- Implement BaseParrot with stats accumulation for all Parrot agents
- Add TokenUsage, CostEstimate fields to Block proto/message
- Add parent_block_id, branch_path for tree branching support
- Add ForkBlock, ListBlockBranches, SwitchBranch, DeleteBranch RPCs
- Implement postgres migration for new Block fields
- Add comprehensive tests for stats, ForkBlock, and cost calculation

Frontend changes:
- Add TokenUsageBadge and BlockCostBadge components for displaying stats
- Add BranchIndicator and BranchSelector for conversation branching
- Implement useBranchTree hook for branch operations
- Update SessionSummaryPanel to display token usage and timing
- Add frontend integration tests with Vitest
- Update i18n keys for new features

Documentation:
- Add AI_CHAT_INTERFACE.md with complete UI architecture diagrams
- Update ARCHITECTURE.md with Unified Block Model references

All 51 Loki Mode tasks completed. make check-all passes.

Refs #79

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs(claude-md): refactor as project manifesto

- Restructure from patch collection to纲领性 document
- Add "第一性原理" section defining project essence
- Consolidate architecture decisions with clear mappings
- Streamline workflow and coding standards
- Remove troubleshooting details (defer to DEBUG_LESSONS.md)
- Reduce from 150 to 112 lines while increasing clarity

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(ai, frontend): add session summary bar and code quality fixes

Features:
- Add SessionBar component displaying aggregated session stats (cost, tokens, duration)
- Add BlockEditDialog for editing user inputs and creating branches
- Add type guards isStreamingStatus(), isErrorStatus() for BlockStatus checks
- Add isCompletedStatus() helper function

Code quality fixes (P0/P1/P2/P3):
- Fix JSX syntax errors: rename test files from .test.ts to .test.tsx
- Fix BlockStatus comparison bug (String() was always false)
- Reduce 'any' type usage in useBlockQueries.ts
- Extract magic number MILLI_CENTS_TO_USD constant
- Remove unused imports and variables

i18n:
- Add translations for session bar, edit dialog, and status labels

Refs #79

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(cc): simplify EvolutionMode system prompt

- Condense decision tree from verbose Chinese to concise English
- Simplify idea-researcher trigger flow
- Add language directive to CCRunner system prompt

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(ai, frontend): fix Block editing and cursor flicker issues

Backend changes:
- Add replaceUserInputs parameter to ForkBlock API for message editing
- Add reason validation and return InvalidArgument for empty reason
- Store fork metadata (forked_from, fork_reason, fork_type) for debugging
- Remove duplicate log entry from ForkBlock (keep service layer only)
- Add unit tests: TestForkBlock_WithReplaceUserInputs, TestForkBlock_EmptyReason

Frontend changes:
- Simplify BlockEditDialog UI: remove "original message" display area
- Merge multiple user inputs (with newlines) for editing
- Fix handleEdit to pass complete MessageBlock for input merging
- Remove onSend call after ForkBlock (was creating duplicate block)
- Add new i18n keys: message, edit_placeholder

Bug fix:
- Fix mouse cursor flickering on /auth/signup page caused by overly
  broad [tabIndex] CSS selector targeting Radix UI components

Refs #79

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(ai, frontend): complete session summary UI enhancements and code audit fixes (Issue #79)

This commit completes the P0-P3 phase tasks and addresses all code audit findings:

**P2 Tasks:**
- Add BlockSummary restoration from persisted Block.sessionStats after page refresh
- Implement friendly branch path numbering (0/1/2 → A.2.3) with Base26 conversion
- Integrate SessionBar into ChatHeader for PC, mobile-only standalone display

**P3 Tasks:**
- Update AI_CHAT_INTERFACE.md to v0.93.1 with new UI patterns

**Code Audit Fixes:**
- P1-#1: Add safeBigIntToNumber with MAX_SAFE_INTEGER boundary check
- P2-#1: Add MAX_ITERATIONS limit to toBase26 to prevent potential infinite loops
- P2-#2: Optimize calculateSessionStats to process only last 100 blocks
- P3-#1: Replace hardcoded Chinese text with i18n t() calls
- P3-#2: Add detailed comment for MILLI_CENTS_TO_USD constant

**New Components:**
- HeaderSessionStats: Mode-differentiated session stats (Normal/Geek/Evolution)

**Bug Fixes:**
- Fix ForkBlock protobuf serialization using create(UserInputSchema, ...)
- Fix ToolCalls duplication with occurrence-based deduplication
- Fix import ordering per Biome lint rules

Refs #79

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(router): remove unused mu field from RouterCache

The sync.RWMutex field was declared but never used since the underlying
LRUCache handles its own locking internally.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test(frontend): fix all TypeScript lint errors in test files

- Remove unused BlockListCacheData interface (re-added for internal use)
- Fix protobuf mock creation using proper types
- Change \`as any\` to \`as unknown as Type\` for observer mocks
- Use EmptySchema for delete/append operations
- Use ListBlocksResponseSchema for list operations
- Import EmptySchema from @bufbuild/protobuf/wkt

Refs #79

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* style(proto): format ai_service.proto with buf

* chore(frontend): update lockfile to match package.json dependencies

- Update @testing-library/jest-dom from 6.6.0 to 6.9.1
- Update @testing-library/react from 16.2.0 to 16.3.2

---------

Co-authored-by: 黄飞虹 <aaronwong1989@gmail.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
hrygo pushed a commit that referenced this pull request Feb 6, 2026
- Add TotalCostUsd conversion from NormalSessionStats.TotalCostMilliCents
- Add debug logging for token tracking in normal mode agents
- Remove frontend debug console.log/console.debug statements
  - Keep console.error and console.warn for error reporting
- Update SessionSummaryPanel and UnifiedMessageBlock for stats display

Refs #1

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
hrygo pushed a commit that referenced this pull request Feb 6, 2026
… audit fixes (Issue #79)

This commit completes the P0-P3 phase tasks and addresses all code audit findings:

**P2 Tasks:**
- Add BlockSummary restoration from persisted Block.sessionStats after page refresh
- Implement friendly branch path numbering (0/1/2 → A.2.3) with Base26 conversion
- Integrate SessionBar into ChatHeader for PC, mobile-only standalone display

**P3 Tasks:**
- Update AI_CHAT_INTERFACE.md to v0.93.1 with new UI patterns

**Code Audit Fixes:**
- P1-#1: Add safeBigIntToNumber with MAX_SAFE_INTEGER boundary check
- P2-#1: Add MAX_ITERATIONS limit to toBase26 to prevent potential infinite loops
- P2-#2: Optimize calculateSessionStats to process only last 100 blocks
- P3-#1: Replace hardcoded Chinese text with i18n t() calls
- P3-#2: Add detailed comment for MILLI_CENTS_TO_USD constant

**New Components:**
- HeaderSessionStats: Mode-differentiated session stats (Normal/Geek/Evolution)

**Bug Fixes:**
- Fix ForkBlock protobuf serialization using create(UserInputSchema, ...)
- Fix ToolCalls duplication with occurrence-based deduplication
- Fix import ordering per Biome lint rules

Refs #79

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
hrygo pushed a commit that referenced this pull request Feb 6, 2026
Add guidance for using TODO LIST to track multiple tasks, preventing
"memory loss" or losing direction during multi-task sessions.

When to use TODO LIST:
- Multiple optimization points found during analysis
- User requests to tackle issues one by one
- Tasks take >1 hour or have multiple steps

Workflow:
1. Create tasks with TaskCreate after analysis
2. Track status with TaskList
3. Update to in_progress before starting
4. Mark completed when done

Example practice from this session:
- Analyzed logs → found 5 issues
- Created 4 TODOs for remaining work
- Completed #1 (connection warmup), tracked others

Refs #79

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
hrygo added a commit that referenced this pull request Feb 6, 2026
* fix(frontend): optimize Vite config for React deps stability

Add React and related dependencies to optimizeDeps.include to prevent
runtime issues where React hooks may be unavailable due to module
loading order problems.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(ai): implement LLM stats collection, cost tracking, and conversation branching (Issue #79)

This commit implements three interconnected specifications:
- P1-A006: LLM Stats Collection + Session Summary for Normal Mode
- ai-block-fields-extension: Token usage, cost estimate, model version fields
- tree-conversation-branching: Fork/switch/delete conversation branches

Backend changes:
- Add LLMCallStats struct with token usage and timing metrics
- Refactor LLMService.Chat/ChatStream to return stats
- Implement BaseParrot with stats accumulation for all Parrot agents
- Add TokenUsage, CostEstimate fields to Block proto/message
- Add parent_block_id, branch_path for tree branching support
- Add ForkBlock, ListBlockBranches, SwitchBranch, DeleteBranch RPCs
- Implement postgres migration for new Block fields
- Add comprehensive tests for stats, ForkBlock, and cost calculation

Frontend changes:
- Add TokenUsageBadge and BlockCostBadge components for displaying stats
- Add BranchIndicator and BranchSelector for conversation branching
- Implement useBranchTree hook for branch operations
- Update SessionSummaryPanel to display token usage and timing
- Add frontend integration tests with Vitest
- Update i18n keys for new features

Documentation:
- Add AI_CHAT_INTERFACE.md with complete UI architecture diagrams
- Update ARCHITECTURE.md with Unified Block Model references

All 51 Loki Mode tasks completed. make check-all passes.

Refs #79

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(ai, frontend): add session summary bar and code quality fixes

Features:
- Add SessionBar component displaying aggregated session stats (cost, tokens, duration)
- Add BlockEditDialog for editing user inputs and creating branches
- Add type guards isStreamingStatus(), isErrorStatus() for BlockStatus checks
- Add isCompletedStatus() helper function

Code quality fixes (P0/P1/P2/P3):
- Fix JSX syntax errors: rename test files from .test.ts to .test.tsx
- Fix BlockStatus comparison bug (String() was always false)
- Reduce 'any' type usage in useBlockQueries.ts
- Extract magic number MILLI_CENTS_TO_USD constant
- Remove unused imports and variables

i18n:
- Add translations for session bar, edit dialog, and status labels

Refs #79

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(ai, frontend): complete session summary UI enhancements and code audit fixes (Issue #79)

This commit completes the P0-P3 phase tasks and addresses all code audit findings:

**P2 Tasks:**
- Add BlockSummary restoration from persisted Block.sessionStats after page refresh
- Implement friendly branch path numbering (0/1/2 → A.2.3) with Base26 conversion
- Integrate SessionBar into ChatHeader for PC, mobile-only standalone display

**P3 Tasks:**
- Update AI_CHAT_INTERFACE.md to v0.93.1 with new UI patterns

**Code Audit Fixes:**
- P1-#1: Add safeBigIntToNumber with MAX_SAFE_INTEGER boundary check
- P2-#1: Add MAX_ITERATIONS limit to toBase26 to prevent potential infinite loops
- P2-#2: Optimize calculateSessionStats to process only last 100 blocks
- P3-#1: Replace hardcoded Chinese text with i18n t() calls
- P3-#2: Add detailed comment for MILLI_CENTS_TO_USD constant

**New Components:**
- HeaderSessionStats: Mode-differentiated session stats (Normal/Geek/Evolution)

**Bug Fixes:**
- Fix ForkBlock protobuf serialization using create(UserInputSchema, ...)
- Fix ToolCalls duplication with occurrence-based deduplication
- Fix import ordering per Biome lint rules

Refs #79

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test(frontend): fix all TypeScript lint errors in test files

- Remove unused BlockListCacheData interface (re-added for internal use)
- Fix protobuf mock creation using proper types
- Change \`as any\` to \`as unknown as Type\` for observer mocks
- Use EmptySchema for delete/append operations
- Use ListBlocksResponseSchema for list operations
- Import EmptySchema from @bufbuild/protobuf/wkt

Refs #79

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore(frontend): update lockfile to match package.json dependencies

- Update @testing-library/jest-dom from 6.6.0 to 6.9.1
- Update @testing-library/react from 16.2.0 to 16.3.2

* fix(ai): remove duplicate TrackToolCall in MemoParrot

Rebase caused duplicate TrackToolCall call. Remove one instance.

Refs #79

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(ai): add thinking event before LLM call + add episodic_memory table

- Fix cold-start latency issue in ScheduleParrot by sending thinking event
  before first LLM call (reduces perceived latency from 4s to immediate feedback)
- Add episodic_memory table to LATEST.sql for new installations
- Unify all Parrot agents to send thinking event before LLM call

Related to #79

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(db): sync all missing tables to LATEST.sql

Add 6 missing tables to LATEST.sql for new installations:
- user_preferences: AI personalization preferences
- conversation_context: AI session persistence and recovery
- agent_metrics: A/B testing metrics
- tool_metrics: Tool call performance metrics
- chat_app_credential: Multi-platform chat app integrations
- ai_block: Unified Block Model (core table!)

This ensures new installations have all required tables from the start,
preventing "relation does not exist" warnings.

Related to #79

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs(db): add migration guide and sync check script

Add prevention mechanism for future migration sync issues:
- store/migration/postgres/CLAUDE.md: Complete migration development guide
- scripts/check-migration-sync.sh: Automated sync verification script
- Link to migration guide in root CLAUDE.md

Key principles:
1. Any DB change must update BOTH migrate/*.up.sql AND LATEST.sql
2. Run check-migration-sync.sh before committing migrations

Related to #79

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore(db): remove redundant old migration files

Remove 5 outdated migration files from root of postgres dir:
- 20260203_chat_apps_credential.* (superseded by 20260203070000_*)
- 20260203_conversation_channel_type.* (superseded by 20260203130000_*)
- V0.53.4__add_chat_app_app_secret.sql (superseded by 20260203080000_*)

These files:
- Use old naming format (YYYYMMDD_ and V*.*__)
- Are not read by the migration system (migrator.go only reads migrate/)
- Have newer counterparts in migrate/ directory

Directory structure now cleaner:
- CLAUDE.md (migration guide)
- migrate/ (incremental migrations)
- schema/ (LATEST.sql)

Related to #79

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs(architecture): update architecture docs for router optimization

- Update freshness timestamp to 2026-02-07 (v0.93.1)
- Document four-layer routing system (Cache → Rule → History → LLM)
- Add AI model strategy overview table
- Update intent classification to use SiliconFlow + Qwen2.5-7B-Instruct
- Document fast path optimization (time + query keywords)
- Remove deprecated ChatRouterConfig from API documentation
- Add structured JSON Schema output for LLM classifier

Ref:
- ai/router/service.go: four-layer routing implementation
- server/router/api/v1/ai_service.go: SiliconFlow + Qwen integration
- ai/router/rule_matcher.go: fast path optimization

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* perf(ai): add LLM connection warmup on service startup

Add asynchronous LLM connection warmup to reduce first-request latency.
The warmup sends a minimal ping request (max_tokens=1, temperature=0)
to pre-establish TCP/TLS connections before the first real user request.

Changes:
- Add Warmup(ctx) method to llmService with direct API call
  - Uses max_tokens=1 (minimum cost, ~85% cheaper than default)
  - Uses temperature=0 (fastest deterministic response)
  - 5s timeout, failures don't affect service startup
- Call Warmup asynchronously in NewAPIV1Service after LLM init
- Add provider() helper for logging

Expected impact:
- First request latency: ~5400ms → ~4900ms (save ~500ms)
- Warmup cost: ~¥0.0000006 per startup (vs ¥0.000005 before)

Refs #79

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs(claude): add multi-task management workflow with TODO LIST

Add guidance for using TODO LIST to track multiple tasks, preventing
"memory loss" or losing direction during multi-task sessions.

When to use TODO LIST:
- Multiple optimization points found during analysis
- User requests to tackle issues one by one
- Tasks take >1 hour or have multiple steps

Workflow:
1. Create tasks with TaskCreate after analysis
2. Track status with TaskList
3. Update to in_progress before starting
4. Mark completed when done

Example practice from this session:
- Analyzed logs → found 5 issues
- Created 4 TODOs for remaining work
- Completed #1 (connection warmup), tracked others

Refs #79

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* perf(ai): fix N+1 query in ListAIConversations

Use LEFT JOIN + COUNT GROUP BY to fetch block counts in a single query,
eliminating the N+1 query problem where each conversation triggered
a separate ListAIBlocks call.

Changes:
- store.AIConversation: add BlockCount field
- postgres.ListAIConversations: use LEFT JOIN ai_block with COUNT
- Remove per-conversation ListAIBlocks calls from handler

Before: N conversations → N+1 database queries
After:  N conversations → 1 database query

Performance impact:
- 10 conversations: 11 queries → 1 query (91% reduction)
- 100 conversations: 101 queries → 1 query (99% reduction)

Refs #79

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(ai): improve token stats logging for tool-based agents

Tool-based agents (MemoParrot/ScheduleParrot/AmazingParrot) don't have
direct LLM calls, so token stats are always zero. Instead of logging
misleading zeros, log meaningful tool metrics:

Changes:
- When PromptTokens=0 and CompletionTokens=0:
  - Log "tool-based agent stats" with tool_calls count
  - Log "tool-based agent completed" with tools used
- Preserve original logging for agents with real token stats

Before:
  Agent: got normal stats... prompt_tokens=0 completion_tokens=0
  Agent: applied normal stats... prompt_tokens=0 completion_tokens=0

After:
  Agent: tool-based agent stats tool_calls=1 duration_ms=5423
  Agent: tool-based agent completed tool_calls=1 tools=schedule_query

Refs #79

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* style(ai): format llm.go with gofmt

Align comment formatting in Warmup function for consistency.

Refs #79

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(frontend): use ListMessages API in useBlocksWithFallback

- Use ListMessages API instead of ListBlocks for pagination support
- Reduces duplicate DB queries when switching conversations
- React Query now caches response for both hooks

Before: useBlocksWithFallback → ListBlocks + syncMessages → ListMessages
After:  Both hooks use ListMessages → cached response

Refs #79

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs(claude): optimize with SOTA Agent engineering practices

Major improvements:
- Add "SOTA Agent 工程实践" section with:
  - Thinking Protocol for complex decisions
  - Tool usage strategy matrix
  - Metacognition: self-healing protocol when stuck
  - SOTA reasoning patterns (CoT, ReAct, Self-Refinement)
- Restructure for progressive disclosure
- Add freshness header (v0.93.1)
- Simplify tables for better scannability
- Emoji icons for visual hierarchy

Key additions:
- When to use Task tools vs direct operations
- Explicit thinking criteria (architecture changes, unfamiliar APIs)
- Self-healing flow: re-read → visualize → clarify → confidence → document

Refs #79

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(logs): remove duplicate block creation log

BlockManager already logs "Created block for chat" with round_number.
Removed redundant log in handler.go to avoid duplication.

Refs #79

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(lint): remove unused llmResponse type

Refs #79

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(frontend): regenerate broken pnpm lockfile

The lockfile had duplicated mapping keys causing CI to fail.
Regenerated with pnpm install.

Refs #87

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(logs): optimize API logging format

- Add duration_ms to track request processing time
- Shorten service name (remove memos.api.v1. prefix)
- Use underscore case for status (ok, client_error, server_error)
- Use empty message for cleaner structured log output

Before: INFO OK method=/memos.api.v1.AuthService/GetCurrentUser
After:  INFO type=API method=AuthService/GetCurrentUser status=ok duration_ms=12

Refs #79

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>
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