Skip to content

Conversation

@zerob13
Copy link
Collaborator

@zerob13 zerob13 commented Aug 29, 2025

  • add default system prompt for deepchat
  • remove systemprompt and tools from image generate model
  • fix dataimport bug
  • clean up some ui items

Summary by CodeRabbit

  • New Features

    • Manage default system prompt: Reset to built-in or Clear from Settings; older configs auto-populate on upgrade; store and presenter expose these actions.
    • Per-model-type behavior: image-generation models suppress system prompt and related enrichments.
  • UI

    • Chat Config shows model-type icons and hides system prompt for image models.
    • Prompt Settings add Reset/Clear actions with feedback.
    • Web content length limit redesigned with +/- and inline edit.
  • Reliability

    • More robust data import across DB versions with clearer errors.
    • Window now ensures initial position stays on-screen.
  • Localization

    • Added prompt-setting translations for multiple languages.
  • Chores

    • Version bumped to 0.3.4.

Improve the web content length limit setting in CommonSettings with:
- Replace simple input with interactive counter design
- Add -/+ buttons for quick adjustments (±100 step)
- Enable click-to-edit number for direct input
- Update range to 0-10000 characters
- Maintain single-row compact layout
- Add visual feedback and hover states

🤖 Generated with [Claude Code](https://claude.ai/code)
…orter

- Add missing fields (enabled_mcp_tools, thinking_budget, reasoning_effort, verbosity) to SELECT query
- Add compatibility handling for different database schema versions
- Use try-catch to fall back to basic fields when new fields are not available
- Ensure INSERT and SELECT statements have matching field structure

Fixes data import error: Failed to import data
… import

- Fix 'no such column: metadata' error in message_attachments table
- Add schema compatibility handling for both source and target databases
- Use try-catch pattern to fall back to basic schema when metadata column is not available
- Fix TypeScript errors by properly handling unknown error types
- Ensure both SELECT and INSERT operations are compatible with different schema versions

Resolves the core issue causing data import failures: SqliteError: no such column: metadata
- Remove verbose console.log statements used for debugging
- Remove unnecessary try-catch wrappers that only rethrow errors
- Keep essential error handling and schema compatibility features
- Fix TypeScript errors related to unused catch parameters

Code is now production-ready after successful debugging phase.
@zerob13 zerob13 marked this pull request as ready for review August 29, 2025 14:46
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 29, 2025

Walkthrough

Adds default system-prompt management (reset/clear) with migration to 0.3.4, introduces model-type awareness for image-generation flows across presenter and UI, enhances SQLite importer with multi-version schema fallbacks and richer errors, updates CommonSettings web content limit control, bumps package version, and adds i18n strings for new prompt actions.

Changes

Cohort / File(s) Summary
Version bump
package.json
Bump version 0.3.3 → 0.3.4.
Config prompt management
src/main/presenter/configPresenter/index.ts, src/shared/presenter.d.ts, src/renderer/src/stores/settings.ts, src/renderer/src/components/settings/PromptSetting.vue
Add DEFAULT_SYSTEM_PROMPT, migration for pre-0.3.4 empty default_system_prompt, new public APIs resetToDefaultPrompt() and clearSystemPrompt() on ConfigPresenter and declaration file, expose store helpers, and UI buttons/handlers to reset/clear the system prompt.
Model-type awareness (image-generation)
src/main/presenter/threadPresenter/index.ts, src/renderer/src/components/ChatConfig.vue, src/renderer/src/components/NewThread.vue, src/renderer/src/components/TitleView.vue
Add optional modelType (ModelType) to prompt preparation; suppress system prompt, search/enrichment, MCP tools and related token reservations for image-generation models; propagate model type through UI and hide System Prompt for imageGeneration.
SQLite import compatibility & hardening
src/main/presenter/sqlitePresenter/importData.ts
Add read/insert fallbacks for newer/legacy schemas (conversations, message_attachments, attachments), COALESCE/defaults for missing fields, per-conversation/message/attachment try/catch with descriptive errors, and clearer transactional error messages.
Settings UI control change
src/renderer/src/components/settings/CommonSettings.vue
Replace numeric input with +/- control and inline editing for webContentLengthLimit; add editing state, focus handling, increase/decrease handlers, validation (0..10000), and persistence via config presenter.
Prompt setting UI / i18n
src/renderer/src/components/settings/PromptSetting.vue, src/renderer/src/i18n/*/settings.json
Add Reset/Clear buttons and handlers in PromptSetting.vue and add promptSetting translations (resetToDefault, clear, reset/clear success/failure) across multiple locales (en-US, fa-IR, fr-FR, ja-JP, ko-KR, ru-RU, zh-CN, zh-HK, zh-TW).
Window position validation
src/main/presenter/windowPresenter/index.ts
Add validateWindowPosition helper and use it to ensure the initial shell window position fits the primary display work area or is centered.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant TitleView as TitleView.vue
  participant NewThread as NewThread.vue
  participant ChatConfig as ChatConfig.vue
  participant ThreadP as threadPresenter
  participant Model as Model API

  User->>TitleView: Select model
  TitleView->>ChatConfig: :model-type = config.type
  User->>NewThread: Start new thread
  NewThread->>ChatConfig: :model-type = activeModel.type
  User->>ChatConfig: Send message
  ChatConfig->>ThreadP: preparePromptContent(..., modelType)
  alt modelType == ImageGeneration
    ThreadP-->>ThreadP: Suppress systemPrompt/search/enrichment/MCP tooling
    ThreadP->>Model: formatMessagesForCompletion(with empty systemPrompt)
  else
    ThreadP-->>ThreadP: Include systemPrompt/search/enrichment/MCP tooling
    ThreadP->>Model: formatMessagesForCompletion(with systemPrompt)
  end
  Model-->>ThreadP: Response
  ThreadP-->>User: Rendered result
Loading
sequenceDiagram
  autonumber
  participant Importer as importData.ts
  participant SrcDB as Source SQLite
  participant DstDB as Target SQLite

  Importer->>DstDB: BEGIN TRANSACTION
  Importer->>SrcDB: SELECT conversations (try new fields)
  alt New-schema available
    SrcDB-->>Importer: Rows (new fields)
  else Fallback
    Importer->>SrcDB: SELECT conversations (legacy fields)
    SrcDB-->>Importer: Rows (legacy)
    Importer-->>Importer: Normalize missing fields with defaults
  end

  loop each conversation
    Importer->>DstDB: INSERT conversation (try new-fields insert)
    alt Insert fails
      Importer->>DstDB: INSERT conversation (legacy insert)
    end
    Importer->>SrcDB: SELECT messages
    loop each message
      Importer->>DstDB: INSERT message (try/catch)
      opt attachments
        Importer->>SrcDB: SELECT message_attachments (try with metadata)
        alt metadata missing
          Importer->>SrcDB: SELECT message_attachments (legacy)
          Importer-->>Importer: Normalize metadata=null
        end
        Importer->>DstDB: INSERT attachments (try with metadata, fallback)
      end
    end
  end
  Importer->>DstDB: COMMIT
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • deepinfect

Poem

I’m a rabbit in the changelog glade,
Version bumped and prompts remade.
Clear or reset with one small hop,
Image models skip the system stop.
Older imports stitched to new—hip hop hooray! 🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore/ux-in-settings

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.
    • 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.
  • 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 the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

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

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit 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

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • 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

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 13

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/shared/presenter.d.ts (1)

1040-1040: Type typo breaks type-checking: use unknown

unknow is invalid TS type and will cause declaration errors.

-  env: Record<string, unknow>
+  env: Record<string, unknown>
src/main/presenter/sqlitePresenter/importData.ts (1)

37-39: Password quoting in PRAGMA is unsafe; escape or use hex key.

Direct string interpolation into PRAGMA key can break on quotes and is injection-prone. Escape single quotes or use the recommended hex key format.

-      this.sourceDb.pragma(`cipher='sqlcipher'`)
-      this.sourceDb.pragma(`key='${sourcePassword}'`)
+      this.sourceDb.pragma(`cipher='sqlcipher'`)
+      this.sourceDb.pragma(`key='${String(sourcePassword).replace(/'/g, "''")}'`)
@@
-        this.targetDb.pragma(`cipher='sqlcipher'`)
-        this.targetDb.pragma(`key='${targetPassword}'`)
+        this.targetDb.pragma(`cipher='sqlcipher'`)
+        this.targetDb.pragma(`key='${String(targetPassword).replace(/'/g, "''")}'`)

Optional: this.sourceDb.pragma("key = \"x'" + Buffer.from(sourcePassword).toString('hex') + "'\"") to avoid quoting entirely.

Also applies to: 49-51

🧹 Nitpick comments (12)
src/shared/presenter.d.ts (1)

461-463: Document new API and align semantics

Add brief JSDoc to clarify behavior (reset uses built‑in default; clear sets to empty/no system prompt). Consider renaming for clarity to resetSystemPromptToDefault/clearSystemPrompt if feasible (optional).

   // 默认系统提示词设置
   getDefaultSystemPrompt(): Promise<string>
   setDefaultSystemPrompt(prompt: string): Promise<void>
+  /**
+   * Reset the system prompt to the built-in default value (removes any user override).
+   */
   resetToDefaultPrompt(): Promise<void>
+  /**
+   * Clear the system prompt (sets to empty / no system prompt).
+   */
   clearSystemPrompt(): Promise<void>
src/renderer/src/i18n/en-US/settings.json (1)

797-800: Tighten English copy

“Clear prompt words” is awkward; use “Clear prompt” for brevity/consistency.

   "promptSetting": {
     "resetToDefault": "Reset to default prompt",
-    "clear": "Clear prompt words"
+    "clear": "Clear prompt"
   }
src/renderer/src/components/ChatConfig.vue (2)

38-41: Use English for comments.

Project guideline requires English for logs/comments. Please translate these inline comments.

-// 判断是否为图片生成模型
+// Whether the selected model is an image-generation model

141-163: Reduce v-if chain with a computed icon name.

Minor readability win: compute the icon once and render a single Icon.

-      <Icon
-        v-if="props.modelType === 'chat'"
-        icon="lucide:message-circle"
-        class="w-3 h-3 text-muted-foreground"
-      />
-      <Icon
-        v-else-if="props.modelType === 'imageGeneration'"
-        icon="lucide:image"
-        class="w-3 h-3 text-muted-foreground"
-      />
-      <Icon
-        v-else-if="props.modelType === 'embedding'"
-        icon="lucide:layers"
-        class="w-3 h-3 text-muted-foreground"
-      />
-      <Icon
-        v-else-if="props.modelType === 'rerank'"
-        icon="lucide:arrow-up-down"
-        class="w-3 h-3 text-muted-foreground"
-      />
+      <Icon :icon="{
+        chat: 'lucide:message-circle',
+        imageGeneration: 'lucide:image',
+        embedding: 'lucide:layers',
+        rerank: 'lucide:arrow-up-down'
+      }[props.modelType || 'chat']" class="w-3 h-3 text-muted-foreground" />
src/renderer/src/components/TitleView.vue (1)

