Skip to content

Conversation

kubbot
Copy link
Contributor

@kubbot kubbot commented Jul 17, 2025

User description

通过使用全局 store 和 idempotent load 函数优化 prompts 加载, 防止切换内容卡片时重复 API 调用.

  • 修改 llm-analysis-store 使 loadPrompts idempotent
  • 更新 ModernAnalysisInterface 使用 store
  • 添加优化测试

Closes #261


Description

  • Refactored ModernAnalysisInterface to optimize AI prompts loading using a global store, preventing repeated API calls when switching content cards.
  • Added unit tests to ensure prompts load correctly and only once across multiple instances.
  • Modernized the chat input and send button design for improved user experience.
  • Updated the loadPrompts function in the store to enhance performance and prevent unnecessary fetches.

Changes walkthrough 📝

Relevant files
Tests
ModernAnalysisInterface.test.tsx
Add tests for prompts loading in ModernAnalysisInterface 

frontend/tests/components/ai/ModernAnalysisInterface.test.tsx

  • Added tests for ModernAnalysisInterface to ensure prompts load
    correctly.
  • Mocked API calls for prompts and content conversations.
  • +64/-0   
    Enhancement
    ModernAnalysisInterface.tsx
    Refactor prompts loading and modernize UI in ModernAnalysisInterface

    frontend/components/ai/ModernAnalysisInterface.tsx

  • Refactored prompts loading to use global store for idempotent loading.
  • Removed local state for prompts and integrated store usage.
  • Updated UI components for modern design.
  • +104/-98
    ai-chat.tsx
    Modernize chat input and button design in AIChat                 

    frontend/components/ui/ai-chat.tsx

  • Updated send button icon from Send to ArrowUpRight.
  • Modernized input field design for better user experience.
  • +31/-20 
    llm-analysis-store.ts
    Improve prompt loading logic in LLM analysis store             

    frontend/lib/stores/llm-analysis-store.ts

  • Enhanced loadPrompts function to prevent redundant API calls.
  • Added checks for existing prompts and loading state.
  • +4/-0     

    💡 Penify usage:
    Comment /help on the PR to get a list of all available Penify tools and their descriptions

    “winston” added 2 commits July 17, 2025 12:13
    - 更新聊天输入框和发送按钮的样式,提升用户体验
    - 将发送按钮的图标从Send更改为ArrowUpRight
    - 优化输入框的布局和交互效果,增加阴影和圆角设计
    - 确保输入框在加载状态下禁用,提升功能一致性
    @kubbot kubbot requested a review from cubxxw as a code owner July 17, 2025 04:59
    @github-project-automation github-project-automation bot moved this to Backlog in nexus Jul 17, 2025
    Copy link
    Contributor

    coderabbitai bot commented Jul 17, 2025

    Important

    Review skipped

    Auto reviews are disabled on base/target branches other than the default branch.

    Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

    You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


    Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

    ❤️ Share
    🪧 Tips

    Chat

    There are 3 ways to chat with CodeRabbit:

    • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
      • I pushed a fix in commit <commit_id>, please review it.
      • Explain this complex logic.
      • Open a follow-up GitHub issue for this discussion.
    • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
      • @coderabbitai explain this code block.
      • @coderabbitai modularize this function.
    • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
      • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
      • @coderabbitai read src/utils.ts and explain its main purpose.
      • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
      • @coderabbitai help me debug CodeRabbit configuration file.

    Support

    Need help? Create a ticket on our support page for assistance with any issues or questions.

    Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

    CodeRabbit Commands (Invoked using PR comments)

    • @coderabbitai pause to pause the reviews on a PR.
    • @coderabbitai resume to resume the paused reviews.
    • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
    • @coderabbitai full review to do a full review from scratch and review all the files again.
    • @coderabbitai summary to regenerate the summary of the PR.
    • @coderabbitai generate docstrings to generate docstrings for this PR.
    • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
    • @coderabbitai resolve resolve all the CodeRabbit review comments.
    • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
    • @coderabbitai help to get help.

    Other keywords and placeholders

    • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
    • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
    • Add @coderabbitai anywhere in the PR title to generate the title automatically.

    CodeRabbit Configuration File (.coderabbit.yaml)

    • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
    • Please see the configuration documentation for more information.
    • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

    Documentation and Community

    • Visit our Documentation for detailed information on how to use CodeRabbit.
    • Join our Discord Community to get help, request features, and share feedback.
    • Follow us on X/Twitter for updates and announcements.

    Copy link
    Contributor

    penify-dev bot commented Jul 17, 2025

    PR Review 🔍

    ⏱️ Estimated effort to review [1-5]

    3, because the changes involve both refactoring existing components and adding new tests, which require a moderate level of understanding of the codebase.

    🧪 Relevant tests

    Yes

    ⚡ Possible issues

    Possible Bug: The loadPrompts function in the store may not handle cases where prompts are already loaded correctly, potentially leading to unexpected behavior.

    🔒 Security concerns

    No

    Copy link

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    🎫 Ticket compliance analysis 🔶

    261 - Partially compliant

    Compliant requirements:

    • Prevent duplicate loading of AI analysis prompts when switching content cards
    • Implement prompts configuration caching mechanism
    • Reduce unnecessary API requests and server load
    • Move prompts configuration to higher-level component management

    Non-compliant requirements:

    • Only reload prompts when user settings change

    Requires further human verification:

    • Improve user experience by eliminating delays during card switching

    ⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
    🧪 PR contains tests
    🔒 No security concerns identified
    ⚡ Recommended focus areas for review

    Race Condition

    The idempotent check uses enabledPrompts.length > 0 which may not be reliable if prompts can be empty legitimately. Also checking isLoadingPrompts without proper synchronization could lead to race conditions in concurrent scenarios.

    const state = get();
    if (state.enabledPrompts.length > 0 || state.isLoadingPrompts) {
      return;
    }
    Type Safety

    Multiple @ts-expect-error comments and unsafe type casting with (cardContent.data as any) indicate potential type safety issues that should be properly addressed rather than suppressed.

    (cardContent.data as any).text ||
    (cardContent.data as any).content ||
    (cardContent.data as any).summary ||
    JSON.stringify(cardContent.data);
    

    Copy link
    Contributor

    penify-dev bot commented Jul 17, 2025

    PR Code Suggestions ✨

    Latest suggestions up to bd42426
    Explore these optional code suggestions:

    CategorySuggestion                                                                                                                                    Impact
    General
    Clear error state when skipping load

    The idempotent check should reset error state when skipping load to prevent
    stale errors from previous failed attempts. This ensures the UI doesn't show
    outdated error messages when prompts are already loaded.

    frontend/lib/stores/llm-analysis-store.ts [158-163]

     loadPrompts: async () => {
       const state = get();
       if (state.enabledPrompts.length > 0 || state.isLoadingPrompts) {
    +    set({ error: null });
         return;
       }
       set({ isLoadingPrompts: true, error: null });
    • Apply / Chat
    Suggestion importance[1-10]: 7

    __

    Why: This suggestion correctly identifies a potential state management issue where a stale error could persist, and the proposed fix is accurate and improves the robustness of the store.

    Medium
    Simplify test mock clearing

    The commented code and @ts-expect-error suppressions are unnecessary since Jest
    mocks are automatically cleared between tests. Remove the clutter and use
    jest.clearAllMocks() for cleaner test setup.

    frontend/tests/components/ai/ModernAnalysisInterface.test.tsx [32-43]

     beforeEach(() => {
    -  // Remove the mockClear lines, as spyOn already handles it
    -  // (promptsApi.getEnabledPrompts as jest.Mock).mockClear();
    -  // etc.
    -  // Add @ts-expect-error for mockClear
    -  // @ts-expect-error - Mocked function
    -  (promptsApi.getEnabledPrompts as jest.Mock).mockClear();
    -  // @ts-expect-error - Mocked function
    -  (promptsApi.getDisabledPrompts as jest.Mock).mockClear();
    -  // @ts-expect-error - Mocked function
    -  (contentApi.getContentConversations as jest.Mock).mockClear();
    +  jest.clearAllMocks();
     });
    • Apply / Chat
    Suggestion importance[1-10]: 6

    __

    Why: The suggestion correctly points out that the beforeEach block can be simplified by using jest.clearAllMocks(), which improves code readability and maintainability.

    Low
    • Update

    Previous suggestions

    Suggestions
    CategorySuggestion                                                                                                                                    Score
    Best practice
    Use jest.clearAllMocks() for resetting mocks in tests

    Instead of using mockClear on the mocked functions, consider using jest.clearAllMocks() in
    the beforeEach to ensure all mocks are reset, which is a cleaner approach.

    frontend/tests/components/ai/ModernAnalysisInterface.test.tsx [38]

    -(promptsApi.getEnabledPrompts as jest.Mock).mockClear();
    +jest.clearAllMocks();
     
    Suggestion importance[1-10]: 8

    Why: Using jest.clearAllMocks() is a cleaner approach to reset all mocks, improving test maintainability and clarity.

    8
    Performance
    Call loadPrompts only once when the component mounts

    Ensure that loadPrompts is only called when the component is mounted by adding an empty
    dependency array to the useEffect hook to prevent unnecessary calls.

    frontend/components/ai/ModernAnalysisInterface.tsx [90-92]

     useEffect(() => {
       loadPrompts();
    -}, [loadPrompts]);
    +}, []);
     
    Suggestion importance[1-10]: 7

    Why: Adding an empty dependency array to the useEffect hook ensures loadPrompts is only called once, optimizing performance.

    7
    Maintainability
    Replace any with a defined interface for better type safety

    Instead of using any for type assertion, define a proper interface for the expected
    structure of cardContent.data to improve type safety.

    frontend/components/ai/ModernAnalysisInterface.tsx [478]

    -(cardContent.data as any).text ||
    +(cardContent.data as YourDefinedInterface).text ||
     
    Suggestion importance[1-10]: 6

    Why: Defining a proper interface instead of using any enhances type safety, making the code more robust and maintainable.

    6
    Accessibility
    Use a semantic button element for the submit action

    Consider using a button element for the submit action instead of a Button component to
    ensure semantic HTML and accessibility.

    frontend/components/ui/ai-chat.tsx [336-346]

    -<Button
    +<button
       type="submit"
       disabled={!input.trim() || isLoading}
    -  size="icon"
    +  className="rounded-full h-6 w-6 shadow-md text-foreground hover:text-foreground bg-neutral-100 hover:bg-neutral-300 dark:bg-zinc-700 dark:hover:bg-zinc-600 cursor-pointer"
     
    Suggestion importance[1-10]: 5

    Why: Using a native button element improves semantic HTML and accessibility, which is important for user experience and compliance.

    5

    “winston” added 16 commits July 17, 2025 16:37
    …flicts
    
    - Update navigation icons:
      - Content Library → Library: change icon from IconArchive to Inbox
      - Home: change icon from IconInnerShadowTop to GalleryHorizontalEnd
      - Prompts: change icon from MessageSquare to BotMessageSquare
    - Rename 'Content Library' to 'Library' in navigation
    - Reorder navigation: Library first, then Home, Favorites, Prompts
    - Add right margin (pr-3) to navigation buttons to prevent edge alignment
    - Fix ContentItemPublic type conflicts by extending openapi-client types
    - Update related test cases to match new navigation structure
    - 引入复选框组件,简化全选和单选链接的操作
    - 更新链接选择区域的样式,提升用户体验
    - 调整复选框的事件处理方式,确保状态管理一致性
    - 调整AI聊天组件底部输入区域内边距从 p-4 改为 p-2
    - 减少enhanced-llm-analysis-sidebar底部Footer区域间距
    - 统一所有聊天组件的底部间距,提升界面紧凑性
    - 涉及文件: ai-chat, streaming-chat, enhanced-llm-analysis-sidebar, chat-with-question-display
    - 将多个组件的底部间距从 mb-4 调整为 mb-1,提升界面紧凑性
    - 更新 ModernAnalysisInterface 和 ChatWithQuestionDisplay 组件的样式,确保一致性
    - 调整 AIChat 组件的内边距,进一步优化用户体验
    - 替换ModernAnalysisInterface中发送按钮的Brain图标为标准Loader2图标
    - 替换加载状态页面的Brain图标为标准Loader2图标
    - 保持与项目其他地方加载图标的一致性
    - 使用标准的旋转加载动画效果
    - 添加详细的控制台日志来调试聊天框无法传输的问题
    - 记录请求开始、URL、请求体、响应状态等关键信息
    - 改进错误处理,显示具体错误信息而不是通用提示
    - 帮助定位前端到后端的API调用问题
    - 添加请求URL、请求体、token状态的详细日志
    - 添加API响应状态、头部信息的调试输出
    - 改进错误处理,显示具体的错误响应内容
    - 添加分析流程各阶段的状态跟踪
    - 帮助排查聊天框无法正常传输到后端的问题
    - 更新DEFAULT_LLM_MODEL为deepseek-v3-ensemble
    - 更新所有AI任务模型配置(summary, key_points, labels, chat, analysis)
    - 移除content.py中的硬编码模型引用,使用配置的默认模型
    - 统一使用DeepSeek V3作为全局默认模型,提升性能和一致性
    Copy link

    CI Feedback 🧐

    A test triggered by this PR failed. Here is an AI-generated analysis of the failure:

    Action: test-docker-compose

    Failed stage: Build and test services [❌]

    Failure summary:

    The action failed during the Docker Compose build step. The error occurred because the path
    /home/runner/work/nexus/nexus/admin was not found when trying to prepare the build context for the
    admin service. This suggests that the admin directory is missing from the repository or the Docker
    Compose configuration is referencing an incorrect path.

    Relevant error logs:
    1:  ##[group]Runner Image Provisioner
    2:  Hosted Compute Agent
    ...
    
    102:  ##[endgroup]
    103:  ##[group]Determining the checkout info
    104:  ##[endgroup]
    105:  [command]/usr/bin/git sparse-checkout disable
    106:  [command]/usr/bin/git config --local --unset-all extensions.worktreeConfig
    107:  ##[group]Checking out the ref
    108:  [command]/usr/bin/git checkout --progress --force -B feat/prompt refs/remotes/origin/feat/prompt
    109:  Switched to a new branch 'feat/prompt'
    110:  branch 'feat/prompt' set up to track 'origin/feat/prompt'.
    111:  ##[endgroup]
    112:  [command]/usr/bin/git log -1 --format=%H
    113:  d2756d75ba86a1b064934875fd9c09ef8fca163c
    114:  ##[group]Run echo "Running as user: $(whoami)"
    115:  �[36;1mecho "Running as user: $(whoami)"�[0m
    116:  �[36;1mecho "Docker access test:"�[0m
    117:  �[36;1mdocker ps || echo "Docker access failed"�[0m
    118:  shell: /usr/bin/bash -e {0}
    ...
    
    150:  �[36;1mdoppler setup --silent --project nexus --config stg�[0m
    151:  �[36;1mdoppler secrets download --no-file --format env > .env�[0m
    152:  shell: /usr/bin/bash -e {0}
    153:  env:
    154:  DOPPLER_TOKEN: ***
    155:  ##[endgroup]
    156:  Using DOPPLER_TOKEN from the environment. To disable this, use --no-read-env.
    157:  ##[group]Run docker compose down -v --remove-orphans
    158:  �[36;1mdocker compose down -v --remove-orphans�[0m
    159:  �[36;1mdocker compose build�[0m
    160:  �[36;1mdocker compose up -d --wait backend frontend admin pgadmin�[0m
    161:  shell: /usr/bin/bash -e {0}
    162:  ##[endgroup]
    163:  Compose can now delegate builds to bake for better performance.
    164:  To do so, set COMPOSE_BAKE=true.
    165:  time="2025-07-18T09:59:33Z" level=warning msg="current commit information was not captured by the build" error="failed to get git commit: "
    166:  unable to prepare context: path "/home/runner/work/nexus/nexus/admin" not found
    167:  ##[error]Process completed with exit code 1.
    168:  Post job cleanup.
    

    @Neo-Neooo Neo-Neooo merged commit 8a725dc into feat/prompt Jul 18, 2025
    3 of 4 checks passed
    @Neo-Neooo Neo-Neooo deleted the feat/fix-issue-261 branch July 18, 2025 10:06
    @github-project-automation github-project-automation bot moved this from Backlog to Done in nexus Jul 18, 2025
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    Projects
    Status: Done
    Development

    Successfully merging this pull request may close these issues.

    2 participants