diff --git a/src/main/presenter/deeplinkPresenter/index.ts b/src/main/presenter/deeplinkPresenter/index.ts index 54f426a68..490bafe80 100644 --- a/src/main/presenter/deeplinkPresenter/index.ts +++ b/src/main/presenter/deeplinkPresenter/index.ts @@ -184,6 +184,14 @@ export class DeeplinkPresenter implements IDeeplinkPresenter { } else { systemPrompt = '' } + let mentions: string[] = [] + const mentionsParam = params.get('mentions') + if (mentionsParam && mentionsParam.trim() !== '') { + mentions = decodeURIComponent(mentionsParam) + .split(',') + .map((mention) => mention.trim()) + .filter((mention) => mention.length > 0) + } // 如果用户增加了yolo=1或者yolo=true,则自动发送消息 const yolo = params.get('yolo') const autoSend = yolo && yolo.trim() !== '' @@ -204,6 +212,7 @@ export class DeeplinkPresenter implements IDeeplinkPresenter { msg, modelId, systemPrompt, + mentions, autoSend }) } diff --git a/src/renderer/src/components/ChatInput.vue b/src/renderer/src/components/ChatInput.vue index ae60c6d37..6d62d9cb4 100644 --- a/src/renderer/src/components/ChatInput.vue +++ b/src/renderer/src/components/ChatInput.vue @@ -202,7 +202,11 @@ import Document from '@tiptap/extension-document' import Paragraph from '@tiptap/extension-paragraph' import Text from '@tiptap/extension-text' import { Mention } from './editor/mention/mention' -import suggestion, { mentionData, setPromptFilesHandler } from './editor/mention/suggestion' +import suggestion, { + mentionData, + setPromptFilesHandler, + getPromptFilesHandler +} from './editor/mention/suggestion' import { mentionSelected } from './editor/mention/suggestion' import Placeholder from '@tiptap/extension-placeholder' import HardBreak from '@tiptap/extension-hard-break' @@ -213,6 +217,8 @@ import { ResourceListEntry } from '@shared/presenter' import { searchHistory } from '@/lib/searchHistory' import { useLanguageStore } from '@/stores/language' import { useToast } from '@/components/ui/toast/use-toast' +import type { CategorizedData } from './editor/mention/suggestion' +import type { PromptListEntry } from '@shared/presenter' const langStore = useLanguageStore() const mcpStore = useMcpStore() @@ -1018,17 +1024,110 @@ function onKeydown(e: KeyboardEvent) { } } +// 通过名称查找mention数据 +const findMentionByName = (name: string): CategorizedData | null => { + // 在当前的mentionData中查找匹配的项目 + const foundMention = mentionData.value.find( + (item) => item.type === 'item' && (item.label === name || item.id === name) + ) + + return foundMention || null +} + +// 简化的插入mention到编辑器 +const insertMentionToEditor = (mentionData: CategorizedData, position: number): boolean => { + try { + // 构建mention节点属性 + const mentionAttrs = { + id: mentionData.id, + label: mentionData.label, + category: mentionData.category, + content: mentionData.mcpEntry ? JSON.stringify(mentionData.mcpEntry) : '' + } + + // 使用TipTap命令插入mention + const success = editor + .chain() + .focus() + .setTextSelection(position) + .insertContent({ + type: 'mention', + attrs: mentionAttrs + }) + .insertContent(' ') // 默认添加空格 + .run() + + // 更新内部状态 + if (success) { + inputText.value = editor.getText() + } + + return success + } catch (error) { + console.error('Failed to insert mention to editor:', error) + return false + } +} +const handlePostInsertActions = async (mentionData: CategorizedData): Promise => { + // 处理Prompt类型的特殊逻辑 + if (mentionData.category === 'prompts' && mentionData.mcpEntry) { + const promptEntry = mentionData.mcpEntry as PromptListEntry + + // 处理关联文件 + if (promptEntry.files && Array.isArray(promptEntry.files) && promptEntry.files.length > 0) { + const handler = getPromptFilesHandler() + if (handler) { + await handler(promptEntry.files).catch((error) => { + console.error('Failed to handle prompt files:', error) + }) + } + } + } +} + defineExpose({ - setText: (text: string) => { - inputText.value = text + clearContent: () => { + inputText.value = '' + editor.chain().clearContent().run() + editor.view.updateState(editor.state) + }, + appendText: (text: string) => { + inputText.value += text nextTick(() => { - editor.chain().clearContent().insertContent(text).run() + editor.chain().insertContent(text).run() editor.view.updateState(editor.state) setTimeout(() => { const docSize = editor.state.doc.content.size editor.chain().focus().setTextSelection(docSize).run() }, 10) }) + }, + appendMention: async (name: string) => { + try { + // 通过name在各个数据源中查找匹配的mention + const mentionData = findMentionByName(name) + + if (!mentionData) { + console.warn(`Mention not found: ${name}`) + return false + } + + // 计算插入位置(默认为光标位置) + const insertPosition = editor.state.selection.anchor + + // 执行TipTap插入操作 + const insertSuccess = insertMentionToEditor(mentionData, insertPosition) + + // 处理后续操作(如文件关联、参数处理等) + if (insertSuccess) { + await handlePostInsertActions(mentionData) + } + + return insertSuccess + } catch (error) { + console.error('Failed to append mention:', error) + return false + } } }) diff --git a/src/renderer/src/components/NewThread.vue b/src/renderer/src/components/NewThread.vue index 645680f2c..6763ce56c 100644 --- a/src/renderer/src/components/NewThread.vue +++ b/src/renderer/src/components/NewThread.vue @@ -302,8 +302,18 @@ watch( handleModelUpdate(matchedModel.model, matchedModel.providerId) } } - if (newCache.msg && chatInputRef.value) { - chatInputRef.value.setText(newCache.msg) + if (chatInputRef.value && (newCache.msg || newCache.mentions)) { + const chatInput = chatInputRef.value // 将引用存储在局部变量中 + chatInput.clearContent() + if (newCache.mentions) { + // 优先处理 mentions + newCache.mentions.forEach((mention) => { + chatInput.appendMention(mention) + }) + } + if (newCache.msg) { + chatInput.appendText(newCache.msg) + } } if (newCache.systemPrompt) { systemPrompt.value = newCache.systemPrompt diff --git a/src/renderer/src/stores/chat.ts b/src/renderer/src/stores/chat.ts index 3d483c091..903042d88 100644 --- a/src/renderer/src/stores/chat.ts +++ b/src/renderer/src/stores/chat.ts @@ -66,6 +66,7 @@ export const useChatStore = defineStore('chat', () => { modelId?: string systemPrompt?: string autoSend?: boolean + mentions?: string[] } | null>(null) // Getters @@ -955,7 +956,8 @@ export const useChatStore = defineStore('chat', () => { msg: data.msg, modelId: data.modelId, systemPrompt: data.systemPrompt, - autoSend: data.autoSend + autoSend: data.autoSend, + mentions: data.mentions } } })