126-127: Ensure config includes ‘type’; add defensive default.

If getModelDefaultConfig ever omits type, modelType becomes undefined. Default to ModelType.Chat to avoid UI regressions.

-const modelType = ref(ModelType.Chat)
+const modelType = ref(ModelType.Chat)
...
-      modelType.value = config.type
+      modelType.value = (config as any)?.type ?? ModelType.Chat

Also applies to: 135-135

src/renderer/src/components/NewThread.vue (1)

216-217: Prefer carrying through model tags when available.

You’re setting tags: [] repeatedly even when model.tags may exist. Minor, but loses UI info.

-                    tags: [],
+                    tags: model.tags ?? [],
@@
-                  tags: [],
+                  tags: model.tags ?? [],
@@
-          tags: [],
+          tags: model.tags ?? [],
@@
-    tags: [],
+    tags: model.tags ?? [],

Also applies to: 243-244, 269-269, 301-301

src/main/presenter/sqlitePresenter/importData.ts (2)

1-63: Enable foreign keys and use English comments.

  • Turn on FK enforcement to catch integrity issues early.
  • Comments are in Chinese; project guideline requires English.
   constructor(
@@
-    // 初始化源数据库连接
+    // Initialize source database connection
     this.sourceDb = new Database(sourcePath)
+    this.sourceDb.pragma('foreign_keys = ON')
@@
-      this.targetDb = new Database(targetDbOrPath)
+      this.targetDb = new Database(targetDbOrPath)
       this.targetDb.pragma('journal_mode = WAL')
+      this.targetDb.pragma('foreign_keys = ON')

237-296: Prepare statements once per method to improve performance.

Inside tight loops you repeatedly call prepare. Hoist prepare calls outside loops and reuse statements.

src/main/presenter/configPresenter/index.ts (1)

33-38: Minor copy nit in DEFAULT_SYSTEM_PROMPT.

Missing space: “languages.Always”. Consider tightening wording.

-Adhere to this in all languages.Always respond in the same language as the user's query.`
+Adhere to this in all languages. Always respond in the same language as the user's query.`
src/renderer/src/components/settings/CommonSettings.vue (3)

448-450: limitInputRef unused; optionally focus after entering edit mode.

Call focus to justify the new ref.

 const startEditingLimit = () => {
   isEditingLimit.value = true
+  setTimeout(() => limitInputRef.value?.focus(), 0)
 }

Also applies to: 751-759


724-736: Logs must be English and avoid hardcoded CN text.

Update log string; keep behavior unchanged.

-  if (numValue >= 0 && numValue <= 10000 && !isNaN(numValue)) {
+  if (numValue >= 0 && numValue <= 10000 && !isNaN(numValue)) {
     try {
-      const displayText = numValue === 0 ? '无限制' : `${numValue}字符`
-      console.log('设置网页内容长度限制:', displayText)
+      const displayText = numValue === 0 ? 'Unlimited' : `${numValue} characters`
+      console.log('Set web content length limit:', displayText)
       // 直接调用presenter设置,不依赖store
       await configPresenter.setSetting('webContentLengthLimit', numValue)
       // 更新响应式变量
       webContentLengthLimit.value = numValue
     } catch (error) {
-      console.error('设置网页内容长度限制失败:', error)
+      console.error('Failed to set web content length limit:', error)
     }
   }

739-748: Clamp WebContentLengthLimit max to 10,000

  • Change upper bound from 20,000 to 10,000 to match the input’s max and disabled state.
  • Verify that settings.common.unlimited and settings.common.characters i18n keys exist.
-const increaseWebContentLimit = () => {
-  const newValue = Math.min(webContentLengthLimit.value + 100, 20000)
+const increaseWebContentLimit = () => {
+  const newValue = Math.min(webContentLengthLimit.value + 100, 10000)
   handleWebContentLengthLimitChange(newValue)
}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 8eeee3f and 5f64d2b.

📒 Files selected for processing (20)
  • package.json (1 hunks)
  • src/main/presenter/configPresenter/index.ts (5 hunks)
  • src/main/presenter/sqlitePresenter/importData.ts (5 hunks)
  • src/main/presenter/threadPresenter/index.ts (3 hunks)
  • src/renderer/src/components/ChatConfig.vue (4 hunks)
  • src/renderer/src/components/NewThread.vue (6 hunks)
  • src/renderer/src/components/TitleView.vue (3 hunks)
  • src/renderer/src/components/settings/CommonSettings.vue (4 hunks)
  • src/renderer/src/components/settings/PromptSetting.vue (2 hunks)
  • src/renderer/src/i18n/en-US/settings.json (1 hunks)
  • src/renderer/src/i18n/fa-IR/settings.json (1 hunks)
  • src/renderer/src/i18n/fr-FR/settings.json (1 hunks)
  • src/renderer/src/i18n/ja-JP/settings.json (1 hunks)
  • src/renderer/src/i18n/ko-KR/settings.json (1 hunks)
  • src/renderer/src/i18n/ru-RU/settings.json (1 hunks)
  • src/renderer/src/i18n/zh-CN/settings.json (1 hunks)
  • src/renderer/src/i18n/zh-HK/settings.json (1 hunks)
  • src/renderer/src/i18n/zh-TW/settings.json (1 hunks)
  • src/renderer/src/stores/settings.ts (2 hunks)
  • src/shared/presenter.d.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (21)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development-setup.mdc)

**/*.{js,jsx,ts,tsx}: 使用 OxLint 进行代码检查
Log和注释使用英文书写

Files:

  • src/shared/presenter.d.ts
  • src/renderer/src/stores/settings.ts
  • src/main/presenter/sqlitePresenter/importData.ts
  • src/main/presenter/configPresenter/index.ts
  • src/main/presenter/threadPresenter/index.ts
src/shared/*.d.ts

📄 CodeRabbit inference engine (.cursor/rules/electron-best-practices.mdc)

The shared/*.d.ts files are used to define the types of objects exposed by the main process to the renderer process

Files:

  • src/shared/presenter.d.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/error-logging.mdc)

**/*.{ts,tsx}: 始终使用 try-catch 处理可能的错误
提供有意义的错误信息
记录详细的错误日志
优雅降级处理
日志应包含时间戳、日志级别、错误代码、错误描述、堆栈跟踪(如适用)、相关上下文信息
日志级别应包括 ERROR、WARN、INFO、DEBUG
不要吞掉错误
提供用户友好的错误信息
实现错误重试机制
避免记录敏感信息
使用结构化日志
设置适当的日志级别

Enable and adhere to strict TypeScript type checking

Files:

  • src/shared/presenter.d.ts
  • src/renderer/src/stores/settings.ts
  • src/main/presenter/sqlitePresenter/importData.ts
  • src/main/presenter/configPresenter/index.ts
  • src/main/presenter/threadPresenter/index.ts
src/shared/**/*.{ts,tsx,d.ts}

📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)

共享类型定义放在 shared 目录

Files:

  • src/shared/presenter.d.ts
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

Use English for all logs and comments

Files:

  • src/shared/presenter.d.ts
  • src/renderer/src/components/ChatConfig.vue
  • src/renderer/src/stores/settings.ts
  • src/renderer/src/components/settings/PromptSetting.vue
  • src/main/presenter/sqlitePresenter/importData.ts
  • src/renderer/src/components/TitleView.vue
  • src/main/presenter/configPresenter/index.ts
  • src/renderer/src/components/settings/CommonSettings.vue
  • src/renderer/src/components/NewThread.vue
  • src/main/presenter/threadPresenter/index.ts
src/shared/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Put shared types and IPC contracts in src/shared/

Files:

  • src/shared/presenter.d.ts
src/renderer/src/**/*

📄 CodeRabbit inference engine (.cursor/rules/i18n.mdc)

src/renderer/src/**/*: All user-facing strings must use i18n keys (avoid hardcoded user-visible text in code)
Use the 'vue-i18n' framework for all internationalization in the renderer
Ensure all user-visible text in the renderer uses the translation system

Files:

  • src/renderer/src/i18n/zh-CN/settings.json
  • src/renderer/src/i18n/ko-KR/settings.json
  • src/renderer/src/i18n/ru-RU/settings.json
  • src/renderer/src/i18n/ja-JP/settings.json
  • src/renderer/src/components/ChatConfig.vue
  • src/renderer/src/i18n/zh-TW/settings.json
  • src/renderer/src/i18n/fa-IR/settings.json
  • src/renderer/src/i18n/en-US/settings.json
  • src/renderer/src/stores/settings.ts
  • src/renderer/src/i18n/zh-HK/settings.json
  • src/renderer/src/i18n/fr-FR/settings.json
  • src/renderer/src/components/settings/PromptSetting.vue
  • src/renderer/src/components/TitleView.vue
  • src/renderer/src/components/settings/CommonSettings.vue
  • src/renderer/src/components/NewThread.vue
src/renderer/src/**

📄 CodeRabbit inference engine (CLAUDE.md)

Organize UI components by feature under src/renderer/src/

Files:

  • src/renderer/src/i18n/zh-CN/settings.json
  • src/renderer/src/i18n/ko-KR/settings.json
  • src/renderer/src/i18n/ru-RU/settings.json
  • src/renderer/src/i18n/ja-JP/settings.json
  • src/renderer/src/components/ChatConfig.vue
  • src/renderer/src/i18n/zh-TW/settings.json
  • src/renderer/src/i18n/fa-IR/settings.json
  • src/renderer/src/i18n/en-US/settings.json
  • src/renderer/src/stores/settings.ts
  • src/renderer/src/i18n/zh-HK/settings.json
  • src/renderer/src/i18n/fr-FR/settings.json
  • src/renderer/src/components/settings/PromptSetting.vue
  • src/renderer/src/components/TitleView.vue
  • src/renderer/src/components/settings/CommonSettings.vue
  • src/renderer/src/components/NewThread.vue
src/renderer/**/*.{vue,ts,js,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)

渲染进程代码放在 src/renderer

Files:

  • src/renderer/src/components/ChatConfig.vue
  • src/renderer/src/stores/settings.ts
  • src/renderer/src/components/settings/PromptSetting.vue
  • src/renderer/src/components/TitleView.vue
  • src/renderer/src/components/settings/CommonSettings.vue
  • src/renderer/src/components/NewThread.vue
src/renderer/src/**/*.{vue,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/vue-best-practices.mdc)

src/renderer/src/**/*.{vue,ts,tsx,js,jsx}: Use the Composition API for better code organization and reusability
Implement proper state management with Pinia
Utilize Vue Router for navigation and route management
Leverage Vue's built-in reactivity system for efficient data handling

Files:

  • src/renderer/src/components/ChatConfig.vue
  • src/renderer/src/stores/settings.ts
  • src/renderer/src/components/settings/PromptSetting.vue
  • src/renderer/src/components/TitleView.vue
  • src/renderer/src/components/settings/CommonSettings.vue
  • src/renderer/src/components/NewThread.vue
src/renderer/src/**/*.vue

📄 CodeRabbit inference engine (.cursor/rules/vue-best-practices.mdc)

Use scoped styles to prevent CSS conflicts between components

src/renderer/src/**/*.vue: Follow existing component patterns when creating new UI components
Ensure responsive design with Tailwind CSS for new UI components
Add proper error handling and loading states to UI components

Files:

  • src/renderer/src/components/ChatConfig.vue
  • src/renderer/src/components/settings/PromptSetting.vue
  • src/renderer/src/components/TitleView.vue
  • src/renderer/src/components/settings/CommonSettings.vue
  • src/renderer/src/components/NewThread.vue
src/renderer/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)

