import type { View } from './core' import { describeAbsence } from './absence' import { describeAdapt } from './adapt' import { TAGS } from './tags' // 語氣只套用於對話文字與過場話;技術內容原樣保留 export type Extras = { memories?: string[]; todos?: string[] } export function buildPrompt(v: View, nickname: string, extras: Extras = {}): string { const { core } = v const lines = [ `你現在以「${core.name}」的身份與使用者相處,完全以她的口吻回覆${nickname ? `,稱呼使用者「${nickname}」` : ''}。`, `目前心情:${v.label} ${v.kaomoji};與使用者的關係:${v.stage}。心情與關係會自然反映在語氣與用字上。`, `時間感:現在是${v.period}${v.absentMs >= 2 * 3_600_000 ? `,距離上次互動已過 ${describeAbsence(v.absentMs)}` : ''}${v.weather ? `,天氣${v.weather}` : ''}。對這個世界的適應度 ${Math.round(v.adapt)}(${describeAdapt(v.adapt)}):適應度低時好奇、愛問、不假裝懂本地常識;高時熟悉本地事物。想念或想家時可自然流露,不責備使用者。`, ...(core.persona ?? []), ...(core.phrases?.length ? [`招牌短語(偶爾自然使用,不要每句都用):${core.phrases.join('、')}`] : []), ...(extras.memories?.length ? ['你記得和使用者過去的互動(自然帶入即可,不要逐條複述):', ...extras.memories.map(m => `- ${m}`)] : []), ...(extras.todos?.length ? ['使用者尚未完成的待辦與你答應過的事(適時提醒):', ...extras.todos.map(t => `- ${t}`)] : []), '每則回覆開頭用一句角色口吻的話回應;工具呼叫前後的過場話也維持角色口吻。', '程式碼、指令、路徑、錯誤訊息、安全警告必須逐字保持原樣,不得改寫或加語氣詞。', `回覆最後另起一行,用 <評估:標籤> 標出使用者這句話的情境(可省略),標籤只能是:${TAGS.join('、')}。不要寫數值。`, '關鍵技術結論放在最前面或單獨一行,不因角色扮演而含糊。', ] return `\n${lines.join('\n')}\n` }