Skip to content

Conversation

@yyhhyyyyyy
Copy link
Collaborator

@yyhhyyyyyy yyhhyyyyyy commented Sep 8, 2025

implement separated system and custom prompt management

CleanShot.2025-09-08.at.09.43.45.mp4

Summary by CodeRabbit

  • New Features

    • Full System Prompts management: create, edit, delete, preview, set default, reset-to-default, and per-item actions with confirmations and toasts. Prompts are persisted and one can mark a default.
  • API / Store

    • Settings and configuration APIs added to manage system prompts (CRUD + default prompt ID), exposed to renderer components.
  • i18n

    • Updated prompt label and added extensive translations/keys for system prompts across multiple locales.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 8, 2025

Walkthrough

Adds a persistent SystemPrompt entity and store, implements CRUD and default-id APIs in the ConfigPresenter and presenter types, exposes those APIs via the renderer settings store, replaces the PromptSetting UI with a system-prompts manager, and expands/renames promptSetting i18n keys across locales.

Changes

Cohort / File(s) Summary
Config presenter & store + types
src/main/presenter/configPresenter/index.ts, src/shared/types/presenters/legacy.presenters.d.ts
Add SystemPrompt interface and systemPromptsStore; implement getSystemPrompts, setSystemPrompts, addSystemPrompt, updateSystemPrompt, deleteSystemPrompt, setDefaultSystemPromptId, getDefaultSystemPromptId; getDefaultSystemPrompt now prefers store with legacy fallback.
Renderer settings store
src/renderer/src/stores/settings.ts
Add async wrappers that delegate system-prompts CRUD and default-id get/set to presenter; expose these methods in the settings store public API.
Settings UI (PromptSetting)
src/renderer/src/components/settings/PromptSetting.vue
Replace single default prompt editor with full system-prompts management UI (list/select/add/edit/delete/reset); add form, sheet, toasts, confirmations, migration/safety logic, and sync with settings store.
i18n — promptSetting locales
src/renderer/src/i18n/*/promptSetting.json
(en-US, fa-IR, fr-FR, ja-JP, ko-KR, ru-RU, zh-CN, zh-HK, zh-TW)
Rename contentpromptContent where applicable; add many new keys for system-prompts management and delete confirmations; minor JSON formatting adjustments (trailing commas).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant UI as PromptSetting.vue
  participant Store as settingsStore
  participant Presenter as ConfigPresenter
  participant DB as systemPromptsStore

  User->>UI: Open System Prompts settings
  UI->>Store: getSystemPrompts(), getDefaultSystemPromptId()
  Store->>Presenter: delegate calls
  Presenter->>DB: read prompts & default id
  DB-->>Presenter: prompts, default id
  Presenter-->>Store: return prompts & default id
  Store-->>UI: render list & selection

  rect rgb(231,245,255)
  note right of UI: create / edit / delete / set default
  UI->>Store: addSystemPrompt/updateSystemPrompt/deleteSystemPrompt/setDefaultSystemPromptId
  Store->>Presenter: delegate
  Presenter->>DB: persist changes
  DB-->>Presenter: ack
  Presenter-->>Store: ok
  Store-->>UI: refresh & show toast
  end
Loading
sequenceDiagram
  autonumber
  participant Consumer
  participant Presenter as ConfigPresenter
  participant DB as systemPromptsStore
  note over Consumer,Presenter: Resolve default system prompt content
  Consumer->>Presenter: getDefaultSystemPrompt()
  Presenter->>DB: fetch default SystemPrompt
  alt default exists in store
    DB-->>Presenter: default prompt
    Presenter-->>Consumer: return default.content
  else fallback to legacy
    Presenter-->>Consumer: return legacy DEFAULT_SYSTEM_PROMPT
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • zerob13
  • deepinfect

Poem

In my burrow I code and I chew,
New prompts I plant like morning dew.
One default carrot, others to share,
CRUD hops and toasts fill the air.
Across languages I twitch my nose—settings grow, off we go! 🥕🐇


📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 36debf9 and 9ee3319.

📒 Files selected for processing (1)
  • src/main/presenter/configPresenter/index.ts (6 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/presenter/configPresenter/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)
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/separate-system-custom-prompts

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@yyhhyyyyyy yyhhyyyyyy changed the title Feat/separate system custom prompts feat: implement separated system and custom prompt management Sep 8, 2025
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: 6

Caution

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

⚠️ Outside diff range comments (6)
src/shared/types/presenters/legacy.presenters.d.ts (1)

1071-1071: Typo breaks typing: unknow → unknown

This is a compile-time error in MCPServerConfig.

-  env: Record<string, unknow>
+  env: Record<string, unknown>
src/renderer/src/components/settings/PromptSetting.vue (3)

1185-1189: Use nanoid for stable IDs; avoid deprecated substr

Current ID generation uses Math.random().substr which is deprecated and less robust. You already import nanoid.

-              if (!importedPrompt.id) {
-                // 如果导入的提示词没有ID,生成一个新的ID
-                importedPrompt.id = timestamp.toString() + Math.random().toString(36).substr(2, 9)
-              }
+              if (!importedPrompt.id) {
+                // 如果导入的提示词没有ID,生成一个新的ID
+                importedPrompt.id = nanoid(12)
+              }

1233-1239: All UI strings must be i18n — replace hardcoded Chinese error text

Replace “错误: …” and “文件读取失败” with i18n keys per repo rules.

-          toast({
-            title: t('promptSetting.importFailed'),
-            description: `错误: ${errorMessage}`,
-            variant: 'destructive'
-          })
+          toast({
+            title: t('promptSetting.importFailed'),
+            description: t('common.errorWithDetail', { detail: errorMessage }),
+            variant: 'destructive'
+          })
@@
-        toast({
-          title: t('promptSetting.importFailed'),
-          description: '文件读取失败',
-          variant: 'destructive'
-        })
+        toast({
+          title: t('promptSetting.importFailed'),
+          description: t('promptSetting.fileReadFailed'),
+          variant: 'destructive'
+        })

Note: Please ensure the keys common.errorWithDetail and promptSetting.fileReadFailed exist in all locales.

Also applies to: 1242-1248


589-596: Localize “unknown” MIME label

Avoid hardcoded English in UI.

-                          >{{ file.type || 'unknown' }}</span
+                          >{{ file.type || t('common.unknown') }}</span
src/main/presenter/configPresenter/index.ts (1)

1211-1213: Sync legacy setter with the new store to avoid split sources of truth

setDefaultSystemPrompt currently updates only app-settings. Also update the “default” system prompt entry.

   // 设置默认系统提示词
   async setDefaultSystemPrompt(prompt: string): Promise<void> {
-    this.setSetting('default_system_prompt', prompt)
+    this.setSetting('default_system_prompt', prompt)
+    // Keep system_prompts in sync
+    const prompts = (await this.getSystemPrompts()) as SystemPrompt[]
+    const now = Date.now()
+    const idx = prompts.findIndex((p) => p.id === 'default')
+    if (idx !== -1) {
+      prompts[idx] = { ...prompts[idx], content: prompt, isDefault: true, updatedAt: now }
+    } else {
+      prompts.push({
+        id: 'default',
+        name: 'DeepChat',
+        content: prompt,
+        isDefault: true,
+        createdAt: now,
+        updatedAt: now
+      })
+    }
+    await this.setSystemPrompts(prompts)
   }
src/renderer/src/stores/settings.ts (1)

3-3: Import SystemPrompt type for strict typing

Use precise types per guidelines.

-import { type LLM_PROVIDER, type RENDERER_MODEL_META } from '@shared/presenter'
+import { type LLM_PROVIDER, type RENDERER_MODEL_META, type SystemPrompt } from '@shared/presenter'
🧹 Nitpick comments (21)
src/renderer/src/i18n/fa-IR/promptSetting.json (6)

73-75: Wording consistency: use “ویرایش … انتخاب‌شده”

Align description phrasing with the “ویرایش …” title and use half‑space in “انتخاب‌شده”.

-  "editSystemPromptDesc": "تغییر دستورکار سامانه انتخاب شده",
+  "editSystemPromptDesc": "ویرایش دستورکار سامانه انتخاب‌شده",
-  "systemPromptDescription": "دستورکار سامانه انتخاب شده به عنوان پیش‌فرض برای گفت‌وگوهای جدید استفاده خواهد شد",
+  "systemPromptDescription": "دستورکار سامانه انتخاب‌شده به عنوان پیش‌فرض برای گفت‌وگوهای جدید استفاده خواهد شد",

81-81: Typography: add half‑space in “به‌طور”

Minor Persian typography polish.

-  "systemPromptAddedAndSwitched": "دستورکار سامانه اضافه شد و به طور خودکار به عنوان پیش‌فرض تنظیم شد",
+  "systemPromptAddedAndSwitched": "دستورکار سامانه اضافه شد و به‌طور خودکار به عنوان پیش‌فرض تنظیم شد",

86-86: Clarify autosave tip

More natural phrasing; keeps your existing “نگه‌داری” terminology.

-  "systemPromptEditTip": "پس از ویرایش، هنگام از دست دادن فوکوس خودکار نگه‌داری می‌شود",
+  "systemPromptEditTip": "پس از ویرایش، با خروج فوکوس به‌طور خودکار نگه‌داری می‌شود",

90-91: Unify delete terminology with existing keys

Elsewhere this file uses “پاک” (e.g., confirmDelete). Consider aligning these two for consistency.

-  "confirmDeleteSystemPrompt": "آیا مطمئن هستید که می‌خواهید دستورکار سامانه \"{name}\" را حذف کنید؟",
-  "confirmDeleteSystemPromptDescription": "این عمل قابل بازگشت نیست. دستورکار سامانه به طور دائم حذف خواهد شد."
+  "confirmDeleteSystemPrompt": "آیا مطمئن هستید که می‌خواهید دستورکار سامانه «{name}» را پاک کنید؟",
+  "confirmDeleteSystemPromptDescription": "این عمل قابل بازگشت نیست. دستورکار سامانه به‌طور دائم پاک خواهد شد."

77-77: Label clarity

“promptContent” reads clearer as “محتوای دستورکار”, parallel to placeholders.

-  "promptContent": "دستورکار",
+  "promptContent": "محتوای دستورکار",

66-66: Remove deprecated saveDefaultPromptFailed from all locales
The legacy key now sits alongside systemPromptSaveFailed in every promptSetting.json; delete it everywhere to prevent duplication and drift.

-  "saveDefaultPromptFailed": "<translation>",
src/renderer/src/i18n/fr-FR/promptSetting.json (2)

11-11: Label wording consistency with placeholder

To align with Line 12’s placeholder (“contenu du prompt”), consider using the more explicit label below.

-  "promptContent": "Prompt",
+  "promptContent": "Contenu du prompt",

69-91: Unify terminology and improve phrasing in fr-FR/promptSetting.json

Translation keys are in sync with en-US locale.

-  "systemPromptAddedAndSwitched": "Prompt système ajouté et automatiquement défini par défaut",
+  "systemPromptAddedAndSwitched": "Prompt système ajouté et automatiquement défini comme par défaut",
-  "systemPromptEditTip": "Sauvegarde automatique lorsque le focus est perdu après modification",
+  "systemPromptEditTip": "Enregistrement automatique lorsque le focus est perdu après modification",
-  "resetToDefault": "Rétablir par défaut",
+  "resetToDefault": "Rétablir le contenu par défaut",
-  "resetToDefaultSuccess": "Rétabli au contenu par défaut avec succès",
+  "resetToDefaultSuccess": "Contenu par défaut rétabli avec succès",
-  "resetToDefaultFailed": "Échec de la réinitialisation par défaut"
+  "resetToDefaultFailed": "Échec de la réinitialisation aux valeurs par défaut"
src/renderer/src/i18n/zh-HK/promptSetting.json (2)

62-62: Use Traditional terms: 默認/創建/設置 → 預設/建立/設定

Align with zh-HK locale usage.

Apply:

-  "defaultSystemPromptDescription": "此提示詞將作為所有新對話的默認系統提示詞,您可以在創建對話時修改,注意本設置修改後會在下一次創建新會話時生效。",
+  "defaultSystemPromptDescription": "此提示詞將作為所有新對話的預設系統提示詞,您可以在建立對話時修改,注意本設定修改後會在下一次建立新會話時生效。",

21-22: HK wording polish: 導出/導入、字符

Prefer common HK terms.

-  "export": "導出",
-  "import": "導入",
+  "export": "匯出",
+  "import": "匯入",
-  "characters": "字符",
+  "characters": "字元",

Also applies to: 37-37

src/renderer/src/i18n/zh-TW/promptSetting.json (2)

62-62: Use TW terms: 默認/創建/設置 → 預設/建立/設定

Improve locale accuracy.

-  "defaultSystemPromptDescription": "此提示詞將作為所有新對話的默認系統提示詞,您可以在創建對話時修改,注意本設置修改後會在下一次創建新會話時生效。",
+  "defaultSystemPromptDescription": "此提示詞將作為所有新對話的預設系統提示詞,您可以在建立對話時修改,注意本設定修改後會在下一次建立新會話時生效。",

21-22: TW wording: 導出/導入、字符

Use common TW phrasing.

-  "export": "導出",
-  "import": "導入",
+  "export": "匯出",
+  "import": "匯入",
-  "characters": "字符",
+  "characters": "字元",

Also applies to: 37-37

src/renderer/src/i18n/ja-JP/promptSetting.json (1)

20-20: Minor JP UX copy tweaks

Button/label tone.

-  "showLess": "閉じる",
+  "showLess": "折りたたむ",
-  "addParameter": "パラメーターを追加します",
+  "addParameter": "パラメーターを追加",

Also applies to: 29-29

src/shared/types/presenters/legacy.presenters.d.ts (1)

76-83: SystemPrompt shape: clarify defaults and timestamps

Avoid dual sources of truth for default and document timestamp units.

 export interface SystemPrompt {
   id: string
   name: string
   content: string
-  isDefault?: boolean
-  createdAt?: number
-  updatedAt?: number
+  /** Derived; source of truth is getDefaultSystemPromptId() */
+  isDefault?: boolean
+  /** Unix epoch milliseconds */
+  createdAt?: number
+  /** Unix epoch milliseconds */
+  updatedAt?: number
 }