src/renderer/**/*.{ts,tsx,vue}: Use descriptive variable names with auxiliary verbs (e.g., isLoading, hasError).
Use TypeScript for all code; prefer types over interfaces.
Avoid enums; use const objects instead.
Use arrow functions for methods and computed properties.
Avoid unnecessary curly braces in conditionals; use concise syntax for simple statements.

Files:

  • src/renderer/src/components/ChatConfig.vue
  • src/renderer/src/stores/settings.ts
  • src/renderer/src/components/settings/PromptSetting.vue
  • src/renderer/src/components/TitleView.vue
  • src/renderer/src/components/settings/CommonSettings.vue
  • src/renderer/src/components/NewThread.vue
src/renderer/**/*.{vue,ts}

📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)

Implement lazy loading for routes and components.

Files:

  • src/renderer/src/components/ChatConfig.vue
  • src/renderer/src/stores/settings.ts
  • src/renderer/src/components/settings/PromptSetting.vue
  • src/renderer/src/components/TitleView.vue
  • src/renderer/src/components/settings/CommonSettings.vue
  • src/renderer/src/components/NewThread.vue
src/renderer/**/*.{ts,vue}

📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)

src/renderer/**/*.{ts,vue}: Use useFetch and useAsyncData for data fetching.
Implement SEO best practices using Nuxt's useHead and useSeoMeta.

