From d695dbc1b188b474b00fdd7203d6320abd72b565 Mon Sep 17 00:00:00 2001 From: randy1568 Date: Tue, 25 Nov 2025 16:29:38 +0800 Subject: [PATCH] =?UTF-8?q?feat(feat):=20=E9=80=89=E6=8B=A9=E6=99=BA?= =?UTF-8?q?=E8=83=BD=E4=BD=93=EF=BC=8C=E5=B0=81=E8=A3=85roleDefinition?= =?UTF-8?q?=E5=88=B0systemprompt=E4=B8=AD,=E6=96=B0=E5=BB=BA=E4=BC=9A?= =?UTF-8?q?=E8=AF=9D=E5=92=8C=E5=9C=A8=E8=80=81=E7=9A=84=E4=BC=9A=E8=AF=9D?= =?UTF-8?q?=E4=B8=AD=E5=9D=87=E7=94=9F=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/presenter/configPresenter/index.ts | 18 ++++++++++--- src/main/presenter/promptPresenter/system.ts | 15 ++++++++--- src/renderer/src/components/NewThread.vue | 26 ++++++++++++++----- src/renderer/src/components/TitleView.vue | 20 +++++++++++++- .../types/presenters/legacy.presenters.d.ts | 3 ++- 5 files changed, 66 insertions(+), 16 deletions(-) diff --git a/src/main/presenter/configPresenter/index.ts b/src/main/presenter/configPresenter/index.ts index 0d06e82..17a2b84 100644 --- a/src/main/presenter/configPresenter/index.ts +++ b/src/main/presenter/configPresenter/index.ts @@ -1249,8 +1249,8 @@ export class ConfigPresenter implements IConfigPresenter { } // 获取默认系统提示词 - async getDefaultSystemPrompt(): Promise { - const default_system_prompt = await this.getBuildInSystemPrompt() + async getDefaultSystemPrompt(agent?: Agent): Promise { + const default_system_prompt = await this.getBuildInSystemPrompt(agent) return default_system_prompt } @@ -1269,10 +1269,20 @@ export class ConfigPresenter implements IConfigPresenter { this.setSetting('default_system_prompt', '') } - private async getBuildInSystemPrompt(): Promise { + private async getBuildInSystemPrompt(agent?: Agent): Promise { // 获取内置的系统提示词 + let roleDefinition = '' + if (agent) { + roleDefinition += `Your name is ${agent.name},${agent.description}.` + if (agent.skills.length > 0) { + roleDefinition += `You have the following skills:\n` + for (const skill of agent.skills || []) { + roleDefinition += `- ${skill.name}=>${skill.description}\n` + } + } + } const useBuiltInTools = this.getUseBuiltInTools() - return await SYSTEM_PROMPT('', '', this.getLanguage(), '', useBuiltInTools) + return await SYSTEM_PROMPT('', '', this.getLanguage(), '', useBuiltInTools, roleDefinition) } async getSystemPrompts(): Promise { diff --git a/src/main/presenter/promptPresenter/system.ts b/src/main/presenter/promptPresenter/system.ts index 6ad2091..2b7a8af 100644 --- a/src/main/presenter/promptPresenter/system.ts +++ b/src/main/presenter/promptPresenter/system.ts @@ -29,9 +29,14 @@ async function generatePrompt( globalCustomInstructions?: string, language?: string, IgnoreInstructions?: string, - useBuiltInTools?: boolean + useBuiltInTools?: boolean, + roleDefinition?: string ): Promise { - const promptSections = [markdownFormattingSection()] + const promptSections: string[] = [] + if (roleDefinition) { + promptSections.push(roleDefinition) + } + promptSections.push(markdownFormattingSection()) if (useBuiltInTools) { promptSections.push(`${getSharedToolUseSection()} @@ -71,13 +76,15 @@ export const SYSTEM_PROMPT = async ( globalCustomInstructions?: string, language?: string, IgnoreInstructions?: string, - useBuiltInTools?: boolean + useBuiltInTools?: boolean, + roleDefinition?: string ): Promise => { return generatePrompt( cwd, globalCustomInstructions, language, IgnoreInstructions, - useBuiltInTools + useBuiltInTools, + roleDefinition ) } diff --git a/src/renderer/src/components/NewThread.vue b/src/renderer/src/components/NewThread.vue index 69767d6..93e330c 100644 --- a/src/renderer/src/components/NewThread.vue +++ b/src/renderer/src/components/NewThread.vue @@ -140,7 +140,7 @@ import { Badge } from '@/components/ui/badge' import { Icon } from '@iconify/vue' import ModelSelect from './ModelSelect.vue' import { useChatStore } from '@/stores/chat' -import { MODEL_META } from '@shared/presenter' +import { Agent, MODEL_META } from '@shared/presenter' import { useSettingsStore } from '@/stores/settings' import { computed, nextTick, ref, watch, onMounted } from 'vue' import { UserMessageContent } from '@shared/chat' @@ -164,8 +164,8 @@ const { t } = useI18n() const chatStore = useChatStore() const settingsStore = useSettingsStore() -// 使用全局状态中的选中智能体 -const selectedAgent = computed(() => chatStore.selectedAgent) +// 使用全局状态中的选中智能体(Pinia 会自动解包 ref,这里直接返回值) +const selectedAgent = computed(() => chatStore.selectedAgent || null) const activeModel = ref({ name: '', id: '', @@ -193,6 +193,15 @@ const forcedSearch = ref(undefined) const searchStrategy = ref<'turbo' | 'max' | undefined>(undefined) const reasoningEffort = ref<'minimal' | 'low' | 'medium' | 'high' | undefined>(undefined) const verbosity = ref<'low' | 'medium' | 'high' | undefined>(undefined) +//动态加载系统提示词 +const loadSystemPrompt = async (agent?: Agent | null) => { + try { + const prompt = await configPresenter.getDefaultSystemPrompt(agent || undefined) + systemPrompt.value = prompt + } catch (error) { + console.error('[NewThread] Failed to load system prompt', error) + } +} const name = computed(() => { return activeModel.value?.name ? activeModel.value.name.split('/').pop() : '' @@ -409,9 +418,6 @@ watch( onMounted(async () => { const groupElement = document.querySelector('.new-thread-model-select') - configPresenter.getDefaultSystemPrompt().then((prompt) => { - systemPrompt.value = prompt - }) if (groupElement) { useEventListener(groupElement, 'mouseenter', handleMouseEnter) useEventListener(groupElement, 'mouseleave', handleMouseLeave) @@ -441,6 +447,14 @@ watch( { immediate: true } ) +watch( + selectedAgent, + (agent) => { + loadSystemPrompt(agent) + }, + { immediate: true } +) + // 定义模板部分的类型 interface TemplateTextPart { type: 'text' diff --git a/src/renderer/src/components/TitleView.vue b/src/renderer/src/components/TitleView.vue index 9a25ed6..5870396 100644 --- a/src/renderer/src/components/TitleView.vue +++ b/src/renderer/src/components/TitleView.vue @@ -106,7 +106,7 @@ import ScrollablePopover from './ScrollablePopover.vue' import ChatConfig from './ChatConfig.vue' import ModelSelect from './ModelSelect.vue' import ModelIcon from './icons/ModelIcon.vue' -import { MODEL_META } from '@shared/presenter' +import { Agent, MODEL_META } from '@shared/presenter' import { onMounted, onUnmounted, ref, watch, computed } from 'vue' import { useChatStore } from '@/stores/chat' import { usePresenter } from '@/composables/usePresenter' @@ -138,6 +138,16 @@ const searchStrategy = ref(chatStore.chatConfig.searchStrategy) const reasoningEffort = ref(chatStore.chatConfig.reasoningEffort) const verbosity = ref(chatStore.chatConfig.verbosity) const modelType = ref(ModelType.Chat) +// Pinia 解包后直接返回值,保持 watch 能正确触发 +const selectedAgent = computed(() => chatStore.selectedAgent || null) +const loadSystemPrompt = async (agent?: Agent | null) => { + try { + const prompt = await configPresenter.getDefaultSystemPrompt(agent || undefined) + systemPrompt.value = prompt + } catch (error) { + console.error('[TitleView] Failed to load system prompt', error) + } +} // 获取模型配置来初始化默认值并智能调整当前参数 const loadModelConfig = async () => { const modelId = chatStore.chatConfig.modelId @@ -409,6 +419,14 @@ watch( { deep: true } ) +watch( + selectedAgent, + (agent) => { + loadSystemPrompt(agent) + }, + { immediate: true } +) + type Model = { name: string id: string diff --git a/src/shared/types/presenters/legacy.presenters.d.ts b/src/shared/types/presenters/legacy.presenters.d.ts index ae6130c..5597b6a 100644 --- a/src/shared/types/presenters/legacy.presenters.d.ts +++ b/src/shared/types/presenters/legacy.presenters.d.ts @@ -476,7 +476,7 @@ export interface IConfigPresenter { updateCustomPrompt(promptId: string, updates: Partial): Promise deleteCustomPrompt(promptId: string): Promise // Default system prompt settings - getDefaultSystemPrompt(): Promise + getDefaultSystemPrompt(agent?: Agent): Promise setDefaultSystemPrompt(prompt: string): Promise resetToDefaultPrompt(): Promise clearSystemPrompt(): Promise @@ -521,6 +521,7 @@ export interface IConfigPresenter { // Agent management methods getAgents(): Promise + getInstalledAgents(): Promise setAgents(agents: Agent[]): Promise addAgent(agent: Agent): Promise installAgent(agentId: string): Promise -- Gitee