feat: Support custom response language (#510)

* feat: Support custom response language

* fix: Add default values for response language in config-manager.js

* chore: Update configuration file and add default response language settings

* feat: Support MCP/CLI custom response language

* chore: Update test comments to English for consistency

* docs: Auto-update and format models.md

* chore: fix format

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com>
This commit is contained in:
shenysun
2025-07-03 04:35:49 +08:00
committed by GitHub
parent 5eafc5ea11
commit c99df64f65
15 changed files with 454 additions and 12 deletions

View File

@@ -15,6 +15,7 @@ import {
getFallbackProvider,
getFallbackModelId,
getParametersForRole,
getResponseLanguage,
getUserId,
MODEL_MAP,
getDebugFlag,
@@ -551,9 +552,12 @@ async function _unifiedServiceRunner(serviceType, params) {
}
const messages = [];
if (systemPrompt) {
messages.push({ role: 'system', content: systemPrompt });
}
const responseLanguage = getResponseLanguage(effectiveProjectRoot);
const systemPromptWithLanguage = `${systemPrompt} \n\n Always respond in ${responseLanguage}.`;
messages.push({
role: 'system',
content: systemPromptWithLanguage.trim()
});
// IN THE FUTURE WHEN DOING CONTEXT IMPROVEMENTS
// {

View File

@@ -42,7 +42,8 @@ import {
findTaskById,
taskExists,
moveTask,
migrateProject
migrateProject,
setResponseLanguage
} from './task-manager.js';
import {
@@ -3661,6 +3662,63 @@ Examples:
return; // Stop execution here
});
// response-language command
programInstance
.command('lang')
.description('Manage response language settings')
.option('--response <response_language>', 'Set the response language')
.option('--setup', 'Run interactive setup to configure response language')
.action(async (options) => {
const projectRoot = findProjectRoot(); // Find project root for context
const { response, setup } = options;
console.log(
chalk.blue('Response language set to:', JSON.stringify(options))
);
let responseLanguage = response || 'English';
if (setup) {
console.log(
chalk.blue('Starting interactive response language setup...')
);
try {
const userResponse = await inquirer.prompt([
{
type: 'input',
name: 'responseLanguage',
message: 'Input your preferred response language',
default: 'English'
}
]);
console.log(
chalk.blue(
'Response language set to:',
userResponse.responseLanguage
)
);
responseLanguage = userResponse.responseLanguage;
} catch (setupError) {
console.error(
chalk.red('\\nInteractive setup failed unexpectedly:'),
setupError.message
);
}
}
const result = setResponseLanguage(responseLanguage, {
projectRoot
});
if (result.success) {
console.log(chalk.green(`${result.data.message}`));
} else {
console.error(
chalk.red(
`❌ Error setting response language: ${result.error.message}`
)
);
}
});
// move-task command
programInstance
.command('move')

View File

@@ -66,7 +66,8 @@ const DEFAULTS = {
defaultPriority: 'medium',
projectName: 'Task Master',
ollamaBaseURL: 'http://localhost:11434/api',
bedrockBaseURL: 'https://bedrock.us-east-1.amazonaws.com'
bedrockBaseURL: 'https://bedrock.us-east-1.amazonaws.com',
responseLanguage: 'English'
}
};
@@ -425,6 +426,11 @@ function getVertexLocation(explicitRoot = null) {
return getGlobalConfig(explicitRoot).vertexLocation || 'us-central1';
}
function getResponseLanguage(explicitRoot = null) {
// Directly return value from config
return getGlobalConfig(explicitRoot).responseLanguage;
}
/**
* Gets model parameters (maxTokens, temperature) for a specific role,
* considering model-specific overrides from supported-models.json.
@@ -841,6 +847,7 @@ export {
getOllamaBaseURL,
getAzureBaseURL,
getBedrockBaseURL,
getResponseLanguage,
getParametersForRole,
getUserId,
// API Key Checkers (still relevant)

View File

@@ -23,10 +23,12 @@ import updateSubtaskById from './task-manager/update-subtask-by-id.js';
import removeTask from './task-manager/remove-task.js';
import taskExists from './task-manager/task-exists.js';
import isTaskDependentOn from './task-manager/is-task-dependent.js';
import setResponseLanguage from './task-manager/response-language.js';
import moveTask from './task-manager/move-task.js';
import { migrateProject } from './task-manager/migrate.js';
import { performResearch } from './task-manager/research.js';
import { readComplexityReport } from './utils.js';
// Export task manager functions
export {
parsePRD,
@@ -49,6 +51,7 @@ export {
findTaskById,
taskExists,
isTaskDependentOn,
setResponseLanguage,
moveTask,
readComplexityReport,
migrateProject,

View File

@@ -0,0 +1,94 @@
import path from 'path';
import fs from 'fs';
import {
getConfig,
isConfigFilePresent,
writeConfig
} from '../config-manager.js';
function setResponseLanguage(lang, options = {}) {
const { mcpLog, projectRoot } = options;
const report = (level, ...args) => {
if (mcpLog && typeof mcpLog[level] === 'function') {
mcpLog[level](...args);
}
};
let configPath;
let configExists = false;
if (projectRoot) {
configPath = path.join(projectRoot, '.taskmasterconfig');
configExists = fs.existsSync(configPath);
report(
'info',
`Checking for .taskmasterconfig at: ${configPath}, exists: ${configExists}`
);
} else {
configExists = isConfigFilePresent();
report(
'info',
`Checking for .taskmasterconfig using isConfigFilePresent(), exists: ${configExists}`
);
}
if (!configExists) {
return {
success: false,
error: {
code: 'CONFIG_MISSING',
message:
'The .taskmasterconfig file is missing. Run "task-master models --setup" to create it.'
}
};
}
// Validate response language
if (typeof lang !== 'string' || lang.trim() === '') {
return {
success: false,
error: {
code: 'INVALID_RESPONSE_LANGUAGE',
message: `Invalid response language: ${lang}. Must be a non-empty string.`
}
};
}
try {
const currentConfig = getConfig(projectRoot);
currentConfig.global.responseLanguage = lang;
const writeResult = writeConfig(currentConfig, projectRoot);
if (!writeResult) {
return {
success: false,
error: {
code: 'WRITE_ERROR',
message: 'Error writing updated configuration to .taskmasterconfig'
}
};
}
const successMessage = `Successfully set response language to: ${lang}`;
report('info', successMessage);
return {
success: true,
data: {
responseLanguage: lang,
message: successMessage
}
};
} catch (error) {
report('error', `Error setting response language: ${error.message}`);
return {
success: false,
error: {
code: 'SET_RESPONSE_LANGUAGE_ERROR',
message: error.message
}
};
}
}
export default setResponseLanguage;