src/renderer/**/*.{ts,vue}: Use Pinia for frontend state management
From renderer to main, call presenters via the usePresenter.ts composable

Files:

  • src/renderer/src/components/ChatConfig.vue
  • src/renderer/src/stores/settings.ts
  • src/renderer/src/components/settings/PromptSetting.vue
  • src/renderer/src/components/TitleView.vue
  • src/renderer/src/components/settings/CommonSettings.vue
  • src/renderer/src/components/NewThread.vue
src/renderer/**/*.vue

📄 CodeRabbit inference engine (CLAUDE.md)

src/renderer/**/*.vue: Use Vue 3 Composition API for all components
Use Tailwind CSS with scoped styles for component styling

Files:

  • src/renderer/src/components/ChatConfig.vue
  • src/renderer/src/components/settings/PromptSetting.vue
  • src/renderer/src/components/TitleView.vue
  • src/renderer/src/components/settings/CommonSettings.vue
  • src/renderer/src/components/NewThread.vue
src/{main,renderer}/**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/electron-best-practices.mdc)

src/{main,renderer}/**/*.ts: Use context isolation for improved security
Implement proper inter-process communication (IPC) patterns
Optimize application startup time with lazy loading
Implement proper error handling and logging for debugging

Files:

  • src/renderer/src/stores/settings.ts
  • src/main/presenter/sqlitePresenter/importData.ts
  • src/main/presenter/configPresenter/index.ts
  • src/main/presenter/threadPresenter/index.ts
src/renderer/src/stores/**/*.{vue,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/pinia-best-practices.mdc)

src/renderer/src/stores/**/*.{vue,ts,tsx,js,jsx}: Use modules to organize related state and actions
Implement proper state persistence for maintaining data across sessions
Use getters for computed state properties
Utilize actions for side effects and asynchronous operations
Keep the store focused on global state, not component-specific data

Files:

  • src/renderer/src/stores/settings.ts
src/main/**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/electron-best-practices.mdc)

Use Electron's built-in APIs for file system and native dialogs

From main to renderer, broadcast events via EventBus using mainWindow.webContents.send()

Files:

  • src/main/presenter/sqlitePresenter/importData.ts
  • src/main/presenter/configPresenter/index.ts
  • src/main/presenter/threadPresenter/index.ts
src/main/**/*.{ts,js,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)

主进程代码放在 src/main

Files:

  • src/main/presenter/sqlitePresenter/importData.ts
  • src/main/presenter/configPresenter/index.ts
  • src/main/presenter/threadPresenter/index.ts
src/main/presenter/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Maintain one presenter per functional domain in src/main/presenter/

Files:

  • src/main/presenter/sqlitePresenter/importData.ts
  • src/main/presenter/configPresenter/index.ts
  • src/main/presenter/threadPresenter/index.ts
src/main/presenter/configPresenter/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Centralize configuration logic under configPresenter/

Files:

  • src/main/presenter/configPresenter/index.ts
🧠 Learnings (7)
📚 Learning: 2025-08-26T14:13:46.601Z
Learnt from: CR
PR: ThinkInAIXYZ/deepchat#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-26T14:13:46.601Z
Learning: Applies to src/main/presenter/configPresenter/**/*.ts : Centralize configuration logic under configPresenter/

Applied to files:

  • src/shared/presenter.d.ts
  • src/main/presenter/configPresenter/index.ts
📚 Learning: 2025-08-26T14:13:46.601Z
Learnt from: CR
PR: ThinkInAIXYZ/deepchat#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-26T14:13:46.601Z
Learning: Applies to src/main/presenter/configPresenter/providers.ts : Add new provider configuration entries in configPresenter/providers.ts

Applied to files:

  • src/shared/presenter.d.ts
  • src/renderer/src/components/TitleView.vue
  • src/main/presenter/configPresenter/index.ts
📚 Learning: 2025-07-21T01:46:30.354Z
Learnt from: CR
PR: ThinkInAIXYZ/deepchat#0
File: .cursor/rules/i18n.mdc:0-0
Timestamp: 2025-07-21T01:46:30.354Z
Learning: Applies to src/renderer/src/i18n/common.json : Shared translation keys must be placed in 'src/renderer/src/i18n/common.json'

Applied to files:

  • src/renderer/src/i18n/ru-RU/settings.json
📚 Learning: 2025-07-23T00:45:57.322Z
Learnt from: CR
PR: ThinkInAIXYZ/deepchat#0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-07-23T00:45:57.322Z
Learning: Applies to src/renderer/**/*.{vue} : Use <script setup> syntax for concise component definitions.

Applied to files:

  • src/renderer/src/components/ChatConfig.vue
📚 Learning: 2025-07-21T01:46:30.354Z
Learnt from: CR
PR: ThinkInAIXYZ/deepchat#0
File: .cursor/rules/i18n.mdc:0-0
Timestamp: 2025-07-21T01:46:30.354Z
Learning: Applies to src/renderer/src/**/* : Use the 'vue-i18n' framework for all internationalization in the renderer

Applied to files:

  • src/renderer/src/components/ChatConfig.vue
📚 Learning: 2025-07-23T00:45:57.322Z
Learnt from: CR
PR: ThinkInAIXYZ/deepchat#0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-07-23T00:45:57.322Z
Learning: Applies to src/renderer/**/*.{vue} : Import Icon component from Iconify/Vue.

Applied to files:

  • src/renderer/src/components/ChatConfig.vue
📚 Learning: 2025-07-23T00:45:57.322Z
Learnt from: CR
PR: ThinkInAIXYZ/deepchat#0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-07-23T00:45:57.322Z
Learning: Applies to src/renderer/{composables,utils}/**/*.ts : Use VueUse for common composables and utility functions.

