From 9977b4ee779c45f50b3ac0bfde7222466a1e30ee Mon Sep 17 00:00:00 2001 From: duanfuxiang Date: Tue, 18 Mar 2025 08:13:13 +0800 Subject: [PATCH] update prompt, use user language --- package.json | 4 +- pnpm-lock.yaml | 85 +++++++++++++++++-- src/core/prompts/system.ts | 2 +- .../prompts/tools/ask-followup-question.ts | 2 +- src/utils/prompt-generator.ts | 19 ++++- 5 files changed, 100 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 1e64931..d2d9d34 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "eslint-plugin-react-hooks": "^5.0.0", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", - "obsidian": "latest", + "obsidian": "^1.8.7", "prettier": "^3.4.2", "stylelint": "^16.12.0", "ts-jest": "^29.2.5", @@ -56,6 +56,8 @@ "@langchain/core": "^0.3.26", "@lexical/clipboard": "^0.17.1", "@lexical/react": "^0.17.1", + "@lexical/rich-text": "^0.27.2", + "@lexical/utils": "^0.27.2", "@radix-ui/react-dialog": "^1.1.2", "@radix-ui/react-dropdown-menu": "^2.1.2", "@radix-ui/react-popover": "^1.1.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 02268cb..a241f55 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -26,6 +26,12 @@ importers: '@lexical/react': specifier: ^0.17.1 version: 0.17.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(yjs@13.6.23) + '@lexical/rich-text': + specifier: ^0.27.2 + version: 0.27.2 + '@lexical/utils': + specifier: ^0.27.2 + version: 0.27.2 '@radix-ui/react-dialog': specifier: ^1.1.2 version: 1.1.6(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -223,8 +229,8 @@ importers: specifier: ^29.7.0 version: 29.7.0 obsidian: - specifier: latest - version: 1.7.2(@codemirror/state@6.5.2)(@codemirror/view@6.36.2) + specifier: ^1.8.7 + version: 1.8.7(@codemirror/state@6.5.2)(@codemirror/view@6.36.2) prettier: specifier: ^3.4.2 version: 3.5.1 @@ -1030,6 +1036,9 @@ packages: '@lexical/clipboard@0.17.1': resolution: {integrity: sha512-OVqnEfWX8XN5xxuMPo6BfgGKHREbz++D5V5ISOiml0Z8fV/TQkdgwqbBJcUdJHGRHWSUwdK7CWGs/VALvVvZyw==} + '@lexical/clipboard@0.27.2': + resolution: {integrity: sha512-rfnFYf8P0081IvPOJjE7fWJE+d/dz0Xdsw83uizY5X6HaLXFB/Qy1MrzEqWZnYnOpgi1snAuolZ5Rbg83SIlYA==} + '@lexical/code@0.17.1': resolution: {integrity: sha512-ZspfTm6g6dN3nAb4G5bPp3SqxzdkB/bjGfa0uRKMU6/eBKtrMUgZsGxt0a8JRZ1eq2TZrQhx+l1ceRoLXii/bQ==} @@ -1051,12 +1060,18 @@ packages: '@lexical/html@0.17.1': resolution: {integrity: sha512-yGG+K2DXl7Wn2DpNuZ0Y3uCHJgfHkJN3/MmnFb4jLnH1FoJJiuy7WJb/BRRh9H+6xBJ9v70iv+kttDJ0u1xp5w==} + '@lexical/html@0.27.2': + resolution: {integrity: sha512-6kPvrTxAE39jUhnbYMCenHVHXTlew9sBprniQu5iZSszMfcn/SDkqmHWi8//fhiLlcAa/p0vRDxaBYoQQf0r9A==} + '@lexical/link@0.17.1': resolution: {integrity: sha512-qFJEKBesZAtR8kfJfIVXRFXVw6dwcpmGCW7duJbtBRjdLjralOxrlVKyFhW9PEXGhi4Mdq2Ux16YnnDncpORdQ==} '@lexical/list@0.17.1': resolution: {integrity: sha512-k9ZnmQuBvW+xVUtWJZwoGtiVG2cy+hxzkLGU4jTq1sqxRIoSeGcjvhFAK8JSEj4i21SgkB1FmkWXoYK5kbwtRA==} + '@lexical/list@0.27.2': + resolution: {integrity: sha512-jE7e95ttO26Xtt322dnUwWSG7QgeAfBg3Ghyjd8ByGI5O5wmMgMgb3NCiSSRPBWOpt6PEeD5s5KjQKfMUCCuHQ==} + '@lexical/mark@0.17.1': resolution: {integrity: sha512-V82SSRjvygmV+ZMwVpy5gwgr2ZDrJpl3TvEDO+G5I4SDSjbgvua8hO4dKryqiDVlooxQq9dsou0GrZ9Qtm6rYg==} @@ -1081,18 +1096,30 @@ packages: '@lexical/rich-text@0.17.1': resolution: {integrity: sha512-T3kvj4P1OpedX9jvxN3WN8NP1Khol6mCW2ScFIRNRz2dsXgyN00thH1Q1J/uyu7aKyGS7rzcY0rb1Pz1qFufqQ==} + '@lexical/rich-text@0.27.2': + resolution: {integrity: sha512-naWwPNbEJAue/R0pmZwqnTVkv3V2rzgzz+C6/J5tMOvN1Osth8OL3UD6K8NQX8rjdnXe4soVoH8XsNhU0Jv10w==} + '@lexical/selection@0.17.1': resolution: {integrity: sha512-qBKVn+lMV2YIoyRELNr1/QssXx/4c0id9NCB/BOuYlG8du5IjviVJquEF56NEv2t0GedDv4BpUwkhXT2QbNAxA==} + '@lexical/selection@0.27.2': + resolution: {integrity: sha512-9AJOfw1zMQ3PqGpovEuy6NjfWck/9KzxNPzXoGRZlJRvPexgZirentPWRhLHF3DMtnOML1+GCpj+5LOAYN2XbQ==} + '@lexical/table@0.17.1': resolution: {integrity: sha512-2fUYPmxhyuMQX3MRvSsNaxbgvwGNJpHaKx1Ldc+PT2MvDZ6ALZkfsxbi0do54Q3i7dOon8/avRp4TuVaCnqvoA==} + '@lexical/table@0.27.2': + resolution: {integrity: sha512-6G3jj7EyweviX3/AEZOr/XBTIQN5QCkJcg1Zw3I9Ga0F+CCDM5aeJWRv4hultP1nOz1xtYCDnezhaPV1Gef9dA==} + '@lexical/text@0.17.1': resolution: {integrity: sha512-zD2pAGXaMfPpT8PeNrx3+n0+jGnQORHyn0NEBO+hnyacKfUq5z5sI6Gebsq5NwH789bRadmJM5LvX5w8fsuv6w==} '@lexical/utils@0.17.1': resolution: {integrity: sha512-jCQER5EsvhLNxKH3qgcpdWj/necUb82Xjp8qWQ3c0tyL07hIRm2tDRA/s9mQmvcP855HEZSmGVmR5SKtkcEAVg==} + '@lexical/utils@0.27.2': + resolution: {integrity: sha512-tCEuKL5IXiJ12ZN/Ej37Q7PhcBntekLeQbGiYO4sgIAnR9qI6yYgVH7b1CC+Tf06UapUXjIDG0Uh5/u0W1+kOQ==} + '@lexical/yjs@0.17.1': resolution: {integrity: sha512-9mn5PDtaH5uLMH6hQ59EAx5FkRzmJJFcVs3E6zSIbtgkG3UASR3CFEfgsLKTjl/GC5NnTGuMck+jXaupDVBhOg==} peerDependencies: @@ -3312,6 +3339,9 @@ packages: lexical@0.17.1: resolution: {integrity: sha512-72/MhR7jqmyqD10bmJw8gztlCm4KDDT+TPtU4elqXrEvHoO5XENi34YAEUD9gIkPfqSwyLa9mwAX1nKzIr5xEA==} + lexical@0.27.2: + resolution: {integrity: sha512-R255V+4VBqZmSMWeuMrCNHJZd3L+qBkYYFrxkiO3FLg/36HatZLUdZLRYx+fOMWeSddo0DP9EVl0GTZzNb7v0w==} + lib0@0.2.99: resolution: {integrity: sha512-vwztYuUf1uf/1zQxfzRfO5yzfNKhTtgOByCruuiQQxWQXnPb8Itaube5ylofcV0oM0aKal9Mv+S1s1Ky0UYP1w==} engines: {node: '>=16'} @@ -3655,8 +3685,8 @@ packages: resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} engines: {node: '>= 0.4'} - obsidian@1.7.2: - resolution: {integrity: sha512-k9hN9brdknJC+afKr5FQzDRuEFGDKbDjfCazJwpgibwCAoZNYHYV8p/s3mM8I6AsnKrPKNXf8xGuMZ4enWelZQ==} + obsidian@1.8.7: + resolution: {integrity: sha512-h4bWwNFAGRXlMlMAzdEiIM2ppTGlrh7uGOJS6w4gClrsjc+ei/3YAtU2VdFUlCiPuTHpY4aBpFJJW75S1Tl/JA==} peerDependencies: '@codemirror/state': ^6.0.0 '@codemirror/view': ^6.0.0 @@ -5313,6 +5343,14 @@ snapshots: '@lexical/utils': 0.17.1 lexical: 0.17.1 + '@lexical/clipboard@0.27.2': + dependencies: + '@lexical/html': 0.27.2 + '@lexical/list': 0.27.2 + '@lexical/selection': 0.27.2 + '@lexical/utils': 0.27.2 + lexical: 0.27.2 + '@lexical/code@0.17.1': dependencies: '@lexical/utils': 0.17.1 @@ -5350,6 +5388,12 @@ snapshots: '@lexical/utils': 0.17.1 lexical: 0.17.1 + '@lexical/html@0.27.2': + dependencies: + '@lexical/selection': 0.27.2 + '@lexical/utils': 0.27.2 + lexical: 0.27.2 + '@lexical/link@0.17.1': dependencies: '@lexical/utils': 0.17.1 @@ -5360,6 +5404,11 @@ snapshots: '@lexical/utils': 0.17.1 lexical: 0.17.1 + '@lexical/list@0.27.2': + dependencies: + '@lexical/utils': 0.27.2 + lexical: 0.27.2 + '@lexical/mark@0.17.1': dependencies: '@lexical/utils': 0.17.1 @@ -5424,15 +5473,32 @@ snapshots: '@lexical/utils': 0.17.1 lexical: 0.17.1 + '@lexical/rich-text@0.27.2': + dependencies: + '@lexical/clipboard': 0.27.2 + '@lexical/selection': 0.27.2 + '@lexical/utils': 0.27.2 + lexical: 0.27.2 + '@lexical/selection@0.17.1': dependencies: lexical: 0.17.1 + '@lexical/selection@0.27.2': + dependencies: + lexical: 0.27.2 + '@lexical/table@0.17.1': dependencies: '@lexical/utils': 0.17.1 lexical: 0.17.1 + '@lexical/table@0.27.2': + dependencies: + '@lexical/clipboard': 0.27.2 + '@lexical/utils': 0.27.2 + lexical: 0.27.2 + '@lexical/text@0.17.1': dependencies: lexical: 0.17.1 @@ -5444,6 +5510,13 @@ snapshots: '@lexical/table': 0.17.1 lexical: 0.17.1 + '@lexical/utils@0.27.2': + dependencies: + '@lexical/list': 0.27.2 + '@lexical/selection': 0.27.2 + '@lexical/table': 0.27.2 + lexical: 0.27.2 + '@lexical/yjs@0.17.1(yjs@13.6.23)': dependencies: '@lexical/offset': 0.17.1 @@ -8090,6 +8163,8 @@ snapshots: lexical@0.17.1: {} + lexical@0.27.2: {} + lib0@0.2.99: dependencies: isomorphic.js: 0.2.5 @@ -8611,7 +8686,7 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.1.1 - obsidian@1.7.2(@codemirror/state@6.5.2)(@codemirror/view@6.36.2): + obsidian@1.8.7(@codemirror/state@6.5.2)(@codemirror/view@6.36.2): dependencies: '@codemirror/state': 6.5.2 '@codemirror/view': 6.36.2 diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index 652862a..56d5389 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -109,13 +109,13 @@ export const SYSTEM_PROMPT = async ( supportsComputerUse: boolean, mode: Mode = defaultModeSlug, filesSearchMethod: string = 'regex', + preferredLanguage?: string, mcpHub?: McpHub, diffStrategy?: DiffStrategy, browserViewportSize?: string, customModePrompts?: CustomModePrompts, customModes?: ModeConfig[], globalCustomInstructions?: string, - preferredLanguage?: string, diffEnabled?: boolean, experiments?: Record, enableMcpServerCreation?: boolean, diff --git a/src/core/prompts/tools/ask-followup-question.ts b/src/core/prompts/tools/ask-followup-question.ts index 97e8675..81c3aa8 100644 --- a/src/core/prompts/tools/ask-followup-question.ts +++ b/src/core/prompts/tools/ask-followup-question.ts @@ -1,4 +1,4 @@ -export function getAskFollowupQuestionDescription(): string { +export function getAskFollowupQuestionDescription(userLanguage: string): string { return `## ask_followup_question Description: Ask the user a question to gather additional information needed to complete the task. This tool should be used when you encounter ambiguities, need clarification, or require more details to proceed effectively. It allows for interactive problem-solving by enabling direct communication with the user. Use this tool judiciously to maintain a balance between gathering necessary information and avoiding excessive back-and-forth. Parameters: diff --git a/src/utils/prompt-generator.ts b/src/utils/prompt-generator.ts index a70f3b6..ca0ca9e 100644 --- a/src/utils/prompt-generator.ts +++ b/src/utils/prompt-generator.ts @@ -1,4 +1,4 @@ -import { App, MarkdownView, TAbstractFile, TFile, TFolder, Vault, htmlToMarkdown, requestUrl } from 'obsidian' +import { App, MarkdownView, TAbstractFile, TFile, TFolder, Vault, htmlToMarkdown, requestUrl, getLanguage } from 'obsidian' import { editorStateToPlainText } from '../components/chat-view/chat-input/utils/editor-state-to-plain-text' import { QueryProgressState } from '../components/chat-view/QueryProgress' @@ -35,6 +35,14 @@ export function addLineNumbers(content: string, startLine: number = 1): string { .join("\n") } +export function getFullLanguageName(code: string): string { + try { + return new Intl.DisplayNames([code], { type: 'language' }).of(code) || code; + } catch { + return code.toUpperCase(); + } +} + async function getFolderTreeContent(path: TFolder): Promise { try { const entries = path.children @@ -166,7 +174,10 @@ export class PromptGenerator { } console.log('filesSearchMethod: ', filesSearchMethod) - const systemMessage = await this.getSystemMessageNew(this.settings.mode, filesSearchMethod) + + const userLanguage = getFullLanguageName(getLanguage()) + console.log(' current user language: ', userLanguage) + const systemMessage = await this.getSystemMessageNew(this.settings.mode, filesSearchMethod, userLanguage) const requestMessages: RequestMessage[] = [ systemMessage, @@ -454,8 +465,8 @@ export class PromptGenerator { } } - private async getSystemMessageNew(mode: Mode, filesSearchMethod: string): Promise { - const systemPrompt = await SYSTEM_PROMPT(this.app.vault.getRoot().path, false, mode, filesSearchMethod) + private async getSystemMessageNew(mode: Mode, filesSearchMethod: string, preferredLanguage: string): Promise { + const systemPrompt = await SYSTEM_PROMPT(this.app.vault.getRoot().path, false, mode, filesSearchMethod, preferredLanguage) return { role: 'system',