src/renderer/src/components/settings/PromptSetting.vue (5)

823-826: Make selection robust when stored default ID is missing

If the stored ID doesn’t exist (e.g., prompt deleted externally), fall back to the built-in default or the first item to keep UI consistent.

-const updateCurrentSystemPrompt = () => {
-  currentSystemPrompt.value =
-    systemPrompts.value.find((p) => p.id === selectedSystemPromptId.value) || null
-}
+const updateCurrentSystemPrompt = () => {
+  const found = systemPrompts.value.find((p) => p.id === selectedSystemPromptId.value)
+  if (!found && systemPrompts.value.length) {
+    const fallbackId =
+      systemPrompts.value.find((p) => p.id === 'default')?.id || systemPrompts.value[0].id
+    selectedSystemPromptId.value = fallbackId
+    currentSystemPrompt.value = systemPrompts.value.find((p) => p.id === fallbackId) || null
+  } else {
+    currentSystemPrompt.value = found || null
+  }
+}

905-931: Skip no-op saves to reduce unnecessary writes and toasts

Don’t call update if content hasn’t changed.

 const saveCurrentSystemPrompt = async () => {
   if (!currentSystemPrompt.value) return
 
   try {
+    const existing = systemPrompts.value.find((p) => p.id === currentSystemPrompt.value!.id)
+    if (existing && existing.content === currentSystemPrompt.value.content) {
+      return
+    }
     await settingsStore.updateSystemPrompt(currentSystemPrompt.value.id, {
       content: currentSystemPrompt.value.content,
       updatedAt: Date.now()
     })

933-966: Source the “factory default” content from a single place

Hardcoding the default text here risks divergence from the main-process constant and has a minor grammar issue (“languages.Always”). Provide it from the presenter (e.g., a getBuiltinDefaultSystemPrompt API), or ensure the string is shared.

Would you like me to add a ConfigPresenter.getBuiltinDefaultSystemPrompt() and wire it here?


1341-1346: Localize file size units

Format units via i18n or Intl API to respect locale; current constants are hardcoded.

Example:

-  const sizes = ['Bytes', 'KB', 'MB', 'GB']
+  const sizes = [t('units.bytes'), t('units.kb'), t('units.mb'), t('units.gb')]

Add units.* keys across locales.


1-370: Comments/logs language consistency

Several comments in template/script are Chinese. Guidelines require English for logs/comments. Consider aligning in future edits.

Also applies to: 645-1368

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

35-38: Minor grammar fix in DEFAULT_SYSTEM_PROMPT

Add missing space after the period.

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

1233-1271: Broadcast system-prompt changes via events

Consider emitting CONFIG_EVENTS (e.g., SYSTEM_PROMPTS_UPDATED, DEFAULT_SYSTEM_PROMPT_CHANGED) so all windows stay in sync without manual reloads.

I can add events here and wire listeners in the renderer store if you want.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d77041f and 36debf9.

📒 Files selected for processing (13)
  • src/main/presenter/configPresenter/index.ts (5 hunks)
  • src/renderer/src/components/settings/PromptSetting.vue (6 hunks)
  • src/renderer/src/i18n/en-US/promptSetting.json (3 hunks)
  • src/renderer/src/i18n/fa-IR/promptSetting.json (1 hunks)
  • src/renderer/src/i18n/fr-FR/promptSetting.json (3 hunks)
  • src/renderer/src/i18n/ja-JP/promptSetting.json (1 hunks)
  • src/renderer/src/i18n/ko-KR/promptSetting.json (1 hunks)
  • src/renderer/src/i18n/ru-RU/promptSetting.json (1 hunks)
  • src/renderer/src/i18n/zh-CN/promptSetting.json (3 hunks)
  • src/renderer/src/i18n/zh-HK/promptSetting.json (1 hunks)
  • src/renderer/src/i18n/zh-TW/promptSetting.json (1 hunks)
  • src/renderer/src/stores/settings.ts (2 hunks)
  • src/shared/types/presenters/legacy.presenters.d.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (19)
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-TW/promptSetting.json
  • src/renderer/src/i18n/zh-CN/promptSetting.json
  • src/renderer/src/i18n/zh-HK/promptSetting.json
  • src/renderer/src/stores/settings.ts
  • src/renderer/src/i18n/en-US/promptSetting.json
  • src/renderer/src/components/settings/PromptSetting.vue
  • src/renderer/src/i18n/ja-JP/promptSetting.json
  • src/renderer/src/i18n/ru-RU/promptSetting.json
  • src/renderer/src/i18n/ko-KR/promptSetting.json
  • src/renderer/src/i18n/fr-FR/promptSetting.json
  • src/renderer/src/i18n/fa-IR/promptSetting.json
**/*.{js,jsx,ts,tsx}

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

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

Files:

  • src/renderer/src/stores/settings.ts
  • src/shared/types/presenters/legacy.presenters.d.ts
  • src/main/presenter/configPresenter/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/renderer/src/stores/settings.ts
  • src/main/presenter/configPresenter/index.ts
**/*.{ts,tsx}

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

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

Files:

  • src/renderer/src/stores/settings.ts
  • src/shared/types/presenters/legacy.presenters.d.ts
  • src/main/presenter/configPresenter/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/renderer/**/*.{vue,ts,js,tsx,jsx}

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

渲染进程代码放在 src/renderer

Files:

  • src/renderer/src/stores/settings.ts
  • src/renderer/src/components/settings/PromptSetting.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/stores/settings.ts
  • src/renderer/src/components/settings/PromptSetting.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/stores/settings.ts
  • src/renderer/src/components/settings/PromptSetting.vue
src/renderer/**/*.{vue,ts}

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

Implement lazy loading for routes and components.

Files:

  • src/renderer/src/stores/settings.ts
  • src/renderer/src/components/settings/PromptSetting.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.

Use Pinia for frontend state management (do not introduce alternative state libraries)

Files:

  • src/renderer/src/stores/settings.ts
  • src/renderer/src/components/settings/PromptSetting.vue
**/*.{ts,tsx,js,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

Use English for all logs and comments

Files:

  • src/renderer/src/stores/settings.ts
  • src/shared/types/presenters/legacy.presenters.d.ts
  • src/main/presenter/configPresenter/index.ts
  • src/renderer/src/components/settings/PromptSetting.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

Enable and adhere to strict TypeScript typing (avoid implicit any, prefer precise types)

Files:

  • src/renderer/src/stores/settings.ts
  • src/shared/types/presenters/legacy.presenters.d.ts
  • src/main/presenter/configPresenter/index.ts
  • src/renderer/src/components/settings/PromptSetting.vue
src/shared/**/*.{ts,tsx,d.ts}

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

共享类型定义放在 shared 目录

Files:

  • src/shared/types/presenters/legacy.presenters.d.ts
src/shared/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Place shared types, utilities, constants, and IPC contract definitions under src/shared/

Files:

  • src/shared/types/presenters/legacy.presenters.d.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

Files:

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

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

主进程代码放在 src/main

Files:

  • src/main/presenter/configPresenter/index.ts
src/renderer/src/**/*.vue

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

Use scoped styles to prevent CSS conflicts between components

Files:

  • src/renderer/src/components/settings/PromptSetting.vue
src/renderer/{src,shell,floating}/**/*.vue

📄 CodeRabbit inference engine (CLAUDE.md)

src/renderer/{src,shell,floating}/**/*.vue: Use Vue 3 Composition API for all components
All user-facing strings must use i18n keys via vue-i18n (no hard-coded UI strings)
Use Tailwind CSS utilities and ensure styles are scoped in Vue components

Files:

  • src/renderer/src/components/settings/PromptSetting.vue
src/renderer/src/components/**/*

📄 CodeRabbit inference engine (CLAUDE.md)

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

Files:

  • src/renderer/src/components/settings/PromptSetting.vue
🧠 Learnings (7)
📚 Learning: 2025-09-06T03:07:23.794Z
Learnt from: CR
PR: ThinkInAIXYZ/deepchat#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-06T03:07:23.794Z
Learning: Applies to src/main/presenter/configPresenter/providers.ts : Add provider configuration entries in src/main/presenter/configPresenter/providers.ts

Applied to files:

  • src/main/presenter/configPresenter/index.ts
📚 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} : Leverage ref, reactive, and computed for reactive state management.

Applied to files:

  • src/renderer/src/components/settings/PromptSetting.vue
📚 Learning: 2025-07-21T01:47:28.817Z
Learnt from: CR
PR: ThinkInAIXYZ/deepchat#0
File: .cursor/rules/vue-best-practices.mdc:0-0
Timestamp: 2025-07-21T01:47:28.817Z
Learning: Applies to src/renderer/src/**/*.{vue,ts,tsx,js,jsx} : Leverage Vue's built-in reactivity system for efficient data handling

Applied to files:

  • src/renderer/src/components/settings/PromptSetting.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/settings/PromptSetting.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} : Use <script setup> syntax for concise component definitions.

