diff --git a/src/main/presenter/configPresenter/index.ts b/src/main/presenter/configPresenter/index.ts index 0d06e82e57204044b4d55d4c91e52c84af338cc8..17a2b8416dc0ed61d09b28eab76336a712a55e43 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 6ad2091b3c679b76927d3e51c4ab263a770c161d..2b7a8af19a0208d64a86ba105193c4ea271d7d2f 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 69767d662a1568d4598ac738e4036615bdfafe15..93e330c0ea022d3396a75bb86f5f33a7fa3a2c08 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 9a25ed6bcbe9096814bf4a39bb19c11f93e865b9..58703964dedffccbd728fa346a6e6862598b2eae 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 ae6130c89ce804c05fba933cad211272a4ea0892..5597b6a8948613d8ba1cf80642eda11aad847211 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