Applied to files:

  • src/renderer/src/components/ChatConfig.vue
🧬 Code graph analysis (2)
src/renderer/src/stores/settings.ts (1)
src/main/presenter/configPresenter/index.ts (2)
  • resetToDefaultPrompt (1208-1210)
  • clearSystemPrompt (1213-1215)
src/main/presenter/threadPresenter/index.ts (4)
src/shared/presenter.d.ts (1)
  • ChatMessage (1318-1330)
src/main/presenter/threadPresenter/searchManager.ts (1)
  • generateSearchPrompt (231-247)
src/main/presenter/threadPresenter/contentEnricher.ts (1)
  • ContentEnricher (12-383)
src/main/presenter/index.ts (1)
  • presenter (223-223)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build-check (x64)
🔇 Additional comments (16)
package.json (1)

3-3: Version bump looks good.

0.3.4 aligns with the new config migration and prompt actions. No further changes needed here.

src/renderer/src/i18n/zh-HK/settings.json (2)

797-800: LGTM (terms consistent and natural).

“重置為默認提示詞 / 清空提示詞” reads well and matches existing terminology.


797-800: All locales include promptSetting.resetToDefault and promptSetting.clear
Verified that every settings.json under src/renderer/src/i18n contains both keys.

src/renderer/src/i18n/zh-CN/settings.json (1)

797-800: LGTM (terminology and tone are consistent).

“清空提示词 / 重置为默认提示词” matches existing “系统提示词” usage.

src/shared/presenter.d.ts (1)

461-463: Presenter methods implemented and wired
ConfigPresenter defines resetToDefaultPrompt and clearSystemPrompt (index.ts 1208–1214) and the renderer store calls both in src/renderer/src/stores/settings.ts (1633–1639).

src/renderer/src/components/TitleView.vue (1)

77-78: Passing modelType to ChatConfig: LGTM.

Propagating the model type ensures UI aligns with model capabilities (e.g., hiding system prompt). No issues spotted.

src/renderer/src/components/NewThread.vue (1)

149-157: Initialize and type model ‘type’: LGTM.

Defaulting to ModelType.Chat and typing the shape avoids undefined state; additions are consistent with the rest of this PR.

src/main/presenter/sqlitePresenter/importData.ts (3)

69-121: Schema fallback on conversations: LGTM.

Good multi-version compatibility with a clear fallback and sane defaults for missing fields.


123-149: Transaction wrapping with detailed error propagation: LGTM.

The transaction scope and propagated errors are appropriate; rollback semantics are preserved.


360-391: Robust fallback for message_attachments: LGTM.

Gracefully handles presence/absence of metadata across versions and normalizes results.

src/main/presenter/threadPresenter/index.ts (2)

33-33: ModelType import: OK

No issues with the new import.


2123-2126: MCP tools gating: LGTM

MCP tool definitions are skipped for image-generation; token accounting updated accordingly.

src/main/presenter/configPresenter/index.ts (2)

193-193: Migration rename: OK

migrateConfigData is invoked correctly in the version bump flow.


1207-1215: Reset/Clear APIs: OK

Methods align with new UI actions and eventing via setSetting().

src/renderer/src/stores/settings.ts (1)

1633-1640: Approve: store passthroughs and UI handlers verified
Store methods resetToDefaultPrompt and clearSystemPrompt are properly exported in settings.ts and invoked via click handlers in PromptSetting.vue; ready to merge.

src/renderer/src/components/settings/PromptSetting.vue (1)

28-76: Header + actions wiring: OK

Buttons are properly bound; status indicator logic is clear.