Applied to files:

  • src/renderer/src/components/settings/PromptSetting.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/settings/PromptSetting.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/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/promptSetting.json
🧬 Code graph analysis (2)
src/renderer/src/stores/settings.ts (1)
src/main/presenter/configPresenter/index.ts (7)
  • getSystemPrompts (1225-1231)
  • setSystemPrompts (1233-1235)
  • addSystemPrompt (1237-1241)
  • updateSystemPrompt (1243-1250)
  • deleteSystemPrompt (1252-1256)
  • setDefaultSystemPromptId (1258-1266)
  • getDefaultSystemPromptId (1268-1272)
src/main/presenter/configPresenter/index.ts (1)
src/shared/types/presenters/legacy.presenters.d.ts (1)
  • SystemPrompt (76-83)
🔇 Additional comments (13)
src/renderer/src/i18n/fr-FR/promptSetting.json (1)

49-50: Deletion-confirmation strings look good

Wording, placeholders, and punctuation are correct and consistent with the rest of the file.

src/renderer/src/i18n/zh-HK/promptSetting.json (1)

66-91: New system/custom prompts keys: parity looks good

Keys and placeholders are consistent with en-US. No JSON issues spotted.

src/renderer/src/i18n/ru-RU/promptSetting.json (1)

66-91: System/custom prompts keys added correctly

Placeholders ({name}) and wording look consistent. No structural issues.

src/renderer/src/i18n/zh-TW/promptSetting.json (1)

66-91: System/custom prompts keys OK

Parity with en-US preserved.

src/renderer/src/i18n/ja-JP/promptSetting.json (1)

