@@ -584,6 +584,7 @@ const TOOLS = [
584584 name : { type : 'string' , minLength : 1 , maxLength : 300 , description : '精确任务名、alias 或稳定 taskId' } ,
585585 project : { ...PROJECT_NAMESPACE_INPUT_SCHEMA , description : '可选项目命名空间;提供后限制为 project scope' } ,
586586 scope : { type : 'string' , enum : [ 'project' , 'workspace' ] , description : '可选;默认按 cwd/project 推断' } ,
587+ locale : { type : 'string' , minLength : 2 , maxLength : 32 , description : '按当前用户意图选择的提示语言;省略时沿用已确认任务语言,不从任务名称猜测' } ,
587588 persistIndex : { type : 'boolean' , description : '是否持久化可重建索引;默认 true' }
588589 }
589590 }
@@ -4769,6 +4770,26 @@ function handleMemorySummaryAppend(args) {
47694770 }
47704771}
47714772
4773+ function taskPresentationLocale ( args , candidate , persistedLanguage ) {
4774+ const requested = normalizeLanguageTag ( args . locale )
4775+ if ( requested ) return requested
4776+ let language = persistedLanguage
4777+ if ( language === undefined && candidate ?. taskId && candidate . project ) {
4778+ try {
4779+ const target = taskMemoryTransactionTarget ( { project : candidate . project , scope : 'project' } )
4780+ const identity = { activeRoot : target . activeRoot , project : target . project , taskId : candidate . taskId , taskStatus : 'active' }
4781+ const recovery = readTaskRecoveryState ( { metaDir : resolveTaskRecoveryMetaDir ( identity ) , identity } , { fs } )
4782+ if ( recovery . status === 'fresh' ) language = recovery . state ?. languageContext
4783+ } catch {
4784+ // Presentation has no authority to alter a missing or invalid task state.
4785+ }
4786+ }
4787+ const durable = language ?. durableProvisional !== true
4788+ ? normalizeLanguageTag ( language ?. durablePrimaryLocale || language ?. primaryLanguage || language ?. responseLanguage )
4789+ : ''
4790+ return durable || 'en-US'
4791+ }
4792+
47724793function handleMemoryTaskResolve ( args ) {
47734794 if ( ! String ( args . name || '' ) . trim ( ) ) throw new TaskContinuationError ( 'TASK_NAME_REQUIRED' , 'name is required' )
47744795 const resolution = resolveTaskContinuation ( {
@@ -4779,8 +4800,7 @@ function handleMemoryTaskResolve(args) {
47794800 persistIndex : args . persistIndex !== false
47804801 } )
47814802 const candidates = resolution . candidates || resolution . suggestions || [ ]
4782- const languageEvidence = `${ String ( args . name || '' ) } ${ String ( resolution . candidate ?. displayName || '' ) } ${ candidates . map ( item => item . displayName || '' ) . join ( '' ) } `
4783- const chinese = / [ \u3400 - \u9fff ] / u. test ( languageEvidence )
4803+ const chinese = taskPresentationLocale ( args , resolution . candidate ) . startsWith ( 'zh' )
47844804 let humanText
47854805 if ( resolution . status === 'resolved-active' ) {
47864806 humanText = chinese
@@ -4901,15 +4921,8 @@ function handleMemoryTaskContinuityViewV1(args) {
49014921 activeRoot : target ?. activeRoot || '' ,
49024922 priorDisambiguationReceiptDigest : args . priorDisambiguationReceiptDigest || null
49034923 } )
4904- const persistedLanguage = recoveryRead . state ?. languageContext || { }
4905- const requestedLocale = normalizeLanguageTag ( args . locale )
4906- const durableLocale = normalizeLanguageTag (
4907- persistedLanguage . responseLanguage ||
4908- persistedLanguage . primaryLanguage ||
4909- persistedLanguage . durablePrimaryLocale
4910- )
4911- const languageEvidence = `${ args . name || '' } ${ candidate ?. displayName || '' } `
4912- const locale = requestedLocale || durableLocale || ( / \p{ Script= Han} / u. test ( languageEvidence ) ? 'zh-CN' : 'en-US' )
4924+ const locale = taskPresentationLocale ( args , candidate ,
4925+ recoveryRead . status === 'fresh' ? recoveryRead . state ?. languageContext || { } : { } )
49134926 return {
49144927 content : [ { type : 'text' , text : renderTaskContinuityViewHuman ( view , { locale } ) } ] ,
49154928 structuredContent : view ,
0 commit comments