Comment on lines +278 to +283
if (oldVersion && compare(oldVersion, '0.3.4', '<')) {
const currentPrompt = this.getSetting<string>('default_system_prompt')
if (!currentPrompt || currentPrompt.trim() === '') {
this.setSetting('default_system_prompt', DEFAULT_SYSTEM_PROMPT)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Default prompt set only on upgrade; fresh installs still get empty default.

New users won’t receive DEFAULT_SYSTEM_PROMPT because defaults set default_system_prompt to ''. Either set the default in ElectronStore defaults or ensure migrate runs for first-run.

Apply this change to store defaults (shown as plain TS since it’s outside the changed hunk):

// in constructor defaults:
default_system_prompt: DEFAULT_SYSTEM_PROMPT,
🤖 Prompt for AI Agents
In src/main/presenter/configPresenter/index.ts around lines 278 to 283, the
migration only sets DEFAULT_SYSTEM_PROMPT for users upgrading from <0.3.4,
leaving fresh installs with an empty default; update the ElectronStore
constructor defaults to include default_system_prompt: DEFAULT_SYSTEM_PROMPT (or
alternatively ensure the migration runs on first-run by invoking it when no
prior version exists) so new installs receive the proper default prompt.

Comment on lines +160 to +189
try {
// 首先尝试使用包含所有新字段的INSERT语句
this.targetDb
.prepare(
`INSERT INTO conversations (
conv_id, title, created_at, updated_at, system_prompt,
temperature, context_length, max_tokens, provider_id,
model_id, is_pinned, is_new, artifacts, enabled_mcp_tools,
thinking_budget, reasoning_effort, verbosity
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
)
.run(
conv.conv_id,
conv.title,
conv.created_at,
conv.updated_at,
conv.system_prompt,
conv.temperature,
conv.context_length,
conv.max_tokens,
conv.provider_id,
conv.model_id,
conv.is_pinned || 0,
conv.is_new || 0,
conv.artifacts || 0,
conv.enabled_mcp_tools || null,
conv.thinking_budget || null,
conv.reasoning_effort || null,
conv.verbosity || null
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

Use nullish coalescing (??) instead of || to preserve valid zero values.

thinking_budget can legitimately be 0 (used to disable reasoning). foo || null would turn 0 into null, corrupting data on import.

-          conv.is_pinned || 0,
-          conv.is_new || 0,
-          conv.artifacts || 0,
-          conv.enabled_mcp_tools || null,
-          conv.thinking_budget || null,
-          conv.reasoning_effort || null,
-          conv.verbosity || null
+          conv.is_pinned ?? 0,
+          conv.is_new ?? 0,
+          conv.artifacts ?? 0,
+          conv.enabled_mcp_tools ?? null,
+          conv.thinking_budget ?? null,
+          conv.reasoning_effort ?? null,
+          conv.verbosity ?? null

Apply the same ?? change to the legacy INSERT block, and consider token_count, is_context_edge, is_variant, vectorized, and file_size sites similarly where 0 is valid.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
try {
// 首先尝试使用包含所有新字段的INSERT语句
this.targetDb
.prepare(
`INSERT INTO conversations (
conv_id, title, created_at, updated_at, system_prompt,
temperature, context_length, max_tokens, provider_id,
model_id, is_pinned, is_new, artifacts, enabled_mcp_tools,
thinking_budget, reasoning_effort, verbosity
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
)
.run(
conv.conv_id,
conv.title,
conv.created_at,
conv.updated_at,
conv.system_prompt,
conv.temperature,
conv.context_length,
conv.max_tokens,
conv.provider_id,
conv.model_id,
conv.is_pinned || 0,
conv.is_new || 0,
conv.artifacts || 0,
conv.enabled_mcp_tools || null,
conv.thinking_budget || null,
conv.reasoning_effort || null,
conv.verbosity || null
)
try {
// 首先尝试使用包含所有新字段的INSERT语句
this.targetDb
.prepare(
`INSERT INTO conversations (
conv_id, title, created_at, updated_at, system_prompt,
temperature, context_length, max_tokens, provider_id,
model_id, is_pinned, is_new, artifacts, enabled_mcp_tools,
thinking_budget, reasoning_effort, verbosity
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
)
.run(
conv.conv_id,
conv.title,
conv.created_at,
conv.updated_at,
conv.system_prompt,
conv.temperature,
conv.context_length,
conv.max_tokens,
conv.provider_id,
conv.model_id,
conv.is_pinned ?? 0,
conv.is_new ?? 0,
conv.artifacts ?? 0,
conv.enabled_mcp_tools ?? null,
conv.thinking_budget ?? null,
conv.reasoning_effort ?? null,
conv.verbosity ?? null
)
🤖 Prompt for AI Agents
In src/main/presenter/sqlitePresenter/importData.ts around lines 160 to 189, the
INSERT uses || to coalesce fields which converts valid zeroes to null (e.g.,
thinking_budget); replace uses of || with the nullish coalescing operator (??)
for the listed fields so that 0 is preserved. Update this INSERT block and the
legacy INSERT block similarly, and also apply ?? instead of || for other
numeric/boolean fields where 0 or false are valid (token_count, is_context_edge,
is_variant, vectorized, file_size, and any similar sites) so only null/undefined
become null while 0/false remain intact.

Comment on lines +2098 to 2100
supportsFunctionCall: boolean,
modelType?: ModelType
): Promise<{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Image-generation gating is never activated (modelType not passed to preparePromptContent).

preparePromptContent checks modelType === ModelType.ImageGeneration, but callers don’t pass modelType, so isImageGeneration is always false. Search suppression, URL enrichment suppression, system prompt suppression, and MCP tool omission won’t apply to image models.

Please pass modelConfig.type as the last argument at both call sites:

// startStreamCompletion(...)
const { finalContent, promptTokens } = await this.preparePromptContent(
  conversation,
  userContent,
  contextMessages,
  searchResults,
  urlResults,
  userMessage,
  vision,
  vision ? imageFiles : [],
  modelConfig.functionCall,
  modelConfig?.type // <- add this
)

// continueStreamCompletion(...)
const { finalContent, promptTokens } = await this.preparePromptContent(
  conversation,
  'continue',
  contextMessages,
  null,
  [],
  userMessage,
  false,
  [],
  modelConfig.functionCall,
  modelConfig?.type // <- add this
)

Run to locate all call sites:

Also applies to: 2106-2126, 2145-2145


🏁 Script executed:

#!/bin/bash
rg -nP -C2 '\bpreparePromptContent\s*\(' --type=ts

Length of output: 1246


Pass modelConfig.type to preparePromptContent
src/main/presenter/threadPresenter/index.ts lines 1733 and 1887 invoke preparePromptContent without the final modelType argument, so image‐generation gating never runs. Update both calls to:

,
modelConfig.functionCall,
modelConfig.type
)
🤖 Prompt for AI Agents
In src/main/presenter/threadPresenter/index.ts (call sites at ~lines 1733 and
1887; function signature around 2098-2100), preparePromptContent is currently
invoked without the final modelType parameter so image-generation gating never
runs; update both invocation sites to pass modelConfig.type as the last argument
alongside the existing modelConfig.functionCall (i.e., add modelConfig.type as
the final parameter) so preparePromptContent receives supportsFunctionCall and
the modelType.

Comment on lines +44 to +51
watch(
() => props.modelType,
(newType) => {
if (newType === 'imageGeneration' && systemPrompt.value) {
systemPrompt.value = ''
}
}
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

System prompt may still be sent for image models if this component isn’t mounted.

Clearing happens only when ChatConfig is mounted (it’s inside a Popover and may lazy-mount). If the user selects an image-generation model and sends immediately without opening settings, systemPrompt won’t be cleared. Gate at the send/path-building layer as well.

Follow-up: In NewThread.vue’s handleSend (and any other send path), force systemPrompt = '' when model.type === ImageGeneration. I’ve proposed a concrete patch in the NewThread.vue comment.

🤖 Prompt for AI Agents
In src/renderer/src/components/ChatConfig.vue around lines 44-51, clearing
systemPrompt in the component only runs when that component is mounted, so
image-generation models can still receive systemPrompt if the user sends
immediately; to fix, update the send/path-building layer (e.g., NewThread.vue
handleSend and any other send handlers) to explicitly set systemPrompt = '' (or
clear the request payload's system prompt field) whenever model.type ===
'imageGeneration' before building/sending the message; ensure you handle both
local state and the constructed API payload so no system prompt is sent for
image-generation models.

Comment on lines +100 to 101
:model-type="activeModel?.type"
/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

Image models still send systemPrompt on first message (Popover not opened).

Because ChatConfig’s clearing runs only when mounted, handleSend can still pass the default system prompt for image-generation models. Gate it here to enforce PR objective “Remove system prompt … from image generation model”.

Apply this patch to handleSend:

@@
-const handleSend = async (content: UserMessageContent) => {
+const handleSend = async (content: UserMessageContent) => {
+  const isImageGen = activeModel.value.type === ModelType.ImageGeneration
@@
-  const threadId = await chatStore.createThread(content.text, {
+  const threadId = await chatStore.createThread(content.text, {
     providerId: activeModel.value.providerId,
     modelId: activeModel.value.id,
-    systemPrompt: systemPrompt.value,
+    systemPrompt: isImageGen ? '' : systemPrompt.value,
@@
     verbosity: verbosity.value,
     enabledMcpTools: chatStore.chatConfig.enabledMcpTools
   } as any)

Optional: also strip tools here for image models if applicable in your domain object.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
:model-type="activeModel?.type"
/>
const handleSend = async (content: UserMessageContent) => {
const isImageGen = activeModel.value.type === ModelType.ImageGeneration
const threadId = await chatStore.createThread(content.text, {
providerId: activeModel.value.providerId,
modelId: activeModel.value.id,
systemPrompt: isImageGen ? '' : systemPrompt.value,
verbosity: verbosity.value,
enabledMcpTools: chatStore.chatConfig.enabledMcpTools
} as any)
// …rest of handleSend
}
🤖 Prompt for AI Agents
In src/renderer/src/components/NewThread.vue around lines 100-101, handleSend
still includes the default systemPrompt when the Popover hasn't been opened
because ChatConfig clearing runs on mount; update handleSend to detect when
activeModel?.type is an image-generation model and, in that case, prevent
attaching the systemPrompt to the first message (and optionally remove any tools
from the message payload). Concretely: add a conditional in handleSend that
checks the model type (e.g., startsWith('image') or matches your image-model
enum) and if true, omit systemPrompt and strip tools before constructing/sending
the message; otherwise keep the existing behavior. Ensure this change only
affects image models and preserves existing behavior for text models.

Comment on lines 797 to 800
"promptSetting": {
"resetToDefault": "Réinitialiser avec un mot rapide par défaut",
"clear": "Effacer les mots rapides"
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Correct unnatural French phrasing.

Avoid literal “mot rapide”. Use “prompt” consistently with “Prompt système”.

Apply this diff:

   "promptSetting": {
-    "resetToDefault": "Réinitialiser avec un mot rapide par défaut",
-    "clear": "Effacer les mots rapides"
+    "resetToDefault": "Réinitialiser au prompt système par défaut",
+    "clear": "Effacer le prompt"
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"promptSetting": {
"resetToDefault": "Réinitialiser avec un mot rapide par défaut",
"clear": "Effacer les mots rapides"
}
"promptSetting": {
"resetToDefault": "Réinitialiser au prompt système par défaut",
"clear": "Effacer le prompt"
}
🤖 Prompt for AI Agents
In src/renderer/src/i18n/fr-FR/settings.json around lines 797 to 800, the French
uses the literal "mot rapide" which is unnatural; replace those values to use
"prompt" consistently (matching "Prompt système"). Change "resetToDefault" to
"Réinitialiser le prompt par défaut" and "clear" to "Effacer les prompts".

Comment on lines 797 to 800
"promptSetting": {
"resetToDefault": "デフォルトのプロンプトワードにリセットします",
"clear": "迅速な単語を明確にします"
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix unnatural/mistranslated Japanese labels for prompt actions

  • “プロンプトワード/迅速な単語” are incorrect/unnatural. Prefer concise, consistent terms used elsewhere (e.g., “クリア”).

Apply:

-  "promptSetting": {
-    "resetToDefault": "デフォルトのプロンプトワードにリセットします",
-    "clear": "迅速な単語を明確にします"
-  }
+  "promptSetting": {
+    "resetToDefault": "デフォルトのプロンプトにリセットします",
+    "clear": "プロンプトをクリア"
+  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"promptSetting": {
"resetToDefault": "デフォルトのプロンプトワードにリセットします",
"clear": "迅速な単語を明確にします"
}
"promptSetting": {
"resetToDefault": "デフォルトのプロンプトにリセットします",
"clear": "プロンプトをクリア"
}
🤖 Prompt for AI Agents
In src/renderer/src/i18n/ja-JP/settings.json around lines 797 to 800, the
Japanese strings use unnatural/mistranslated terms (“プロンプトワード” and “迅速な単語”);
replace them with concise, natural labels consistent with the app (e.g., change
reset text to "プロンプトをデフォルトにリセットする" or "デフォルトにリセット" and change clear text to
"クリア" or "クリアする") so both entries use standard, consistent phrasing.

Comment on lines 797 to 800
"promptSetting": {
"resetToDefault": "기본 프롬프트 단어로 재설정하십시오",
"clear": "명확한 신속한 단어"
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix awkward/mistranslated labels.

Current strings read like MT (“프롬프트 단어”, “신속한 단어”). Use consistent terminology with existing “시스템 프롬프트”.

Apply this diff:

   "promptSetting": {
-    "resetToDefault": "기본 프롬프트 단어로 재설정하십시오",
-    "clear": "명확한 신속한 단어"
+    "resetToDefault": "기본 시스템 프롬프트로 재설정",
+    "clear": "시스템 프롬프트 지우기"
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"promptSetting": {
"resetToDefault": "기본 프롬프트 단어로 재설정하십시오",
"clear": "명확한 신속한 단어"
}
"promptSetting": {
"resetToDefault": "기본 시스템 프롬프트로 재설정",
"clear": "시스템 프롬프트 지우기"
}
🤖 Prompt for AI Agents
In src/renderer/src/i18n/ko-KR/settings.json around lines 797 to 800, the labels
use awkward/mistranslated phrases ("프롬프트 단어", "신속한 단어"); change them to use the
existing consistent term "시스템 프롬프트" and clearer verbs: set "resetToDefault" to
"기본 시스템 프롬프트로 재설정" and set "clear" to "시스템 프롬프트 지우기" (replace the current values
accordingly).

Comment on lines 796 to 800
},
"promptSetting": {
"resetToDefault": "Сбросить в приглашение по умолчанию слово",
"clear": "Чистые быстрые слова"
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Fix Russian localization phrasing for prompt actions.

Current strings are unnatural/misleading. Suggest clearer RU translations aligned with other locales.

-  "promptSetting": {
-    "resetToDefault": "Сбросить в приглашение по умолчанию слово",
-    "clear": "Чистые быстрые слова"
-  }
+  "promptSetting": {
+    "resetToDefault": "Сбросить к системному запросу по умолчанию",
+    "clear": "Очистить системный запрос"
+  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
},
"promptSetting": {
"resetToDefault": "Сбросить в приглашение по умолчанию слово",
"clear": "Чистые быстрые слова"
}
},
"promptSetting": {
"resetToDefault": "Сбросить к системному запросу по умолчанию",
"clear": "Очистить системный запрос"
}
🤖 Prompt for AI Agents
In src/renderer/src/i18n/ru-RU/settings.json around lines 796-800, the Russian
strings for prompt actions are unnatural; replace the current values with
clearer phrasing: change "resetToDefault" to "Сбросить подсказку по умолчанию"
and change "clear" to "Очистить подсказку" so they align with other locales and
correctly convey "reset to default prompt" and "clear prompt".

Comment on lines 797 to 800
"promptSetting": {
"resetToDefault": "重置為默認提示詞",
"clear": "清空提示詞"
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Use Traditional Chinese term “預設” instead of Simplified “默認”

Align with zh‑TW conventions.

   "promptSetting": {
-    "resetToDefault": "重置為默認提示詞",
+    "resetToDefault": "重置為預設提示詞",
     "clear": "清空提示詞"
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"promptSetting": {
"resetToDefault": "重置為默認提示詞",
"clear": "清空提示詞"
}
"promptSetting": {
"resetToDefault": "重置為預設提示詞",
"clear": "清空提示詞"
}
🤖 Prompt for AI Agents
In src/renderer/src/i18n/zh-TW/settings.json around lines 797 to 800, the
Traditional Chinese translation uses the Simplified Chinese term "默認"; replace
"重置為默認提示詞" with the zh‑TW preferred phrasing "重置為預設提示詞" (or "重置為預設的提示詞" if that
fits project style) so the file uses the correct local term; update only the
string value and keep the JSON key and formatting intact.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/main/presenter/windowPresenter/index.ts (1)

1198-1218: Make position validation multi-display aware and clamp instead of always centering (optional)

validateWindowPosition is only ever called after app.whenReady(), so using Electron’s screen API here is safe. You can apply the following diff to improve multi-monitor support:

   private validateWindowPosition(
     x: number,
     width: number,
     y: number,
     height: number
   ): { x: number; y: number } {
-    const primaryDisplay = screen.getPrimaryDisplay()
-    const { workArea } = primaryDisplay
-    const isXValid = x >= workArea.x && x + width <= workArea.x + workArea.width
-    const isYValid = y >= workArea.y && y + height <= workArea.y + workArea.height
-    if (!isXValid || !isYValid) {
-      console.log(
-        `Window position out of bounds (x: ${x}, y: ${y}, width: ${width}, height: ${height}), centering window`
-      )
-      return {
-        x: workArea.x + Math.max(0, (workArea.width - width) / 2),
-        y: workArea.y + Math.max(0, (workArea.height - height) / 2)
-      }
-    }
-    return { x, y }
+    // Choose the display that best matches the proposed rect; fall back to primary.
+    const targetDisplay =
+      screen.getDisplayMatching({ x, y, width, height }) ?? screen.getPrimaryDisplay()
+    const wa = targetDisplay.workArea
+
+    const rectIntersects =
+      x < wa.x + wa.width && x + width > wa.x && y < wa.y + wa.height && y + height > wa.y
+
+    // If entirely off-screen (e.g., prior monitor missing), center on nearest display.
+    if (!rectIntersects) {
+      console.log(
+        `Window position out of bounds (x: ${x}, y: ${y}, w: ${width}, h: ${height}), centering on nearest display`
+      )
+      const centeredWidth = Math.min(width, wa.width)
+      const centeredHeight = Math.min(height, wa.height)
+      return {
+        x: wa.x + Math.max(0, Math.floor((wa.width - centeredWidth) / 2)),
+        y: wa.y + Math.max(0, Math.floor((wa.height - centeredHeight) / 2))
+      }
+    }
+
+    // Clamp within workArea so the window is fully visible.
+    const maxX = wa.x + wa.width - Math.min(width, wa.width)
+    const maxY = wa.y + wa.height - Math.min(height, wa.height)
+    return {
+      x: Math.min(Math.max(x, wa.x), maxX),
+      y: Math.min(Math.max(y, wa.y), maxY)
+    }
   }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between e2770ca and 1c5205f.

📒 Files selected for processing (1)
  • src/main/presenter/windowPresenter/index.ts (3 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development-setup.mdc)

**/*.{js,jsx,ts,tsx}: 使用 OxLint 进行代码检查
Log和注释使用英文书写

Files:

  • src/main/presenter/windowPresenter/index.ts
src/{main,renderer}/**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/electron-best-practices.mdc)

src/{main,renderer}/**/*.ts: Use context isolation for improved security
Implement proper inter-process communication (IPC) patterns
Optimize application startup time with lazy loading
Implement proper error handling and logging for debugging

Files:

  • src/main/presenter/windowPresenter/index.ts
src/main/**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/electron-best-practices.mdc)

Use Electron's built-in APIs for file system and native dialogs

From main to renderer, broadcast events via EventBus using mainWindow.webContents.send()

Files:

  • src/main/presenter/windowPresenter/index.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/error-logging.mdc)

**/*.{ts,tsx}: 始终使用 try-catch 处理可能的错误
提供有意义的错误信息
记录详细的错误日志
优雅降级处理
日志应包含时间戳、日志级别、错误代码、错误描述、堆栈跟踪(如适用)、相关上下文信息
日志级别应包括 ERROR、WARN、INFO、DEBUG
不要吞掉错误
提供用户友好的错误信息
实现错误重试机制
避免记录敏感信息
使用结构化日志
设置适当的日志级别

Enable and adhere to strict TypeScript type checking

Files:

  • src/main/presenter/windowPresenter/index.ts
src/main/**/*.{ts,js,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)

主进程代码放在 src/main

Files:

  • src/main/presenter/windowPresenter/index.ts
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

Use English for all logs and comments

Files:

  • src/main/presenter/windowPresenter/index.ts
src/main/presenter/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Maintain one presenter per functional domain in src/main/presenter/

Files:

  • src/main/presenter/windowPresenter/index.ts
🧠 Learnings (3)
📚 Learning: 2025-07-21T01:45:54.229Z
Learnt from: CR
PR: ThinkInAIXYZ/deepchat#0
File: .cursor/rules/electron-best-practices.mdc:0-0
Timestamp: 2025-07-21T01:45:54.229Z
Learning: Applies to src/main/**/*.ts : Use Electron's built-in APIs for file system and native dialogs

Applied to files:

  • src/main/presenter/windowPresenter/index.ts
📚 Learning: 2025-07-21T01:45:54.229Z
Learnt from: CR
PR: ThinkInAIXYZ/deepchat#0
File: .cursor/rules/electron-best-practices.mdc:0-0
Timestamp: 2025-07-21T01:45:54.229Z
Learning: Applies to src/renderer/src/composables/usePresenter.ts : The IPC in the renderer process is implemented in usePresenter.ts, allowing direct calls to the presenter-related interfaces exposed by the main process

Applied to files:

  • src/main/presenter/windowPresenter/index.ts
📚 Learning: 2025-07-21T01:45:54.229Z
Learnt from: CR
PR: ThinkInAIXYZ/deepchat#0
File: .cursor/rules/electron-best-practices.mdc:0-0
Timestamp: 2025-07-21T01:45:54.229Z
Learning: Applies to src/main/presenter/index.ts : The IPC messages from the main process to notify the view mainly rely on the EventBus index.ts to listen for events that need to be notified and then send them to the renderer through the mainWindow

Applied to files:

  • src/main/presenter/windowPresenter/index.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build-check (x64)
🔇 Additional comments (1)
src/main/presenter/windowPresenter/index.ts (1)

2-2: LGTM: import of screen is appropriate for position validation.

Comment on lines +578 to +596
// 计算初始位置,确保窗口完全在屏幕范围内
const initialX =
options?.x !== undefined
? options.x
: this.validateWindowPosition(
shellWindowState.x,
shellWindowState.width,
shellWindowState.y,
shellWindowState.height
).x
let initialY =
options?.y !== undefined
? options?.y
: this.validateWindowPosition(
shellWindowState.x,
shellWindowState.width,
shellWindowState.y,
shellWindowState.height
).y
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Validate once and include option overrides before validation.

Calling validateWindowPosition twice and not validating user-provided x/y independently can place windows off-screen when only one axis is overridden. Compute candidateX/Y first, then validate once.

Apply this diff:

-    // 计算初始位置,确保窗口完全在屏幕范围内
-    const initialX =
-      options?.x !== undefined
-        ? options.x
-        : this.validateWindowPosition(
-            shellWindowState.x,
-            shellWindowState.width,
-            shellWindowState.y,
-            shellWindowState.height
-          ).x
-    let initialY =
-      options?.y !== undefined
-        ? options?.y
-        : this.validateWindowPosition(
-            shellWindowState.x,
-            shellWindowState.width,
-            shellWindowState.y,
-            shellWindowState.height
-          ).y
+    // 计算初始位置,确保窗口完全在屏幕范围内(一次校验即可)
+    const candidateX = options?.x ?? shellWindowState.x
+    const candidateY = options?.y ?? shellWindowState.y
+    const { x: initialX, y: initialY } = this.validateWindowPosition(
+      candidateX,
+      shellWindowState.width,
+      candidateY,
+      shellWindowState.height
+    )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// 计算初始位置,确保窗口完全在屏幕范围内
const initialX =
options?.x !== undefined
? options.x
: this.validateWindowPosition(
shellWindowState.x,
shellWindowState.width,
shellWindowState.y,
shellWindowState.height
).x
let initialY =
options?.y !== undefined
? options?.y
: this.validateWindowPosition(
shellWindowState.x,
shellWindowState.width,
shellWindowState.y,
shellWindowState.height
).y
// 计算初始位置,确保窗口完全在屏幕范围内(一次校验即可)
const candidateX = options?.x ?? shellWindowState.x
const candidateY = options?.y ?? shellWindowState.y
const { x: initialX, y: initialY } = this.validateWindowPosition(
candidateX,
shellWindowState.width,
candidateY,
shellWindowState.height
)
🤖 Prompt for AI Agents
In src/main/presenter/windowPresenter/index.ts around lines 578 to 596, the code
calls validateWindowPosition twice and fails to validate user-provided x/y
independently; compute candidateX and candidateY first using options.x !==
undefined ? options.x : shellWindowState.x and options.y !== undefined ?
options.y : shellWindowState.y, then call this.validateWindowPosition once with
candidateX, shellWindowState.width, candidateY, shellWindowState.height and use
the returned .x and .y as initialX and initialY so single-axis overrides are
validated correctly.

@zerob13 zerob13 merged commit c029040 into dev Aug 30, 2025
2 checks passed
@zerob13 zerob13 deleted the chore/ux-in-settings branch September 21, 2025 15:15
This was referenced Oct 12, 2025
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.

3 participants