66-91: System/custom prompts keys added—looks good

Keys, placeholders, and punctuation are consistent. OK.

src/renderer/src/i18n/ko-KR/promptSetting.json (1)

66-91: System/custom prompts keys added—OK

Placeholders are intact; translations read naturally.

src/renderer/src/i18n/zh-CN/promptSetting.json (3)

49-50: Add system-prompt delete confirmations: OK

Copies match style of existing delete prompts.


69-91: Bulk system/custom prompts keys: OK

Parity with en-US confirmed; placeholders consistent.


11-11: content → promptContent rename: OK

No remaining references to promptSetting.content in the codebase after renaming.

src/renderer/src/i18n/en-US/promptSetting.json (3)

49-50: Add system-prompt delete confirmations: OK

Wording consistent with existing delete strings.


11-11: Approve rename of contentpromptContent
No stale promptSetting.content references found in the repository; safe to merge.


69-91: Keep “preview” in promptSetting.json; no shared usage detected
grep across all i18n namespaces shows “preview” only in promptSetting.json for each locale—no need to move it to common.json.

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

1201-1208: Confirm migration covers all legacy default-system-prompt APIs
Legacy methods setDefaultSystemPrompt, resetToDefaultPrompt, and clearSystemPrompt are still referenced in:

  • src/shared/types/presenters/legacy.presenters.d.ts
  • src/renderer/src/stores/settings.ts (lines ~1629, 1634, 1639)
  • src/main/presenter/configPresenter/index.ts (lines ~1211, 1216, 1221)
    Ensure your migration logic preserves any user-defined default_system_prompt for all these code paths.

Comment on lines +143 to +157
this.systemPromptsStore = new ElectronStore<{ prompts: SystemPrompt[] }>({
name: 'system_prompts',
defaults: {
prompts: [
{
id: 'default',
name: 'DeepChat',
content: DEFAULT_SYSTEM_PROMPT,
isDefault: true,
createdAt: Date.now(),
updatedAt: Date.now()
}
]
}
})
Copy link
Contributor

@coderabbitai coderabbitai bot Sep 8, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue

Migrate legacy default_system_prompt into the new system_prompts store

Without migration, existing users’ customized default prompt is ignored after upgrade (getDefaultSystemPrompt now prefers systemPrompts). Migrate on startup.

     this.systemPromptsStore = new ElectronStore<{ prompts: SystemPrompt[] }>({
       name: 'system_prompts',
       defaults: {
         prompts: [
           {
             id: 'default',
             name: 'DeepChat',
             content: DEFAULT_SYSTEM_PROMPT,
             isDefault: true,
             createdAt: Date.now(),
             updatedAt: Date.now()
           }
         ]
       }
     })
+
+    // Migrate legacy default_system_prompt into system_prompts (one-time)
+    try {
+      const legacyDefault = this.store.get('default_system_prompt')
+      if (
+        typeof legacyDefault === 'string' &&
+        legacyDefault.trim() &&
+        legacyDefault.trim() !== DEFAULT_SYSTEM_PROMPT.trim()
+      ) {
+        const prompts = (this.systemPromptsStore.get('prompts') || []) as SystemPrompt[]
+        const now = Date.now()
+        const idx = prompts.findIndex((p) => p.id === 'default')
+        if (idx !== -1) {
+          prompts[idx] = {
+            ...prompts[idx],
+            content: legacyDefault,
+            isDefault: true,
+            updatedAt: now
+          }
+        } else {
+          prompts.push({
+            id: 'default',
+            name: 'DeepChat',
+            content: legacyDefault,
+            isDefault: true,
+            createdAt: now,
+            updatedAt: now
+          })
+        }
+        this.systemPromptsStore.set('prompts', prompts)
+      }
+    } catch (e) {
+      console.warn('Failed to migrate legacy default_system_prompt:', e)
+    }
📝 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
this.systemPromptsStore = new ElectronStore<{ prompts: SystemPrompt[] }>({
name: 'system_prompts',
defaults: {
prompts: [
{
id: 'default',
name: 'DeepChat',
content: DEFAULT_SYSTEM_PROMPT,
isDefault: true,
createdAt: Date.now(),
updatedAt: Date.now()
}
]
}
})
this.systemPromptsStore = new ElectronStore<{ prompts: SystemPrompt[] }>({
name: 'system_prompts',
defaults: {
prompts: [
{
id: 'default',
name: 'DeepChat',
content: DEFAULT_SYSTEM_PROMPT,
isDefault: true,
createdAt: Date.now(),
updatedAt: Date.now()
}
]
}
})
// Migrate legacy default_system_prompt into system_prompts (one-time)
try {
const legacyDefault = this.store.get('default_system_prompt')
if (
typeof legacyDefault === 'string' &&
legacyDefault.trim() &&
legacyDefault.trim() !== DEFAULT_SYSTEM_PROMPT.trim()
) {
const prompts = (this.systemPromptsStore.get('prompts') || []) as SystemPrompt[]
const now = Date.now()
const idx = prompts.findIndex((p) => p.id === 'default')
if (idx !== -1) {
prompts[idx] = {
...prompts[idx],
content: legacyDefault,
isDefault: true,
updatedAt: now
}
} else {
prompts.push({
id: 'default',
name: 'DeepChat',
content: legacyDefault,
isDefault: true,
createdAt: now,
updatedAt: now
})
}
this.systemPromptsStore.set('prompts', prompts)
}
} catch (e) {
console.warn('Failed to migrate legacy default_system_prompt:', e)
}
🤖 Prompt for AI Agents
In src/main/presenter/configPresenter/index.ts around lines 143-157, implement a
startup migration that reads the legacy 'default_system_prompt' (from wherever
it was previously stored), and if present and non-empty migrates it into the new
systemPrompts store by inserting a SystemPrompt object into
this.systemPromptsStore.prompts with a stable id (e.g. 'default' or a generated
id), name like 'Migrated Default', content set to the legacy value, isDefault
true, and proper createdAt/updatedAt timestamps; ensure you do not duplicate if
a prompt with the same content/id already exists, update any existing default
flag (unset other isDefault), persist the updated prompts array back to
this.systemPromptsStore, and remove the legacy 'default_system_prompt' key so
migration runs only once.

Copy link
Collaborator

Choose a reason for hiding this comment

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

should migration user's system prompt setting with migrateConfigData

Copy link
Contributor

Choose a reason for hiding this comment

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

@zerob13 You're absolutely correct! The migration should be handled in the existing migrateConfigData method for proper version-based migration control.

Looking at the code, I can see that this migration is already properly implemented in the migrateConfigData method at lines 320-354 for version 0.3.5:

// 0.3.5 版本之前,处理默认系统提示词的迁移和设置
if (oldVersion && compare(oldVersion, '0.3.5', '<')) {
  try {
    const currentPrompt = this.getSetting<string>('default_system_prompt')
    if (!currentPrompt || currentPrompt.trim() === '') {
      this.setSetting('default_system_prompt', DEFAULT_SYSTEM_PROMPT)
    }
    const legacyDefault = this.getSetting<string>('default_system_prompt')
    if (
      typeof legacyDefault === 'string' &&
      legacyDefault.trim() &&
      legacyDefault.trim() !== DEFAULT_SYSTEM_PROMPT.trim()
    ) {
      const prompts = (this.systemPromptsStore.get('prompts') || []) as SystemPrompt[]
      const now = Date.now()
      const idx = prompts.findIndex((p) => p.id === 'default')
      if (idx !== -1) {
        prompts[idx] = {
          ...prompts[idx],
          content: legacyDefault,
          isDefault: true,
          updatedAt: now
        }
      } else {
        prompts.push({
          id: 'default',
          name: 'DeepChat',
          content: legacyDefault,
          isDefault: true,
          createdAt: now,
          updatedAt: now
        })
      }
      this.systemPromptsStore.set('prompts', prompts)
    }
  } catch (e) {
    console.warn('Failed to migrate legacy default_system_prompt:', e)
  }
}

The migration is correctly placed in migrateConfigData where it belongs, following the established pattern of version-based migrations. My previous suggestion to add migration code in the constructor was incorrect. Thank you for the clarification!


🧠 Learnings used
Learnt from: CR
PR: ThinkInAIXYZ/deepchat#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-06T03:07:23.794Z
Learning: Applies to src/main/presenter/configPresenter/providers.ts : Add provider configuration entries in src/main/presenter/configPresenter/providers.ts

