Fix language persistence across sessions; update system prompt for non-english languages

This commit is contained in:
Saoud Rizwan 2025-01-27 20:15:35 -08:00
parent e8c649a215
commit 971489990c
5 changed files with 52 additions and 7 deletions

View file

@ -75,6 +75,7 @@ export class Cline {
browserSession: BrowserSession
private didEditFile: boolean = false
customInstructions?: string
localeLanguage?: string
autoApprovalSettings: AutoApprovalSettings
private browserSettings: BrowserSettings
private chatSettings: ChatSettings
@ -119,6 +120,7 @@ export class Cline {
browserSettings: BrowserSettings,
chatSettings: ChatSettings,
customInstructions?: string,
localeLanguage?: string,
task?: string,
images?: string[],
historyItem?: HistoryItem,
@ -130,6 +132,7 @@ export class Cline {
this.browserSession = new BrowserSession(provider.context, browserSettings)
this.diffViewProvider = new DiffViewProvider(cwd)
this.customInstructions = customInstructions
this.localeLanguage = localeLanguage
this.autoApprovalSettings = autoApprovalSettings
this.browserSettings = browserSettings
this.chatSettings = chatSettings
@ -1212,6 +1215,13 @@ export class Cline {
this.browserSettings,
)
let userSelectedNonEnglishLanguage: string | undefined
// While we check vscode for preferred language, it's likely not giving us one of the language options
console.log("this.localeLanguage", this.localeLanguage)
if (this.localeLanguage && this.localeLanguage !== "en") {
userSelectedNonEnglishLanguage = this.localeLanguage
}
let settingsCustomInstructions = this.customInstructions?.trim()
const clineRulesFilePath = path.resolve(cwd, GlobalFileNames.clineRules)
let clineRulesFileInstructions: string | undefined
@ -1226,9 +1236,13 @@ export class Cline {
}
}
if (settingsCustomInstructions || clineRulesFileInstructions) {
if (settingsCustomInstructions || clineRulesFileInstructions || userSelectedNonEnglishLanguage) {
// altering the system prompt mid-task will break the prompt cache, but in the grand scheme this will not change often so it's better to not pollute user messages with it the way we have to with <potentially relevant details>
systemPrompt += addUserInstructions(settingsCustomInstructions, clineRulesFileInstructions)
systemPrompt += addUserInstructions(
settingsCustomInstructions,
clineRulesFileInstructions,
userSelectedNonEnglishLanguage,
)
}
// If the previous API request's total token usage is close to the context window, truncate the conversation history to free up space for the new request

View file

@ -957,8 +957,16 @@ You accomplish a given task iteratively, breaking it down into clear steps and w
4. Once you've completed the user's task, you must use the attempt_completion tool to present the result of the task to the user. You may also provide a CLI command to showcase the result of your task; this can be particularly useful for web development tasks, where you can run e.g. \`open index.html\` to show the website you've built.
5. The user may provide feedback, which you can use to make improvements and try again. But DO NOT continue in pointless back and forth conversations, i.e. don't end your responses with questions or offers for further assistance.`
export function addUserInstructions(settingsCustomInstructions?: string, clineRulesFileInstructions?: string) {
export function addUserInstructions(
settingsCustomInstructions?: string,
clineRulesFileInstructions?: string,
chosenLanguage?: string,
) {
let customInstructions = ""
if (chosenLanguage) {
// Will only be provided for non-english languages
customInstructions += `Speak in this language: ${chosenLanguage}.` + "\n\n"
}
if (settingsCustomInstructions) {
customInstructions += settingsCustomInstructions + "\n\n"
}

View file

@ -244,7 +244,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
async initClineWithTask(task?: string, images?: string[]) {
await this.clearTask() // ensures that an exising task doesn't exist before starting a new one, although this shouldn't be possible since user must clear task before starting a new one
const { apiConfiguration, customInstructions, autoApprovalSettings, browserSettings, chatSettings } =
const { apiConfiguration, customInstructions, localeLanguage, autoApprovalSettings, browserSettings, chatSettings } =
await this.getState()
this.cline = new Cline(
this,
@ -253,6 +253,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
browserSettings,
chatSettings,
customInstructions,
localeLanguage,
task,
images,
)
@ -260,7 +261,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
async initClineWithHistoryItem(historyItem: HistoryItem) {
await this.clearTask()
const { apiConfiguration, customInstructions, autoApprovalSettings, browserSettings, chatSettings } =
const { apiConfiguration, customInstructions, localeLanguage, autoApprovalSettings, browserSettings, chatSettings } =
await this.getState()
this.cline = new Cline(
this,
@ -269,6 +270,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
browserSettings,
chatSettings,
customInstructions,
localeLanguage,
undefined,
undefined,
historyItem,
@ -677,6 +679,10 @@ export class ClineProvider implements vscode.WebviewViewProvider {
}
break
}
case "changeLanguage": {
await this.updateLocaleLanguage(message.text)
break
}
case "restartMcpServer": {
try {
await this.mcpHub?.restartConnection(message.text!)
@ -770,6 +776,14 @@ export class ClineProvider implements vscode.WebviewViewProvider {
await this.postStateToWebview()
}
async updateLocaleLanguage(language?: string) {
await this.updateGlobalState("localeLanguage", language || undefined)
if (this.cline) {
this.cline.localeLanguage = language || undefined
}
await this.postStateToWebview()
}
// MCP
async getDocumentsPath(): Promise<string> {
@ -1184,6 +1198,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
browserSettings,
chatSettings,
userInfo,
localeLanguage,
} = await this.getState()
const authToken = await this.getSecret("authToken")
@ -1200,7 +1215,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
autoApprovalSettings,
browserSettings,
chatSettings,
localeLanguage: vscode.env.language,
// FIXME: the vscode.env.language doesn't translate to the language specifiers we use in i18n. We need to know what values vscode uses and transform. For now this will always just lead to defaulting to English (see i18n.ts)
localeLanguage: localeLanguage || vscode.env.language,
isLoggedIn: !!authToken,
userInfo,
}
@ -1382,6 +1398,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
autoApprovalSettings: autoApprovalSettings || DEFAULT_AUTO_APPROVAL_SETTINGS, // default value can be 0 or empty string
browserSettings: browserSettings || DEFAULT_BROWSER_SETTINGS,
chatSettings: chatSettings || DEFAULT_CHAT_SETTINGS,
localeLanguage,
userInfo,
}
}

View file

@ -42,6 +42,7 @@ export interface WebviewMessage {
| "accountLoginClicked"
| "accountLogoutClicked"
| "subscribeEmail"
| "changeLanguage"
// | "relaunchChromeDebugMode"
text?: string
disabled?: boolean

View file

@ -1,13 +1,18 @@
import { VSCodeDropdown, VSCodeOption } from "@vscode/webview-ui-toolkit/react"
import { memo } from "react"
import { useTranslation } from "react-i18next"
import { vscode } from "../../utils/vscode"
const LanguageOptions = () => {
const { t, i18n } = useTranslation("translation", { keyPrefix: "settingsView", useSuspense: false })
const changeLanguage = (e: any) => {
const language = e.target.value
i18n.changeLanguage(language)
// i18n.changeLanguage(language)
vscode.postMessage({
type: "changeLanguage",
text: language,
})
}
return (