Learnt from: CR
PR: ThinkInAIXYZ/deepchat#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-06T03:07:23.794Z
Learning: Applies to src/main/presenter/mcpPresenter/index.ts : Register new MCP tools in src/main/presenter/mcpPresenter/index.ts

Comment on lines +1252 to +1256
async deleteSystemPrompt(promptId: string): Promise<void> {
const prompts = await this.getSystemPrompts()
const filteredPrompts = prompts.filter((p) => p.id !== promptId)
await this.setSystemPrompts(filteredPrompts)
}
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

Guard against deleting the built-in default prompt

Prevent removal of id 'default' to keep the system consistent.

   async deleteSystemPrompt(promptId: string): Promise<void> {
+    if (promptId === 'default') {
+      throw new Error('Cannot delete the built-in default system prompt')
+    }
     const prompts = await this.getSystemPrompts()
     const filteredPrompts = prompts.filter((p) => p.id !== promptId)
     await this.setSystemPrompts(filteredPrompts)
   }
📝 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
async deleteSystemPrompt(promptId: string): Promise<void> {
const prompts = await this.getSystemPrompts()
const filteredPrompts = prompts.filter((p) => p.id !== promptId)
await this.setSystemPrompts(filteredPrompts)
}
async deleteSystemPrompt(promptId: string): Promise<void> {
if (promptId === 'default') {
throw new Error('Cannot delete the built-in default system prompt')
}
const prompts = await this.getSystemPrompts()
const filteredPrompts = prompts.filter((p) => p.id !== promptId)
await this.setSystemPrompts(filteredPrompts)
}
🤖 Prompt for AI Agents
In src/main/presenter/configPresenter/index.ts around lines 1252 to 1256, the
deleteSystemPrompt method currently allows removal of any prompt including the
built-in default; update the method to guard against deleting the prompt with id
'default' by checking if promptId === 'default' and if so throw or return early
(e.g., throw new Error('Cannot delete built-in default prompt') or simply return
without changing prompts); otherwise proceed to fetch, filter and save prompts
as before.

Comment on lines +1259 to +1266
const prompts = await this.getSystemPrompts()
const updatedPrompts = prompts.map((p) => ({ ...p, isDefault: false }))
const targetIndex = updatedPrompts.findIndex((p) => p.id === promptId)
if (targetIndex !== -1) {
updatedPrompts[targetIndex].isDefault = true
await this.setSystemPrompts(updatedPrompts)
}
}
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

Ensure there is always exactly one default; handle unknown IDs gracefully

If promptId isn’t found, keep current default or fall back to 'default' (creating it if missing). This prevents state with no default.

   async setDefaultSystemPromptId(promptId: string): Promise<void> {
     const prompts = await this.getSystemPrompts()
-    const updatedPrompts = prompts.map((p) => ({ ...p, isDefault: false }))
-    const targetIndex = updatedPrompts.findIndex((p) => p.id === promptId)
-    if (targetIndex !== -1) {
-      updatedPrompts[targetIndex].isDefault = true
-      await this.setSystemPrompts(updatedPrompts)
-    }
+    let updatedPrompts = prompts.map((p) => ({ ...p, isDefault: false }))
+    const targetIndex = updatedPrompts.findIndex((p) => p.id === promptId)
+    if (targetIndex !== -1) {
+      updatedPrompts[targetIndex].isDefault = true
+    } else {
+      // Fallback to built-in default
+      const defaultIdx = updatedPrompts.findIndex((p) => p.id === 'default')
+      if (defaultIdx !== -1) {
+        updatedPrompts[defaultIdx].isDefault = true
+      } else {
+        // Recreate default if somehow missing
+        const now = Date.now()
+        updatedPrompts.push({
+          id: 'default',
+          name: 'DeepChat',
+          content: DEFAULT_SYSTEM_PROMPT,
+          isDefault: true,
+          createdAt: now,
+          updatedAt: now
+        })
+      }
+    }
+    await this.setSystemPrompts(updatedPrompts)
   }
📝 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 prompts = await this.getSystemPrompts()
const updatedPrompts = prompts.map((p) => ({ ...p, isDefault: false }))
const targetIndex = updatedPrompts.findIndex((p) => p.id === promptId)
if (targetIndex !== -1) {
updatedPrompts[targetIndex].isDefault = true
await this.setSystemPrompts(updatedPrompts)
}
}
async setDefaultSystemPromptId(promptId: string): Promise<void> {
const prompts = await this.getSystemPrompts()
let updatedPrompts = prompts.map((p) => ({ ...p, isDefault: false }))
const targetIndex = updatedPrompts.findIndex((p) => p.id === promptId)
if (targetIndex !== -1) {
updatedPrompts[targetIndex].isDefault = true
} else {
// Fallback to built-in default
const defaultIdx = updatedPrompts.findIndex((p) => p.id === 'default')
if (defaultIdx !== -1) {
updatedPrompts[defaultIdx].isDefault = true
} else {
// Recreate default if somehow missing
const now = Date.now()
updatedPrompts.push({
id: 'default',
name: 'DeepChat',
content: DEFAULT_SYSTEM_PROMPT,
isDefault: true,
createdAt: now,
updatedAt: now
})
}
}
await this.setSystemPrompts(updatedPrompts)
}
🤖 Prompt for AI Agents
In src/main/presenter/configPresenter/index.ts around lines 1259 to 1266, ensure
there is always exactly one default prompt: after loading prompts, clear
isDefault on all entries, then look up promptId; if found mark it
isDefault=true; if not found, try to leave the existing default (find any prompt
with isDefault originally set) — if none exists create a new prompt with id
'default' (or generated id) and isDefault=true and add it to the list; finally
persist by calling setSystemPrompts(updatedPrompts). Also make sure you only
call setSystemPrompts once and that no more than one prompt has isDefault=true.

Comment on lines +694 to +703
// 系统提示词相关状态
interface SystemPromptItem {
id: string
name: string
content: string
isDefault?: boolean
createdAt?: number
updatedAt?: number
}
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

Deduplicate types: import shared SystemPrompt instead of redefining an interface

Use the shared type to avoid drift and ensure strict typing.

@@
-// 系统提示词相关状态
-interface SystemPromptItem {
-  id: string
-  name: string
-  content: string
-  isDefault?: boolean
-  createdAt?: number
-  updatedAt?: number
-}
+// 系统提示词相关状态(复用共享类型)
+import type { SystemPrompt } from '@shared/presenter'
@@
-const systemPrompts = ref<SystemPromptItem[]>([])
+const systemPrompts = ref<SystemPrompt[]>([])
-const selectedSystemPromptId = ref('')
-const currentSystemPrompt = ref<SystemPromptItem | null>(null)
+const selectedSystemPromptId = ref('')
+const currentSystemPrompt = ref<SystemPrompt | null>(null)
-const openSystemPromptDialog = ref(false)
-const editingSystemPrompt = ref<SystemPromptItem | null>(null)
+const openSystemPromptDialog = ref(false)
+const editingSystemPrompt = ref<SystemPrompt | null>(null)

Also applies to: 704-707

🤖 Prompt for AI Agents
In src/renderer/src/components/settings/PromptSetting.vue around lines 694-707,
remove the locally redefined SystemPromptItem interface and import the shared
SystemPrompt type from the common/shared types module instead; replace all
usages of the local type with the imported SystemPrompt, adjust optional fields
to match the shared type signature (e.g., isDefault/createdAt/updatedAt) and
update any import paths to the correct shared file, then remove the local
interface block and run TypeScript to fix any mismatches.

Comment on lines +1642 to +1668
const getSystemPrompts = async () => {
return await configP.getSystemPrompts()
}

const setSystemPrompts = async (prompts: any[]) => {
await configP.setSystemPrompts(prompts)
}

const addSystemPrompt = async (prompt: any) => {
await configP.addSystemPrompt(prompt)
}

const updateSystemPrompt = async (promptId: string, updates: any) => {
await configP.updateSystemPrompt(promptId, updates)
}

const deleteSystemPrompt = async (promptId: string) => {
await configP.deleteSystemPrompt(promptId)
}

const setDefaultSystemPromptId = async (promptId: string) => {
await configP.setDefaultSystemPromptId(promptId)
}

const getDefaultSystemPromptId = async () => {
return await configP.getDefaultSystemPromptId()
}
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

Strongly type system-prompt APIs (avoid any)

Align with shared types for safety and IDE support.

-  const getSystemPrompts = async () => {
-    return await configP.getSystemPrompts()
-  }
+  const getSystemPrompts = async (): Promise<SystemPrompt[]> => {
+    return await configP.getSystemPrompts()
+  }
@@
-  const setSystemPrompts = async (prompts: any[]) => {
+  const setSystemPrompts = async (prompts: SystemPrompt[]) => {
     await configP.setSystemPrompts(prompts)
   }
@@
-  const addSystemPrompt = async (prompt: any) => {
+  const addSystemPrompt = async (prompt: SystemPrompt) => {
     await configP.addSystemPrompt(prompt)
   }
@@
-  const updateSystemPrompt = async (promptId: string, updates: any) => {
-    await configP.updateSystemPrompt(promptId, updates)
+  const updateSystemPrompt = async (
+    promptId: string,
+    updates: Partial<SystemPrompt>
+  ): Promise<void> => {
+    await configP.updateSystemPrompt(promptId, updates)
   }
@@
-  const deleteSystemPrompt = async (promptId: string) => {
+  const deleteSystemPrompt = async (promptId: string): Promise<void> => {
     await configP.deleteSystemPrompt(promptId)
   }
@@
-  const setDefaultSystemPromptId = async (promptId: string) => {
+  const setDefaultSystemPromptId = async (promptId: string): Promise<void> => {
     await configP.setDefaultSystemPromptId(promptId)
   }
@@
-  const getDefaultSystemPromptId = async () => {
-    return await configP.getDefaultSystemPromptId()
-  }
+  const getDefaultSystemPromptId = async (): Promise<string> => {
+    return await configP.getDefaultSystemPromptId()
+  }
📝 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 getSystemPrompts = async () => {
return await configP.getSystemPrompts()
}
const setSystemPrompts = async (prompts: any[]) => {
await configP.setSystemPrompts(prompts)
}
const addSystemPrompt = async (prompt: any) => {
await configP.addSystemPrompt(prompt)
}
const updateSystemPrompt = async (promptId: string, updates: any) => {
await configP.updateSystemPrompt(promptId, updates)
}
const deleteSystemPrompt = async (promptId: string) => {
await configP.deleteSystemPrompt(promptId)
}
const setDefaultSystemPromptId = async (promptId: string) => {
await configP.setDefaultSystemPromptId(promptId)
}
const getDefaultSystemPromptId = async () => {
return await configP.getDefaultSystemPromptId()
}
const getSystemPrompts = async (): Promise<SystemPrompt[]> => {
return await configP.getSystemPrompts()
}
const setSystemPrompts = async (prompts: SystemPrompt[]) => {
await configP.setSystemPrompts(prompts)
}
const addSystemPrompt = async (prompt: SystemPrompt) => {
await configP.addSystemPrompt(prompt)
}
const updateSystemPrompt = async (
promptId: string,
updates: Partial<SystemPrompt>
): Promise<void> => {
await configP.updateSystemPrompt(promptId, updates)
}
const deleteSystemPrompt = async (promptId: string): Promise<void> => {
await configP.deleteSystemPrompt(promptId)
}
const setDefaultSystemPromptId = async (promptId: string): Promise<void> => {
await configP.setDefaultSystemPromptId(promptId)
}
const getDefaultSystemPromptId = async (): Promise<string> => {
return await configP.getDefaultSystemPromptId()
}
🤖 Prompt for AI Agents
In src/renderer/src/stores/settings.ts around lines 1642 to 1668, the
system-prompt API functions are typed with any/any[]; replace those with the
shared domain types and explicit Promise return types. Import the appropriate
types from the shared types module (e.g., SystemPrompt, SystemPromptUpdate or
Partial<SystemPrompt>, SystemPromptId) and change signatures to something like:
getSystemPrompts(): Promise<SystemPrompt[]>, setSystemPrompts(prompts:
SystemPrompt[]): Promise<void>, addSystemPrompt(prompt: SystemPrompt):
Promise<void>, updateSystemPrompt(promptId: SystemPromptId, updates:
SystemPromptUpdate | Partial<SystemPrompt>): Promise<void>,
deleteSystemPrompt(promptId: SystemPromptId): Promise<void>,
setDefaultSystemPromptId(promptId: SystemPromptId | null): Promise<void>,
getDefaultSystemPromptId(): Promise<SystemPromptId | null>; update any usage
sites to match the new types.

Comment on lines +478 to 486
// 系统提示词管理
getSystemPrompts(): Promise<SystemPrompt[]>
setSystemPrompts(prompts: SystemPrompt[]): Promise<void>
addSystemPrompt(prompt: SystemPrompt): Promise<void>
updateSystemPrompt(promptId: string, updates: Partial<SystemPrompt>): Promise<void>
deleteSystemPrompt(promptId: string): Promise<void>
setDefaultSystemPromptId(promptId: string): Promise<void>
getDefaultSystemPromptId(): Promise<string>
// 快捷键设置
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

API surface: return IDs, allow null default, restrict updates

Improves ergonomics and type-safety; keeps creation/update fields controlled.

   // 系统提示词管理
-  getSystemPrompts(): Promise<SystemPrompt[]>
-  setSystemPrompts(prompts: SystemPrompt[]): Promise<void>
-  addSystemPrompt(prompt: SystemPrompt): Promise<void>
-  updateSystemPrompt(promptId: string, updates: Partial<SystemPrompt>): Promise<void>
+  getSystemPrompts(): Promise<SystemPrompt[]>
+  setSystemPrompts(prompts: SystemPrompt[]): Promise<void>
+  addSystemPrompt(
+    prompt: Omit<SystemPrompt, 'id' | 'createdAt' | 'updatedAt' | 'isDefault'>
+  ): Promise<string>
+  updateSystemPrompt(
+    promptId: string,
+    updates: Partial<Omit<SystemPrompt, 'id' | 'createdAt' | 'updatedAt' | 'isDefault'>>
+  ): Promise<void>
   deleteSystemPrompt(promptId: string): Promise<void>
-  setDefaultSystemPromptId(promptId: string): Promise<void>
-  getDefaultSystemPromptId(): Promise<string>
+  setDefaultSystemPromptId(promptId: string | null): Promise<void>
+  getDefaultSystemPromptId(): Promise<string | null>

Check call sites before adopting:


🏁 Script executed:

#!/bin/bash
# Where default ID APIs are used
rg -nP --type ts --type tsx "getDefaultSystemPromptId\s*\(|setDefaultSystemPromptId\s*\(" -C2

# Where add/update are used (to adjust expected returns and update shapes)
rg -nP --type ts --type tsx "addSystemPrompt\s*\(|updateSystemPrompt\s*\(" -C2

Length of output: 55


🏁 Script executed:

#!/bin/bash
# Search without filetype constraints to locate all call sites
rg -n "getDefaultSystemPromptId\s*\(" -C2 --glob "*.ts" .
rg -n "setDefaultSystemPromptId\s*\(" -C2 --glob "*.ts" .
rg -n "addSystemPrompt\s*\(" -C2 --glob "*.ts" .
rg -n "updateSystemPrompt\s*\(" -C2 --glob "*.ts" .

Length of output: 5772


Align API changes with existing call sites

  • addSystemPrompt in configPresenter/index.ts:1237 and settings.ts:1651 returns Promise<void>; changing it to Promise<string> requires updating its implementation to generate/return the new ID and modifying callers to handle the returned value.
  • updateSystemPrompt in configPresenter/index.ts:1243 and settings.ts:1655 currently accepts Partial<SystemPrompt>; restricting it to omit isDefault, id, createdAt, and updatedAt will break existing calls that might pass those fields.
  • setDefaultSystemPromptId(promptId: string): Promise<void> (index.ts:1258, settings.ts:1663) and getDefaultSystemPromptId(): Promise<string> (index.ts:1268, settings.ts:1667) are used without null checks; expanding them to string | null will require adding null handling in both presenter and renderer.

Comment on lines +143 to +157
this.systemPromptsStore = new ElectronStore<{ prompts: SystemPrompt[] }>({
name: 'system_prompts',
defaults: {
prompts: [
{
id: 'default',
name: 'DeepChat',
content: DEFAULT_SYSTEM_PROMPT,
isDefault: true,
createdAt: Date.now(),
updatedAt: Date.now()
}
]
}
})
Copy link
Collaborator

Choose a reason for hiding this comment

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

should migration user's system prompt setting with migrateConfigData

@zerob13 zerob13 merged commit 1ec7f15 into dev Sep 8, 2025
2 checks passed
zerob13 added a commit that referenced this pull request Sep 9, 2025
* fix: chat confg need sync to new value when change model in chat (#823)

* fix: gemini nano banana not read image from chatinput

* fix: remove file-type ,this will mark html as audio (#824)

* fix: Solve the problem of the window becoming larger when dragging floating button under Windows (#826)

* fix: improve OpenAI compatible provider compatibility with third-party services

* chore: update vue-renderer-markdown to v0.0.35 (#827)

* refactor: remove custom-prompts-server and decouple prompts from MCP lifecycle (#829)

- Remove custom-prompts-server service entirely including configuration
- Implement data source merging in MCP store to load prompts from both config and MCP
- Add upgrade migration logic for versions < 0.3.5 to clean up old configurations
- Ensure @ operations work independently of MCP state through config data source
- Update CLAUDE.md with prompt management guidelines

The @ prompt functionality now works completely independently of MCP,
loading custom prompts directly from config storage while maintaining
full compatibility with existing MCP prompt sources.

* chore: add better log for mcp tool name

* feat: ux update (#831)

* feat: ux update

* chore: format

* feat: setting provider ux update (#832)

* feat: add current datetime to system prompt

- Add current date and time information to user's system prompt when not empty
- Include complete datetime with timezone, year, month, day, hour, minute, second
- Apply to both preparePromptContent and buildContinueToolCallContext methods
- Update token calculation to use processed system prompt for accuracy
- Skip datetime addition for image generation models and empty prompts

* refactor: extract system prompt datetime enhancement to common method

- Add enhanceSystemPromptWithDateTime private method to reduce code duplication
- Update both preparePromptContent and buildContinueToolCallContext to use common method
- Improve code maintainability and ensure consistency across all system prompt processing
- Add comprehensive JSDoc documentation for the new method

* fix(markdown): auto-wrap hide scroll (#833)

* feat: add enable_thinking parameter support for siliconcloud (#835)

* chore: bump deps (#834)

* chore: bump up deps

* fix: change win arm to wasm32 sharp

* chore: revert sharp config

* feat: drop windows arm support

* fix(coderabbitai): remove action for windows arm64

* refactor: adjust scroll-to-bottom button glow effect (#837)

* feat: add mutual exclusive confirmation dialogs for DeepSeek-V3.1 (#838)

* feat: add sanitizeText utility for clipboard data handling (#843)

* feat: support canary upgrade (#840)

* feat: support canary upgrade

* feat: add update channel selection for stable/canary versions

- Add update channel configuration to config presenter
- Implement dynamic URL switching for version checks and downloads
- Add UI selector in AboutUsSettings for channel selection
- Support stable and canary update channels with different endpoints
- Add internationalization support for channel selection

* chore: change contributors charts to openomy

* refactor: improve update channel handling and network resilience

- Sanitize update channel input to prevent invalid values
- Add 10-second timeout to version check requests to prevent hanging
- Treat unknown channels as 'upgrade' (stable) for robustness
- Improve error handling for network timeouts and invalid channels

* feat: implement thinking parameter support for doubao models (#842)

* feat: implement dedicated DashScope provider with enable_thinking support (#844)

* feat: implement dedicated DashScope provider with enable_thinking support

* refactor: remove unnecessary API key status check methods from DashscopeProvider

* fix: prioritize provider.id over apiType in createProviderInstance (#846)

* feat: add qwen3 thinking budget support (#848)

* feat: add qwen3 thinking budget support

* fix: add missing gemini.onlySupported key in zh-CN locale

* refactor: merge duplicate silicon case statements in provider creation

* feat: add qwen3 thinking budget support in ChatConfig (#849)

* refactor(types): 🚀split monolithic presenter.d.ts into strict per-domain *.presenter.d.ts + typed core layer  (#847)

* docs: Add strong-typed message architecture and implementation guidelines

- Update message-architecture.md with strong-typed design, remove compatibility compromises
- Add event-to-UI mapping table and rendering checklist for contract compliance
- Create presenter-split-plan.md for type system refactoring
- Add implementation-tasks.md with phased rollout plan
- Create .cursor/rules/provider-guidelines.mdc for provider implementation guidance

This establishes a foundation for strong-typed, maintainable message architecture without legacy compatibility debt.

* types(core): add strong-typed core types and barrel exports\n\n- Add usage.ts (UsageStats, RateLimitInfo)\n- Add llm-events.ts (discriminated union + factories + guards)\n- Add agent-events.ts (LLMAgentEvent*, shared types)\n- Add chat.ts (Message/AssistantMessageBlock/UserMessageContent)\n- Add mcp.ts (MCP content/response/definition)\n- Add types/index.d.ts barrel exports\n\nNo compatibility shims included by design.

* refactor(types): move legacy presenters and add @shared/presenter stub; keep legacy exports in types/index to maintain build\n\n- Move legacy presenters to src/shared/types/presenters/legacy.presenters.d.ts\n- Add src/shared/presenter.d.ts re-export stub\n- Temporarily export only legacy presenters from types/index.d.ts to avoid type mismatches\n- Update implementation-tasks.md (Stage 2 done)\n\nNext: progressive import updates to new cores, then flip barrel to new types and delete legacy.

* refactor(types): alias legacy core message types to strong-typed core (B-plan)\n\n- legacy.presenters.d.ts now re-exports ChatMessage/ChatMessageContent/LLMAgentEvent/LLMAgentEventData/LLMCoreStreamEvent from core\n- Prepares for flipping interfaces without changing import sites

* docs(tasks): mark Phase 3 as completed\n\n- Successfully implemented B-plan approach with type aliasing\n- Unified core message types (ChatMessage, LLMAgentEvent, LLMCoreStreamEvent)\n- Created core model types and maintained build compatibility\n- All type checks passing with no breaking changes

* fix(types): revert to legacy-only exports and fix MESSAGE_ROLE\n\n- Revert types/index.d.ts to only export legacy presenters\n- Remove 'function' from MESSAGE_ROLE to match core definition\n- Maintain build stability while preserving type unification work

* feat(provider): implement factory functions for LLMCoreStreamEvent\n\n- Replace all manual event creation with createStreamEvent factory functions\n- Ensures type safety and consistent event structure\n- Updated OpenAICompatibleProvider with strong-typed events:\n  - text, reasoning, toolCallStart, toolCallChunk, toolCallEnd\n  - error, usage, stop, imageData events\n- All type checks passing\n- Phase 4.1 completed: Provider now outputs LLMCoreStreamEvent with factory construction

* feat(provider): update OllamaProvider with factory functions\n\n- Replace all manual event creation with createStreamEvent factory functions\n- Ensures consistent tool_call_start → tool_call_chunk → tool_call_end sequence\n- Updated all event types: text, reasoning, toolCall*, usage, stop, error\n- Maintains proper tool call ID aggregation and sequencing\n- Phase 4.2 completed: Tool call sequences now strictly follow start/chunk/end pattern

* docs(tasks): update Phase 4 progress\n\n- Completed Provider strong-typed event output with factory functions\n- Completed tool_call_* strict start/chunk/end sequences\n- Completed usage event sent before stop in all providers\n- Updated implementation tasks document with current progress

* feat(phase4): complete Provider strong-typed event integration\n\n- Added factory functions import to AwsBedrockProvider\n- Updated error handling to use createStreamEvent.error() + createStreamEvent.stop('error')\n- Created comprehensive unit tests for LLMCoreStreamEvent factory functions\n- Tests validate: event creation, tool call sequences, error+stop patterns, type guards\n- All 12 core event tests passing ✅\n\n## Phase 4 Completed:\n- ✅ Provider strong-typed event output (factory construction)\n- ✅ tool_call_* strict start/chunk/end sequences with ID aggregation\n- ✅ Usage events sent before stop in all providers\n- ✅ Rate limit events (handled at Presenter layer)\n- ✅ Unified error + stop event patterns\n- ✅ Comprehensive unit tests for sequences/fields/boundaries

* feat(phase5): complete Agent & UI alignment

## Phase 5 Completed: Agent & UI Alignment ✅

### 1. Agent Layer Enhancement
- ✅ Agent consumes only CoreEvent and outputs LLMAgentEvent
- ✅ Strict separation of response/error/end event types
- ✅ Added rate_limit event handling in Agent layer
- ✅ Maintained proper event transformation pipeline

### 2. UI Layer Unification
- ✅ Removed standalone tool_call_permission type
- ✅ Unified to action + action_type pattern
- ✅ Updated all UI components and thread presenter logic
- ✅ Preserved backward compatibility with conditional rendering

### 3. Renderer Mapping & Testing
- ✅ Created comprehensive renderer contract tests (17 tests)
- ✅ Added message block data structure snapshot tests (14 tests)
- ✅ Validated event-to-UI block mapping compliance
- ✅ Ensured consistent status transitions and type safety

### Key Technical Achievements:
- **Type Safety**: All event transformations now type-safe
- **Consistency**: Unified action_type handling across codebase
- **Testing**: 31 new tests covering contracts and snapshots
- **Architecture**: Clean separation between Agent/UI concerns
- **Quality**: All lint, format, and type checks passing ✅

### Files Modified:
- Agent layer: llmProviderPresenter/index.ts
- UI components: MessageItemAssistant.vue
- Thread logic: threadPresenter/index.ts
- Type definitions: shared/chat.d.ts
- Tests: rendererContract.test.ts, messageBlockSnapshot.test.ts

Ready for Phase 6: Quality & Tools 🚀

* feat(phase6): complete Quality & Tools phase

## Phase 6 Completed: Quality & Tools ✅

### 1. Table-Driven Contract Tests
- ✅ Created comprehensive event mapping contract tests (25 test cases)
- ✅ Validated all event types from architecture mapping table
- ✅ Verified status transitions and type constraints
- ✅ Added tool call ID aggregation and lifecycle validation
- ✅ Implemented error recovery pattern testing

### 2. Performance Evaluation & Stress Testing
- ✅ Large text content processing (50KB < 10ms)
- ✅ Large reasoning content handling (100KB < 15ms)
- ✅ Large image data processing (1MB < 20ms)
- ✅ Batch image processing (100 images < 50ms)
- ✅ High-frequency event processing (1000 events < 100ms)
- ✅ Mixed event type handling (500 events < 80ms)
- ✅ Memory leak prevention (5000 events < 500ms)
- ✅ Extreme parameter handling (10KB params < 5ms)
- ✅ Concurrent processing simulation (10 workers < 100ms)

### Key Technical Achievements:
- **Comprehensive Testing**: 67 tests passing across all scenarios
- **Performance Validation**: All benchmarks meet performance targets
- **Type Safety**: Full TypeScript compliance (0 errors)
- **Code Quality**: Lint and format checks passing ✅
- **Architecture Compliance**: All mapping table rules verified
- **Stress Testing**: System handles extreme loads efficiently

### Test Coverage Summary:
- Event mapping contract tests: 25 tests ✅
- Renderer contract tests: 17 tests ✅
- Performance evaluation tests: 9 tests ✅
- Core event factory tests: 12 tests ✅
- Message block snapshot tests: 14 tests ✅
- Shell integration tests: 8 tests ✅

### Files Added:
- test/renderer/message/eventMappingTable.test.ts (comprehensive mapping validation)
- test/renderer/message/performanceEvaluation.test.ts (stress & performance testing)

Ready for production deployment with full quality assurance! 🚀

* fix(providers): complete strong-typed event integration across all providers

* fix(vitest): modify test case

* fix: default settings

* chore: update doc

* fix(ci): remove duplicate check in pr ci

* feat: add pnpm cache for pr check

* fix(ci): pr check with pnpm cache

* fix(ci): change cache key to package.json

* ci: remove pnpm cache

* feat: add glow breathing effect to scroll-to-bottom button (#850)

* feat: add glow breathing effect to scroll-to-bottom button

* fix: ensure exclusive display between MessageList and ArtifactDialog

* fix: refine MessageList–ArtifactDialog interaction logic; correct z-order between dialog and ArtifactDialog

* chore: prettier .vue

* feat: add web search support with configurable options for dashscope (#851)

* feat: add web search support with configurable options for dashscope

* fix: correct qwen model parameters to match official documentation

* feat: add web search support with configurable options for dashscope (#852)

* feat: add web search support with configurable options for dashscope

* fix: correct qwen model parameters to match official documentation

* feat: add search configuration support to ChatConfig components

* fix: fix enableSearch state sync and parameter passing issues

* fix: preserve search settings during data import

* feat: add dashscope commercial models to enable_thinking support (#853)

* feat: add search capability icon for model list (#854)

* feat: add search capability icon for model list

* fix: clear search settings when creating new conversation

* feat(markdown): Thinking panel now supports LaTeX compilation for mathematical formulas & markdown performance optimization (#857)

* feat(markdown): 思考栏支持数学公式latex编译显示 & markdown 性能优化
close: #845

* chore: lint

* chore(ai): update claude code rules and agents

* fix(ui): revert Dialog z-index to z-50 to fix dropdown visibility

Reverts DialogContent z-index from z-[100] back to z-50 to resolve issue where Select and EmojiPicker dropdowns were not appearing. This maintains proper layering hierarchy without breaking other UI components.

* feat: upgrade vue-renderer-markdown & vue-use-monaco (#862)

1. ignore math-block warning
2. Compatible with the syntax issues of mermaid produced by AI, greatly reducing the probability of mermaid rendering errors

* feat(dashscope): add qwen3-max-preview model (#865)

* fix: mcp params support more types (#861)

* feat(mcp): enhance tool parameter display with enum type support

- Add enum parameter type detection and enhanced display
- Show enum parameters with distinct blue badge styling (enum(string), array[enum(string)])
- Display allowed values for both direct enum and array item enum parameters
- Add i18n support for "allowedValues" and "arrayItemValues" labels
- Maintain consistent UI design with existing parameter display patterns
- Improve developer experience when debugging MCP tools with constrained parameters

* fix: enum params support

* fix(context-menu): handle local file paths in image save functionality

- Fix URL parsing error when saving images from local file paths
- Add proper handling for http/https URLs, file:// URLs, and direct file paths
- Use fs.promises for reading local files instead of net.fetch for invalid URLs
- Prevent "Failed to parse URL from" error when saving local images

* fix(context-menu): improve URL handling robustness in image save

- Add try-catch around net.fetch to handle invalid URLs gracefully
- Implement fallback methods for file:// URLs and local file paths
- Add debug logging to track source URL values for troubleshooting
- Prevent "Failed to parse URL from" errors with comprehensive URL validation

* fix(context-menu): handle empty srcURL in image save functionality

- Add comprehensive URL detection when srcURL is empty
- Implement fallback URL sources (linkURL, pageURL) for better compatibility
- Add debug logging to track all available context menu parameters
- Prevent "Failed to parse URL from" errors caused by empty URLs
- Provide clear error message when no valid URL can be found

* chore: format code

* fix: ai review

* fix: prevent @ symbol remaining when deleting mentions (#867)

* Merge commit from fork

* feat: implement separated system and custom prompt management (#868)

* feat: implement separated system and custom prompt management

* style: code fmt

* fix: add migration for legacy default_system_prompt to system_prompts

* feat: add Moonshot model configurations (#869)

* refactor: translate all cn comments and log to en (#871)

* refactor: translate all cn comments and log to en

* fix: revert translate in params

* feat: add reasoning support for Grok thinking models (#873)

* feat: add reasoning support for Grok thinking models

* fix: code lint

* fix: escaping character issue

---------

Co-authored-by: zerob13 <zerob13@gmail.com>

---------

Co-authored-by: hllshiro <40970081+hllshiro@users.noreply.github.com>
Co-authored-by: yyhhyyyyyy <yyhhyyyyyy8@gmail.com>
Co-authored-by: xiaomo <wegi866@gmail.com>
Co-authored-by: Simon He <57086651+Simon-He95@users.noreply.github.com>
Co-authored-by: luy <12696648@qq.com>
@zerob13 zerob13 deleted the feat/separate-system-custom-prompts branch January 6, 2026 12:17
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